From 9f5baf2aa141dc095733ff2722cc23232329d5a3 Mon Sep 17 00:00:00 2001 From: Chris Collins <1-cirx08@users.noreply.gitlab.cirx08.com> Date: Mon, 23 Dec 2024 21:32:36 +0000 Subject: [PATCH] Prerel 1.4.2 --- .../Controllers/GalleryControllerTests.cs | 24 +-- .../Tests/Controllers/HomeControllerTests.cs | 6 +- .../{SecretKeyHelper.cs => GalleryHelper.cs} | 51 +++++- .../Attributes/RequiresSecretKeyAttribute.cs | 6 +- .../DependencyInjectionConfiguration.cs | 2 +- WeddingShare/Controllers/AdminController.cs | 59 +++++++ WeddingShare/Controllers/GalleryController.cs | 13 +- WeddingShare/Controllers/HomeController.cs | 8 +- WeddingShare/Enums/GalleryOrder.cs | 3 +- .../{SecretKeyHelper.cs => GalleryHelper.cs} | 35 +++- WeddingShare/Views/Admin/Index.cshtml | 22 ++- .../Views/Gallery/GalleryOptions.cshtml | 29 +--- .../Views/Gallery/GalleryWrapper.cshtml | 34 ++-- WeddingShare/Views/Gallery/Index.cshtml | 24 +++ .../Views/Gallery/Modes/Slideshow.cshtml | 13 +- WeddingShare/Views/Shared/_Layout.cshtml | 2 +- WeddingShare/appsettings.json | 6 +- WeddingShare/wwwroot/css/site.css | 55 +++++-- WeddingShare/wwwroot/css/template.css | 2 + WeddingShare/wwwroot/css/themes/dark.css | 2 + WeddingShare/wwwroot/js/admin.js | 43 +++++ readme.md | 152 +++++++++--------- 22 files changed, 414 insertions(+), 177 deletions(-) rename WeddingShare.UnitTests/Tests/Helpers/{SecretKeyHelper.cs => GalleryHelper.cs} (52%) rename WeddingShare/Helpers/{SecretKeyHelper.cs => GalleryHelper.cs} (50%) diff --git a/WeddingShare.UnitTests/Tests/Controllers/GalleryControllerTests.cs b/WeddingShare.UnitTests/Tests/Controllers/GalleryControllerTests.cs index 9205e37..5dbab04 100644 --- a/WeddingShare.UnitTests/Tests/Controllers/GalleryControllerTests.cs +++ b/WeddingShare.UnitTests/Tests/Controllers/GalleryControllerTests.cs @@ -21,7 +21,7 @@ public class GalleryControllerTests { private readonly IWebHostEnvironment _env = Substitute.For(); private readonly IConfigHelper _config = Substitute.For(); - private readonly ISecretKeyHelper _secretKey = Substitute.For(); + private readonly IGalleryHelper _gallery = Substitute.For(); private readonly IDatabaseHelper _database = Substitute.For(); private readonly IFileHelper _file = Substitute.For(); private readonly IDeviceDetector _deviceDetector = Substitute.For(); @@ -64,8 +64,8 @@ public void Setup() _database.GetAllGalleryItems(Arg.Any(), GalleryItemState.Pending).Returns(Task.FromResult(MockData.MockGalleryItems(10, 1, GalleryItemState.Pending))); _database.GetAllGalleryItems(Arg.Any(), GalleryItemState.Approved).Returns(Task.FromResult(MockData.MockGalleryItems(10, 1, GalleryItemState.Approved))); - _secretKey.GetGallerySecretKey(Arg.Any()).Returns("password"); - _secretKey.GetGallerySecretKey("missing").Returns("123456"); + _gallery.GetSecretKey(Arg.Any()).Returns("password"); + _gallery.GetSecretKey("missing").Returns("123456"); _config.GetOrDefault("Settings", "Allowed_File_Types", Arg.Any()).Returns(".jpg,.jpeg,.png"); _config.GetOrDefault("Settings", "Default_Gallery_View", Arg.Any()).Returns((int)ViewMode.Default); @@ -85,7 +85,7 @@ public async Task GalleryController_Index(DeviceType deviceType, string id, stri _deviceDetector.ParseDeviceType(Arg.Any()).Returns(deviceType); _config.GetOrDefault("Settings", "Single_Gallery_Mode", Arg.Any()).Returns(false); - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext(); ViewResult actual = (ViewResult)await controller.Index(id, key, mode, order); @@ -110,7 +110,7 @@ public async Task GalleryController_Index_SingleGalleryMode(DeviceType deviceTyp _deviceDetector.ParseDeviceType(Arg.Any()).Returns(deviceType); _config.GetOrDefault("Settings", "Single_Gallery_Mode", Arg.Any()).Returns(true); - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext(); ViewResult actual = (ViewResult)await controller.Index("default", "password", mode, order); @@ -141,7 +141,7 @@ public async Task GalleryController_UploadImage(bool requiresReview, int fileCou files.Add(new FormFile(null, 0, 0, "TestFile_001", $"{Guid.NewGuid()}.jpg")); } - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext( form: new Dictionary { @@ -164,7 +164,7 @@ public async Task GalleryController_UploadImage(bool requiresReview, int fileCou [TestCase("")] public async Task GalleryController_UploadImage_InvalidGallery(string? id) { - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext(form: new Dictionary { { "Id", id } @@ -182,7 +182,7 @@ public async Task GalleryController_UploadImage_InvalidGallery(string? id) [TestCase("")] public async Task GalleryController_UploadImage_InvalidSecretKey(string? key) { - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext(form: new Dictionary { { "Id", "default" }, @@ -200,7 +200,7 @@ public async Task GalleryController_UploadImage_InvalidSecretKey(string? key) [TestCase()] public async Task GalleryController_UploadImage_MissingGallery() { - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext(form: new Dictionary { { "Id", Guid.NewGuid().ToString() } @@ -217,7 +217,7 @@ public async Task GalleryController_UploadImage_MissingGallery() [TestCase()] public async Task GalleryController_UploadImage_NoFiles() { - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext(form: new Dictionary { { "Id", "default" }, @@ -235,7 +235,7 @@ public async Task GalleryController_UploadImage_NoFiles() [TestCase()] public async Task GalleryController_UploadImage_FileTooBig() { - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext( form: new Dictionary { @@ -257,7 +257,7 @@ public async Task GalleryController_UploadImage_FileTooBig() [TestCase()] public async Task GalleryController_UploadImage_InvalidFileType() { - var controller = new GalleryController(_env, _config, _database, _file, _secretKey, _deviceDetector, _image, _notification, _logger, _localizer); + var controller = new GalleryController(_env, _config, _database, _file, _gallery, _deviceDetector, _image, _notification, _logger, _localizer); controller.ControllerContext.HttpContext = MockData.MockHttpContext( form: new Dictionary { diff --git a/WeddingShare.UnitTests/Tests/Controllers/HomeControllerTests.cs b/WeddingShare.UnitTests/Tests/Controllers/HomeControllerTests.cs index 2169f74..09e7123 100644 --- a/WeddingShare.UnitTests/Tests/Controllers/HomeControllerTests.cs +++ b/WeddingShare.UnitTests/Tests/Controllers/HomeControllerTests.cs @@ -11,7 +11,7 @@ namespace WeddingShare.UnitTests.Tests.Helpers public class HomeControllerTests { private readonly IConfigHelper _config = Substitute.For(); - private readonly ISecretKeyHelper _secretKey = Substitute.For(); + private readonly IGalleryHelper _gallery = Substitute.For(); private readonly IDeviceDetector _deviceDetector = Substitute.For(); private readonly ILogger _logger = Substitute.For>(); @@ -36,9 +36,9 @@ public async Task HomeController_Index(DeviceType deviceType, bool singleGallery { _deviceDetector.ParseDeviceType(Arg.Any()).Returns(deviceType); _config.GetOrDefault("Settings", "Single_Gallery_Mode", Arg.Any()).Returns(singleGalleryMode); - _secretKey.GetGallerySecretKey(Arg.Any()).Returns(secretKey); + _gallery.GetSecretKey(Arg.Any()).Returns(secretKey); - var controller = new HomeController(_config, _secretKey, _deviceDetector, _logger); + var controller = new HomeController(_config, _gallery, _deviceDetector, _logger); controller.ControllerContext.HttpContext = new DefaultHttpContext() { Session = new MockSession() diff --git a/WeddingShare.UnitTests/Tests/Helpers/SecretKeyHelper.cs b/WeddingShare.UnitTests/Tests/Helpers/GalleryHelper.cs similarity index 52% rename from WeddingShare.UnitTests/Tests/Helpers/SecretKeyHelper.cs rename to WeddingShare.UnitTests/Tests/Helpers/GalleryHelper.cs index 916ba4f..c60cb70 100644 --- a/WeddingShare.UnitTests/Tests/Helpers/SecretKeyHelper.cs +++ b/WeddingShare.UnitTests/Tests/Helpers/GalleryHelper.cs @@ -6,11 +6,11 @@ namespace WeddingShare.UnitTests.Tests.Helpers { - public class SecretKeyHelperTests + public class GalleryHelperTests { private readonly IDatabaseHelper _database = Substitute.For(); - public SecretKeyHelperTests() + public GalleryHelperTests() { _database.GetGallery("Gallery1").Returns(new GalleryModel() { SecretKey = "001" }); _database.GetGallery("Gallery2").Returns(new GalleryModel() { SecretKey = "002" }); @@ -22,7 +22,7 @@ public void Setup() } [TestCase()] - public async Task SecretKeyHelper_GetGallerySecretKey_DefaultEnvKey() + public async Task GalleryHelper_GetSecretKey_DefaultEnvKey() { var environment = Substitute.For(); environment.GetEnvironmentVariable("SECRET_KEY").Returns("123"); @@ -34,12 +34,12 @@ public async Task SecretKeyHelper_GetGallerySecretKey_DefaultEnvKey() var config = new ConfigHelper(environment, configuration, Substitute.For>()); - var actual = await new SecretKeyHelper(config, _database).GetGallerySecretKey("Gallery3"); + var actual = await new GalleryHelper(config, _database).GetSecretKey("Gallery3"); Assert.That(actual, Is.EqualTo("123")); } [TestCase()] - public async Task SecretKeyHelper_GetGallerySecretKey_GalleryEnvKey() + public async Task GalleryHelper_GetSecretKey_GalleryEnvKey() { var environment = Substitute.For(); environment.GetEnvironmentVariable("SECRET_KEY").Returns("123"); @@ -52,14 +52,14 @@ public async Task SecretKeyHelper_GetGallerySecretKey_GalleryEnvKey() var config = new ConfigHelper(environment, configuration, Substitute.For>()); - var actual = await new SecretKeyHelper(config, _database).GetGallerySecretKey("Gallery1"); + var actual = await new GalleryHelper(config, _database).GetSecretKey("Gallery1"); Assert.That(actual, Is.EqualTo("001")); } [TestCase("Gallery1", "001")] [TestCase("Gallery2", "002")] [TestCase("Gallery3", null)] - public async Task SecretKeyHelper_GetGallerySecretKey_Database(string galleryId, string key) + public async Task GalleryHelper_GetSecretKey_Database(string galleryId, string key) { var environment = Substitute.For(); environment.GetEnvironmentVariable(Arg.Any()).Returns(string.Empty); @@ -68,8 +68,43 @@ public async Task SecretKeyHelper_GetGallerySecretKey_Database(string galleryId, var config = new ConfigHelper(environment, configuration, Substitute.For>()); - var actual = await new SecretKeyHelper(config, _database).GetGallerySecretKey(galleryId); + var actual = await new GalleryHelper(config, _database).GetSecretKey(galleryId); Assert.That(actual, Is.EqualTo(key)); } + + [TestCase()] + public async Task GalleryHelper_GetConfig_DefaultEnvKey() + { + var environment = Substitute.For(); + environment.GetEnvironmentVariable("SECRET_KEY").Returns("123"); + + var configuration = ConfigurationHelper.MockConfiguration(new Dictionary() + { + { "Secret_Key_Gallery2", "002" } + }); + + var config = new ConfigHelper(environment, configuration, Substitute.For>()); + + var actual = new GalleryHelper(config, _database).GetConfig("Gallery3", "Secret_Key"); + Assert.That(actual, Is.EqualTo("123")); + } + + [TestCase()] + public async Task GalleryHelper_GetConfig_GalleryEnvKey() + { + var environment = Substitute.For(); + environment.GetEnvironmentVariable("SECRET_KEY").Returns("123"); + environment.GetEnvironmentVariable("SECRET_KEY_GALLERY1").Returns("001"); + + var configuration = ConfigurationHelper.MockConfiguration(new Dictionary() + { + { "Secret_Key_Gallery2", "002" } + }); + + var config = new ConfigHelper(environment, configuration, Substitute.For>()); + + var actual = new GalleryHelper(config, _database).GetConfig("Gallery1", "Secret_Key"); + Assert.That(actual, Is.EqualTo("001")); + } } } \ No newline at end of file diff --git a/WeddingShare/Attributes/RequiresSecretKeyAttribute.cs b/WeddingShare/Attributes/RequiresSecretKeyAttribute.cs index 93843f2..3359c2e 100644 --- a/WeddingShare/Attributes/RequiresSecretKeyAttribute.cs +++ b/WeddingShare/Attributes/RequiresSecretKeyAttribute.cs @@ -12,11 +12,11 @@ public override void OnActionExecuting(ActionExecutingContext filterContext) { var request = filterContext.HttpContext.Request; - var secretKeyHelper = filterContext.HttpContext.RequestServices.GetService(); - if (secretKeyHelper != null) + var galleryHelper = filterContext.HttpContext.RequestServices.GetService(); + if (galleryHelper != null) { var galleryId = (request.Query.ContainsKey("id") && !string.IsNullOrWhiteSpace(request.Query["id"])) ? request.Query["id"].ToString().ToLower() : "default"; - var secretKey = secretKeyHelper.GetGallerySecretKey(galleryId).Result; + var secretKey = galleryHelper.GetSecretKey(galleryId).Result; var key = request.Query.ContainsKey("key") ? request.Query["key"].ToString() : string.Empty; if (!string.IsNullOrWhiteSpace(secretKey) && !string.Equals(secretKey, key)) diff --git a/WeddingShare/Configurations/DependencyInjectionConfiguration.cs b/WeddingShare/Configurations/DependencyInjectionConfiguration.cs index 5284d6d..9e1ad5f 100644 --- a/WeddingShare/Configurations/DependencyInjectionConfiguration.cs +++ b/WeddingShare/Configurations/DependencyInjectionConfiguration.cs @@ -8,7 +8,7 @@ public static void AddDependencyInjectionConfiguration(this IServiceCollection s { services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/WeddingShare/Controllers/AdminController.cs b/WeddingShare/Controllers/AdminController.cs index b8a55df..cddd5c9 100644 --- a/WeddingShare/Controllers/AdminController.cs +++ b/WeddingShare/Controllers/AdminController.cs @@ -225,6 +225,65 @@ public async Task ReviewPhoto(int id, ReviewAction action) return Json(new { success = false }); } + [HttpPost] + public async Task BulkReview(ReviewAction action) + { + if (User?.Identity != null && User.Identity.IsAuthenticated) + { + try + { + var items = await _database.GetPendingGalleryItems(); + if (items != null && items.Any()) + { + foreach (var review in items) + { + var galleryDir = Path.Combine(UploadsDirectory, review.GalleryName); + var reviewFile = Path.Combine(galleryDir, "Pending", review.Title); + if (action == ReviewAction.APPROVED) + { + _fileHelper.CreateDirectoryIfNotExists(ThumbnailsDirectory); + + await _imageHelper.GenerateThumbnail(reviewFile, Path.Combine(ThumbnailsDirectory, $"{Path.GetFileNameWithoutExtension(reviewFile)}.webp"), _config.GetOrDefault("Settings", "Thumbnail_Size", 720)); + + _fileHelper.MoveFileIfExists(reviewFile, Path.Combine(galleryDir, review.Title)); + + review.State = GalleryItemState.Approved; + await _database.EditGalleryItem(review); + } + else if (action == ReviewAction.REJECTED) + { + var retain = _config.GetOrDefault("Settings", "Retain_Rejected_Items", false); + if (retain) + { + var rejectedDir = Path.Combine(galleryDir, "Rejected"); + _fileHelper.CreateDirectoryIfNotExists(rejectedDir); + _fileHelper.MoveFileIfExists(reviewFile, Path.Combine(rejectedDir, review.Title)); + } + else + { + _fileHelper.DeleteFileIfExists(reviewFile); + } + + await _database.DeleteGalleryItem(review); + } + else if (action == ReviewAction.UNKNOWN) + { + throw new Exception(_localizer["Unknown_Review_Action"].Value); + } + } + } + + return Json(new { success = true, action }); + } + catch (Exception ex) + { + _logger.LogError(ex, $"{_localizer["Failed_Reviewing_Photo"].Value} - {ex?.Message}"); + } + } + + return Json(new { success = false }); + } + [HttpPost] public async Task AddGallery(GalleryModel model) { diff --git a/WeddingShare/Controllers/GalleryController.cs b/WeddingShare/Controllers/GalleryController.cs index 1729a0b..8d22b56 100644 --- a/WeddingShare/Controllers/GalleryController.cs +++ b/WeddingShare/Controllers/GalleryController.cs @@ -20,7 +20,7 @@ public class GalleryController : Controller private readonly IConfigHelper _config; private readonly IDatabaseHelper _database; private readonly IFileHelper _fileHelper; - private readonly ISecretKeyHelper _secretKey; + private readonly IGalleryHelper _gallery; private readonly IDeviceDetector _deviceDetector; private readonly IImageHelper _imageHelper; private readonly INotificationHelper _notificationHelper; @@ -30,13 +30,13 @@ public class GalleryController : Controller private readonly string UploadsDirectory; private readonly string ThumbnailsDirectory; - public GalleryController(IWebHostEnvironment hostingEnvironment, IConfigHelper config, IDatabaseHelper database, IFileHelper fileHelper, ISecretKeyHelper secretKey, IDeviceDetector deviceDetector, IImageHelper imageHelper, INotificationHelper notificationHelper, ILogger logger, IStringLocalizer localizer) + public GalleryController(IWebHostEnvironment hostingEnvironment, IConfigHelper config, IDatabaseHelper database, IFileHelper fileHelper, IGalleryHelper galleryHelper, IDeviceDetector deviceDetector, IImageHelper imageHelper, INotificationHelper notificationHelper, ILogger logger, IStringLocalizer localizer) { _hostingEnvironment = hostingEnvironment; _config = config; _database = database; _fileHelper = fileHelper; - _secretKey = secretKey; + _gallery = galleryHelper; _deviceDetector = deviceDetector; _imageHelper = imageHelper; _notificationHelper = notificationHelper; @@ -89,7 +89,7 @@ public async Task Index(string id = "default", string? key = null if (gallery != null) { - var secretKey = await _secretKey.GetGallerySecretKey(gallery.Name); + var secretKey = await _gallery.GetSecretKey(gallery.Name); ViewBag.SecretKey = secretKey; var allowedFileTypes = _config.GetOrDefault("Settings", "Allowed_File_Types", ".jpg,.jpeg,.png").Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); @@ -108,6 +108,9 @@ public async Task Index(string id = "default", string? key = null case GalleryOrder.NameDesc: images = images?.OrderBy(x => x.Title); break; + case GalleryOrder.Random: + images = images?.OrderBy(x => Guid.NewGuid()); + break; default: images = images?.OrderByDescending(x => x.Id); break; @@ -146,7 +149,7 @@ public async Task UploadImage() var gallery = await _database.GetGallery(galleryId); if (gallery != null) { - var secretKey = await _secretKey.GetGallerySecretKey(galleryId); + var secretKey = await _gallery.GetSecretKey(galleryId); string key = (Request?.Form?.FirstOrDefault(x => string.Equals("SecretKey", x.Key, StringComparison.OrdinalIgnoreCase)).Value)?.ToString() ?? string.Empty; if (!string.IsNullOrWhiteSpace(secretKey) && !string.Equals(secretKey, key)) { diff --git a/WeddingShare/Controllers/HomeController.cs b/WeddingShare/Controllers/HomeController.cs index 53329e5..49b36e4 100644 --- a/WeddingShare/Controllers/HomeController.cs +++ b/WeddingShare/Controllers/HomeController.cs @@ -8,14 +8,14 @@ namespace WeddingShare.Controllers public class HomeController : Controller { private readonly IConfigHelper _config; - private readonly ISecretKeyHelper _secretKey; + private readonly IGalleryHelper _gallery; private readonly IDeviceDetector _deviceDetector; private readonly ILogger _logger; - public HomeController(IConfigHelper config, ISecretKeyHelper secretKey, IDeviceDetector deviceDetector, ILogger logger) + public HomeController(IConfigHelper config, IGalleryHelper gallery, IDeviceDetector deviceDetector, ILogger logger) { _config = config; - _secretKey = secretKey; + _gallery = gallery; _deviceDetector = deviceDetector; _logger = logger; } @@ -34,7 +34,7 @@ public async Task Index() if (_config.GetOrDefault("Settings", "Single_Gallery_Mode", false)) { - var key = await _secretKey.GetGallerySecretKey("default"); + var key = await _gallery.GetSecretKey("default"); if (string.IsNullOrWhiteSpace(key)) { return RedirectToAction("Index", "Gallery"); diff --git a/WeddingShare/Enums/GalleryOrder.cs b/WeddingShare/Enums/GalleryOrder.cs index 1a7fda8..1b2e474 100644 --- a/WeddingShare/Enums/GalleryOrder.cs +++ b/WeddingShare/Enums/GalleryOrder.cs @@ -6,6 +6,7 @@ public enum GalleryOrder UploadedAsc, UploadedDesc, NameAsc, - NameDesc + NameDesc, + Random } } \ No newline at end of file diff --git a/WeddingShare/Helpers/SecretKeyHelper.cs b/WeddingShare/Helpers/GalleryHelper.cs similarity index 50% rename from WeddingShare/Helpers/SecretKeyHelper.cs rename to WeddingShare/Helpers/GalleryHelper.cs index 7062a99..4cd784a 100644 --- a/WeddingShare/Helpers/SecretKeyHelper.cs +++ b/WeddingShare/Helpers/GalleryHelper.cs @@ -2,23 +2,42 @@ namespace WeddingShare.Helpers { - public interface ISecretKeyHelper + public interface IGalleryHelper { - Task GetGallerySecretKey(string galleryId); + string? GetConfig(string? galleryId, string key); + Task GetSecretKey(string galleryId); } - public class SecretKeyHelper : ISecretKeyHelper + public class GalleryHelper : IGalleryHelper { private readonly IConfigHelper _config; - private readonly IDatabaseHelper _database; + private readonly IDatabaseHelper _database; - public SecretKeyHelper(IConfigHelper config, IDatabaseHelper database) + public GalleryHelper(IConfigHelper config, IDatabaseHelper database) { _config = config; _database = database; } - public async Task GetGallerySecretKey(string galleryId) + public string? GetConfig(string? galleryId, string key) + { + try + { + var value = _config.Get("Settings", $"{key}_{galleryId ?? "default"}"); + if (string.IsNullOrWhiteSpace(value)) + { + value = _config.Get("Settings", key); + } + + return value; + } + catch + { + return null; + } + } + + public async Task GetSecretKey(string galleryId) { try { @@ -31,10 +50,10 @@ public SecretKeyHelper(IConfigHelper config, IDatabaseHelper database) secretKey = _config.Get("Settings", "Secret_Key"); } } - + return secretKey; } - catch + catch { return null; } diff --git a/WeddingShare/Views/Admin/Index.cshtml b/WeddingShare/Views/Admin/Index.cshtml index 3ac2045..0a0532c 100644 --- a/WeddingShare/Views/Admin/Index.cshtml +++ b/WeddingShare/Views/Admin/Index.cshtml @@ -3,7 +3,7 @@ @using WeddingShare.Views.Admin @inject Microsoft.Extensions.Localization.IStringLocalizer _localizer @inject WeddingShare.Helpers.IConfigHelper _config -@inject WeddingShare.Helpers.ISecretKeyHelper _secretKey +@inject WeddingShare.Helpers.IGalleryHelper _gallery @{ var identityEnabled = _config.GetOrDefault("Settings", "Show_Identity_Request", true); @@ -24,6 +24,10 @@
Create
} +
+ +
Approve
+
Import
@@ -45,16 +49,16 @@
- + - + @foreach (var gallery in Model.Galleries.OrderBy(x => string.Equals("default", x.Name, StringComparison.OrdinalIgnoreCase) ? 0 : 1)) { - var secretKey = await _secretKey.GetGallerySecretKey(gallery.Name); + var secretKey = await _gallery.GetSecretKey(gallery.Name); var galleryLink = $"{link}?id={gallery.Name}{(!string.IsNullOrWhiteSpace(secretKey) ? $"&key={secretKey}" : string.Empty)}"; @@ -95,11 +99,13 @@ { foreach (var review in Model.PendingRequests) { -
-
- +
+
+ + +
-
+
@if (identityEnabled) {
diff --git a/WeddingShare/Views/Gallery/GalleryOptions.cshtml b/WeddingShare/Views/Gallery/GalleryOptions.cshtml index 3fc1a86..6c76223 100644 --- a/WeddingShare/Views/Gallery/GalleryOptions.cshtml +++ b/WeddingShare/Views/Gallery/GalleryOptions.cshtml @@ -6,29 +6,6 @@ @inject WeddingShare.Helpers.IConfigHelper _config @model WeddingShare.Models.PhotoGallery -@{ - var ctx = Context.Request; - var baseLink = UrlHelper.Generate(ctx, _config, ctx.Path); - - var queryString = new StringBuilder(); - foreach (var q in ctx.Query.Where(x => !string.Equals("order", x.Key, StringComparison.OrdinalIgnoreCase))) - { - if (string.Equals("key", q.Key, StringComparison.OrdinalIgnoreCase) && _config.GetOrDefault("Settings", "Hide_Key_From_QR_Code", false)) - { - continue; - } - else if (string.Equals("order", q.Key, StringComparison.OrdinalIgnoreCase) || string.Equals("mode", q.Key, StringComparison.OrdinalIgnoreCase)) - { - continue; - } - - queryString.Append($"&{q.Key}={q.Value}"); - } - - baseLink = $"{baseLink}?{queryString.ToString().TrimStart('&')}".TrimEnd(new char[] { '?', '&' }); - var qrCodeLink = $"{baseLink}{(ctx.Query.ContainsKey("order") ? $"{(baseLink.Contains("?") ? "&" : "?")}order={ctx.Query["order"]}" : string.Empty)}"; -} - @if (!_config.GetOrDefault("Settings", "Disable_QR_Code", false)) {
@@ -39,7 +16,7 @@ document.addEventListener('DOMContentLoaded', function () { if ($('#qrcode').length > 0 && $('#qrcode').is(':visible')) { $(function () { - $('#qrcode').qrcode({ width: 150, height: 150, text: '@Html.Raw(qrCodeLink)' }); + $('#qrcode').qrcode({ width: 150, height: 150, text: '@Html.Raw(ViewBag.QRCodeLink)' }); }); } }, false); @@ -57,7 +34,7 @@
@@ -70,7 +47,7 @@ { if (order != GalleryOrder.None) { - @order + @order } }
diff --git a/WeddingShare/Views/Gallery/GalleryWrapper.cshtml b/WeddingShare/Views/Gallery/GalleryWrapper.cshtml index 4ec93c2..58c9d41 100644 --- a/WeddingShare/Views/Gallery/GalleryWrapper.cshtml +++ b/WeddingShare/Views/Gallery/GalleryWrapper.cshtml @@ -1,22 +1,36 @@ @using WeddingShare.Enums @using WeddingShare.Views.Gallery @inject WeddingShare.Helpers.IConfigHelper _config +@inject WeddingShare.Helpers.IGalleryHelper _gallery @inject Microsoft.Extensions.Localization.IStringLocalizer _localizer @model WeddingShare.Models.PhotoGallery -@if (!_config.GetOrDefault("Settings", "Disable_Review_Counter", false)) +@if (Model.ViewMode != ViewMode.Slideshow) { -
-
-
@_localizer["Total"].Value
@(Model?.TotalCount ?? 0)
+ var quote = _gallery.GetConfig(Model?.GalleryId, "Gallery_Quote"); + if (!string.IsNullOrWhiteSpace(quote)) + { +
+
+

@quote

+
-
-
@_localizer["Approved"].Value
@(Model?.ApprovedCount ?? 0)
-
-
-
@_localizer["Pending"].Value
@(Model?.PendingCount ?? 0)
+ } + + if (!_config.GetOrDefault("Settings", "Disable_Review_Counter", false)) + { +
+
+
@_localizer["Total"].Value
@(Model?.TotalCount ?? 0)
+
+
+
@_localizer["Approved"].Value
@(Model?.ApprovedCount ?? 0)
+
+
+
@_localizer["Pending"].Value
@(Model?.PendingCount ?? 0)
+
-
+ } } @if (Model?.Images != null && Model.Images.Any()) diff --git a/WeddingShare/Views/Gallery/Index.cshtml b/WeddingShare/Views/Gallery/Index.cshtml index 19abdce..a5e2af9 100644 --- a/WeddingShare/Views/Gallery/Index.cshtml +++ b/WeddingShare/Views/Gallery/Index.cshtml @@ -1,9 +1,33 @@ @using WeddingShare.Enums +@using WeddingShare.Helpers @using WeddingShare.Views.Gallery @inject Microsoft.Extensions.Localization.IStringLocalizer _localizer @inject WeddingShare.Helpers.IConfigHelper _config @model WeddingShare.Models.PhotoGallery +@{ + var ctx = Context.Request; + var baseLink = UrlHelper.Generate(ctx, _config, ctx.Path); + + var queryString = new System.Text.StringBuilder(); + foreach (var q in ctx.Query.Where(x => !string.Equals("order", x.Key, StringComparison.OrdinalIgnoreCase))) + { + if (string.Equals("key", q.Key, StringComparison.OrdinalIgnoreCase) && _config.GetOrDefault("Settings", "Hide_Key_From_QR_Code", false)) + { + continue; + } + else if (string.Equals("order", q.Key, StringComparison.OrdinalIgnoreCase) || string.Equals("mode", q.Key, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + queryString.Append($"&{q.Key}={q.Value}"); + } + + ViewBag.BaseLink = $"{baseLink}?{queryString.ToString().TrimStart('&')}".TrimEnd(new char[] { '?', '&' }); + ViewBag.QRCodeLink = $"{ViewBag.BaseLink}{(ctx.Query.ContainsKey("order") ? $"{(ViewBag.BaseLink.Contains("?") ? "&" : "?")}order={ctx.Query["order"]}" : string.Empty)}"; +} + @if (Model?.FileUploader != null && Model.ViewMode != ViewMode.Presentation && Model.ViewMode != ViewMode.Slideshow) { diff --git a/WeddingShare/Views/Gallery/Modes/Slideshow.cshtml b/WeddingShare/Views/Gallery/Modes/Slideshow.cshtml index 207f4fa..26c9acb 100644 --- a/WeddingShare/Views/Gallery/Modes/Slideshow.cshtml +++ b/WeddingShare/Views/Gallery/Modes/Slideshow.cshtml @@ -16,13 +16,21 @@ @foreach (var image in Model.Images.Take(slideLimit)) {
- + @if (identityEnabled) {
Uploaded By: @(!string.IsNullOrWhiteSpace(image?.UploadedBy) ? image.UploadedBy : "Anonymous")
}
} + + @if (_config.GetOrDefault("Settings", "Slideshow", "Include_Share_Slide", true)) + { +
+ +
Scan the QR code with your phone to share your images
+
+ }
} } @@ -30,6 +38,7 @@
@_localizer["Name"].Value@_localizer["Name"].Value @_localizer["Total"].Value @_localizer["Approved"].Value @_localizer["Pending"].Value @_localizer["Key"].Value@_localizer["Actions"].Value@_localizer["Actions"].Value