From 7550e0e45d6fbb75b3f000dd942e1df3de31d8ce Mon Sep 17 00:00:00 2001 From: Gary Sharp Date: Wed, 18 Dec 2024 19:37:15 +1100 Subject: [PATCH] qol: wait for attachment thumbnail generation and show additional file type-specific icons --- .../Attachments/AttachmentActionExtensions.cs | 151 +++++++++++++----- Disco.Services/Disco.Services.csproj | 3 + Disco.Services/packages.config | 1 + .../Areas/API/Controllers/DeviceController.cs | 14 +- .../Areas/API/Controllers/JobController.cs | 12 +- .../Areas/API/Controllers/UserController.cs | 11 +- .../Images/AttachmentTypes/MimeTypeIcons.cs | 64 ++++++-- .../Style/Images/AttachmentTypes/archive.png | Bin 0 -> 2332 bytes .../Style/Images/AttachmentTypes/audio.png | Bin 0 -> 2026 bytes .../Style/Images/AttachmentTypes/binary.png | Bin 0 -> 1380 bytes .../Images/AttachmentTypes/spreadsheet.png | Bin 0 -> 2225 bytes .../Style/Images/AttachmentTypes/txt.png | Bin 0 -> 3232 bytes .../Style/Images/AttachmentTypes/unknown.png | Bin 1578 -> 1558 bytes .../Style/Images/AttachmentTypes/video.png | Bin 0 -> 1362 bytes Disco.Web/Disco.Web.csproj | 6 + .../T4MVC/API.DeviceController.generated.cs | 10 +- .../T4MVC/API.JobController.generated.cs | 20 +-- .../T4MVC/API.SystemController.generated.cs | 10 +- .../T4MVC/API.UserController.generated.cs | 10 +- Disco.Web/Extensions/T4MVC/T4MVC.cs | 6 + Disco.Web/Views/Job/JobParts/Resources.cshtml | 2 +- .../Views/Job/JobParts/Resources.generated.cs | 10 +- .../Views/User/UserParts/_Resources.cshtml | 2 +- .../User/UserParts/_Resources.generated.cs | 10 +- 24 files changed, 226 insertions(+), 116 deletions(-) create mode 100644 Disco.Web/ClientSource/Style/Images/AttachmentTypes/archive.png create mode 100644 Disco.Web/ClientSource/Style/Images/AttachmentTypes/audio.png create mode 100644 Disco.Web/ClientSource/Style/Images/AttachmentTypes/binary.png create mode 100644 Disco.Web/ClientSource/Style/Images/AttachmentTypes/spreadsheet.png create mode 100644 Disco.Web/ClientSource/Style/Images/AttachmentTypes/txt.png create mode 100644 Disco.Web/ClientSource/Style/Images/AttachmentTypes/video.png diff --git a/Disco.Services/Attachments/AttachmentActionExtensions.cs b/Disco.Services/Attachments/AttachmentActionExtensions.cs index b67d5cb5..2bb47a54 100644 --- a/Disco.Services/Attachments/AttachmentActionExtensions.cs +++ b/Disco.Services/Attachments/AttachmentActionExtensions.cs @@ -4,8 +4,10 @@ using Disco.Services.Authorization; using Disco.Services.Documents.ManagedGroups; using Disco.Services.Users; using System; +using System.Data.Entity; using System.Drawing; using System.IO; +using System.Threading; namespace Disco.Services { @@ -215,12 +217,37 @@ namespace Disco.Services return ua; } + public static bool WaitForThumbnailGeneration(this IAttachment attachment, DiscoDataContext database, out string thumbnailPath, out string mimeType) + { + thumbnailPath = attachment.RepositoryThumbnailFilename(database); + if (thumbnailPath.EndsWith(".png")) + mimeType = "image/png"; + else + mimeType = "image/jpeg"; + + if (File.Exists(thumbnailPath)) + return true; + + // recently created attachments may not have a thumbnail yet + var timestamp = attachment.Timestamp; + if (timestamp > DateTime.Now.AddSeconds(-5) && attachment.SupportsThumbnailGeneration(out _, out _)) + { + while (!File.Exists(thumbnailPath) && timestamp > DateTime.Now.AddSeconds(-5)) + Thread.Sleep(250); + + if (File.Exists(thumbnailPath)) + return true; + } + + return false; + } + public static string GenerateThumbnail(this IAttachment attachment, DiscoDataContext Database, Stream AttachmentStream) { string thumbnailFilePath = attachment.RepositoryThumbnailFilename(Database); Image thumbnail; - if (GenerateThumbnail(AttachmentStream, attachment.MimeType, out thumbnail)) + if (attachment.GenerateThumbnail(AttachmentStream, out thumbnail)) { thumbnail.SaveJpg(90, thumbnailFilePath); } @@ -235,7 +262,7 @@ namespace Disco.Services using (var attachmentStream = File.OpenRead(attachment.RepositoryFilename(Database))) { Image thumbnail; - if (GenerateThumbnail(attachmentStream, attachment.MimeType, out thumbnail)) + if (attachment.GenerateThumbnail(attachmentStream, out thumbnail)) { thumbnail.SaveJpg(90, thumbnailFilePath); } @@ -244,61 +271,101 @@ namespace Disco.Services return thumbnailFilePath; } - public static bool GenerateThumbnail(Stream Source, string SourceMimeType, out Image Thumbnail) + + private const string pdfMimeType = "application/pdf"; + private const string pdfExtension = "pdf"; + private static readonly string[] imageMimeTypes = new string[] { "image/jpeg", "image/png", "image/gif", "image/bmp" }; + private static readonly string[] imageExtensions = new string[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp" }; + public static (bool supported, bool isImage, bool isPdf) SupportsThumbnailGeneration(string mimeType, string fileName) { - if (Source != null) + if (!string.IsNullOrEmpty(mimeType)) { - // GDI+ (jpg, png, gif, bmp) - if (SourceMimeType.Equals("image/jpeg", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("jpg") || - SourceMimeType.Equals("image/png", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("png") || - SourceMimeType.Equals("image/gif", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("gif") || - SourceMimeType.Equals("image/bmp", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("bmp")) + if (pdfMimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase)) + return (true, false, true); + foreach (var imageMimeType in imageMimeTypes) + if (mimeType.Equals(imageMimeType, StringComparison.OrdinalIgnoreCase)) + return (true, true, false); + } + + if (!string.IsNullOrEmpty(fileName)) + { + if (fileName.EndsWith(pdfExtension, StringComparison.OrdinalIgnoreCase)) + return (true, false, true); + foreach (var imageExtension in imageExtensions) + if (fileName.EndsWith(imageExtension, StringComparison.OrdinalIgnoreCase)) + return (true, true, false); + } + + return (false, false, false); + } + + public static bool SupportsThumbnailGeneration(this IAttachment attachment, out bool isImage, out bool isPdf) + { + var result = SupportsThumbnailGeneration(attachment.MimeType, attachment.Filename); + + isImage = result.isImage; + isPdf = result.isPdf; + + return result.supported; + } + + public static bool GenerateThumbnail(this IAttachment attachment, Stream source, out Image thumbnail) + { + if (source != null) + { + var (supported, isImage, isPdf) = SupportsThumbnailGeneration(attachment.MimeType, attachment.Filename); + + if (supported) { - try + // GDI+ (jpg, png, gif, bmp) + if (isImage) { - using (Image sourceImage = Image.FromStream(Source)) + try { - Thumbnail = sourceImage.ResizeImage(48, 48, Brushes.Black); - using (Image mimeTypeIcon = Properties.Resources.MimeType_img16) + using (Image sourceImage = Image.FromStream(source)) { - Thumbnail.EmbedIconOverlay(mimeTypeIcon); - } - return true; - } - } - catch (Exception) { } - - } - - // PDF - if (SourceMimeType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("pdf")) - { - try - { - using (var pdfiumDocument = PdfiumViewer.PdfDocument.Load(Source)) - { - - if (pdfiumDocument.PageCount > 0) - { - var pageSize = pdfiumDocument.PageSizes[0]; - var size = ImagingExtensions.CalculateResize((int)pageSize.Width, (int)pageSize.Height, 48, 48); - - using (var sourceImage = pdfiumDocument.Render(0, (int)size.Width, (int)size.Height, 72, 72, true)) + thumbnail = sourceImage.ResizeImage(48, 48, Brushes.Black); + using (Image mimeTypeIcon = Properties.Resources.MimeType_img16) { - Thumbnail = sourceImage.ResizeImage(48, 48, Brushes.White); - using (Image mimeTypeIcon = Properties.Resources.MimeType_pdf16) + thumbnail.EmbedIconOverlay(mimeTypeIcon); + } + return true; + } + } + catch (Exception) { } + + } + + // PDF + if (isPdf) + { + try + { + using (var pdfiumDocument = PdfiumViewer.PdfDocument.Load(source)) + { + + if (pdfiumDocument.PageCount > 0) + { + var pageSize = pdfiumDocument.PageSizes[0]; + var size = ImagingExtensions.CalculateResize((int)pageSize.Width, (int)pageSize.Height, 48, 48); + + using (var sourceImage = pdfiumDocument.Render(0, (int)size.Width, (int)size.Height, 72, 72, true)) { - Thumbnail.EmbedIconOverlay(mimeTypeIcon); + thumbnail = sourceImage.ResizeImage(48, 48, Brushes.White); + using (Image mimeTypeIcon = Properties.Resources.MimeType_pdf16) + { + thumbnail.EmbedIconOverlay(mimeTypeIcon); + } + return true; } - return true; } } } + catch (Exception) { } } - catch (Exception) { } } } - Thumbnail = null; + thumbnail = null; return false; } } diff --git a/Disco.Services/Disco.Services.csproj b/Disco.Services/Disco.Services.csproj index bac559b4..343b38cf 100644 --- a/Disco.Services/Disco.Services.csproj +++ b/Disco.Services/Disco.Services.csproj @@ -141,6 +141,9 @@ ..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll + + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll + diff --git a/Disco.Services/packages.config b/Disco.Services/packages.config index 4be4295d..ce827ba7 100644 --- a/Disco.Services/packages.config +++ b/Disco.Services/packages.config @@ -29,5 +29,6 @@ + \ No newline at end of file diff --git a/Disco.Web/Areas/API/Controllers/DeviceController.cs b/Disco.Web/Areas/API/Controllers/DeviceController.cs index 3e235852..545a7ed1 100644 --- a/Disco.Web/Areas/API/Controllers/DeviceController.cs +++ b/Disco.Web/Areas/API/Controllers/DeviceController.cs @@ -1,7 +1,6 @@ using Disco.Models.Repository; using Disco.Models.Services.Devices.Exporting; using Disco.Models.Services.Devices.Importing; -using System.Data.Entity; using Disco.Services; using Disco.Services.Authorization; using Disco.Services.Devices.Exporting; @@ -9,17 +8,18 @@ using Disco.Services.Devices.Importing; using Disco.Services.Exporting; using Disco.Services.Interop; using Disco.Services.Interop.ActiveDirectory; +using Disco.Services.Logging; using Disco.Services.Users; using Disco.Services.Web; using Disco.Web.Extensions; using Disco.Web.Models.Device; using System; using System.Collections.Generic; +using System.Data.Entity; using System.Linq; using System.Web; using System.Web.Caching; using System.Web.Mvc; -using Disco.Services.Logging; namespace Disco.Web.Areas.API.Controllers { @@ -498,14 +498,8 @@ namespace Disco.Web.Areas.API.Controllers var da = Database.DeviceAttachments.Find(id); if (da != null) { - var thumbPath = da.RepositoryThumbnailFilename(Database); - if (System.IO.File.Exists(thumbPath)) - { - if (thumbPath.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) - return File(thumbPath, "image/png"); - else - return File(thumbPath, "image/jpeg"); - } + if (da.WaitForThumbnailGeneration(Database, out var thumbPath, out var mimeType)) + return File(thumbPath, mimeType); else return File(ClientSource.Style.Images.AttachmentTypes.MimeTypeIcons.Icon(da.MimeType), "image/png"); } diff --git a/Disco.Web/Areas/API/Controllers/JobController.cs b/Disco.Web/Areas/API/Controllers/JobController.cs index 70b917fc..b8bff874 100644 --- a/Disco.Web/Areas/API/Controllers/JobController.cs +++ b/Disco.Web/Areas/API/Controllers/JobController.cs @@ -16,7 +16,6 @@ using Disco.Web.Models.Job; using System; using System.Collections.Generic; using System.Data.Entity; -using System.IO; using System.Linq; using System.Web; using System.Web.Caching; @@ -1904,15 +1903,8 @@ namespace Disco.Web.Areas.API.Controllers var ja = Database.JobAttachments.Find(id); if (ja != null) { - var thumbPath = ja.RepositoryThumbnailFilename(Database); - var thumbFileInfo = new FileInfo(thumbPath); - if (thumbFileInfo.Exists && thumbFileInfo.Length > 0) - { - if (thumbPath.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) - return File(thumbPath, "image/png"); - else - return File(thumbPath, "image/jpeg"); - } + if (ja.WaitForThumbnailGeneration(Database, out var thumbPath, out var mimeType)) + return File(thumbPath, mimeType); else return File(ClientSource.Style.Images.AttachmentTypes.MimeTypeIcons.Icon(ja.MimeType), "image/png"); } diff --git a/Disco.Web/Areas/API/Controllers/UserController.cs b/Disco.Web/Areas/API/Controllers/UserController.cs index 15f251fe..a9638f2e 100644 --- a/Disco.Web/Areas/API/Controllers/UserController.cs +++ b/Disco.Web/Areas/API/Controllers/UserController.cs @@ -6,6 +6,7 @@ using Disco.Services.Plugins.Features.DetailsProvider; using Disco.Services.Users; using Disco.Services.Web; using System; +using System.Data.Entity; using System.Linq; using System.Web.Mvc; @@ -42,14 +43,8 @@ namespace Disco.Web.Areas.API.Controllers var ua = Database.UserAttachments.Find(id); if (ua != null) { - var thumbPath = ua.RepositoryThumbnailFilename(Database); - if (System.IO.File.Exists(thumbPath)) - { - if (thumbPath.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) - return File(thumbPath, "image/png"); - else - return File(thumbPath, "image/jpeg"); - } + if (ua.WaitForThumbnailGeneration(Database, out var thumbPath, out var mimeType)) + return File(thumbPath, mimeType); else return File(ClientSource.Style.Images.AttachmentTypes.MimeTypeIcons.Icon(ua.MimeType), "image/png"); } diff --git a/Disco.Web/ClientSource/Style/Images/AttachmentTypes/MimeTypeIcons.cs b/Disco.Web/ClientSource/Style/Images/AttachmentTypes/MimeTypeIcons.cs index db140175..d281c822 100644 --- a/Disco.Web/ClientSource/Style/Images/AttachmentTypes/MimeTypeIcons.cs +++ b/Disco.Web/ClientSource/Style/Images/AttachmentTypes/MimeTypeIcons.cs @@ -1,27 +1,73 @@ using System; +using System.Collections.Generic; +using System.Linq; namespace Disco.Web.ClientSource.Style.Images.AttachmentTypes { public static class MimeTypeIcons { + private static IEnumerable DocumentMimeTypes() + { + yield return "application/msword"; + yield return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + yield return "application/vnd.ms-word.document.macroEnabled.12"; + } + private static IEnumerable SpreadsheetMimeTypes() + { + yield return "application/vnd.ms-excel"; + yield return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + yield return "application/vnd.ms-excel.sheet.macroEnabled.12"; + } + private static IEnumerable ArchiveMimeTypes() + { + yield return "application/zip"; + yield return "application/gzip"; + yield return "application/x-tar"; + yield return "application/x-zip-compressed"; + yield return "application/x-7z-compressed"; + yield return "application/x-bzip"; + yield return "application/x-bzip2"; + yield return "application/x-gzip"; + } + public static string Icon(string MimeType) { + // PDF + if ("application/pdf".Equals(MimeType, StringComparison.OrdinalIgnoreCase)) + return Links.ClientSource.Style.Images.AttachmentTypes.pdf_png; - switch (MimeType.ToLower()) - { - case "application/pdf": - return Links.ClientSource.Style.Images.AttachmentTypes.pdf_png; - case "application/msword": - case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": - case "application/vnd.ms-word.document.macroEnabled.12": - return Links.ClientSource.Style.Images.AttachmentTypes.document_png; - } + // Document icon + if (DocumentMimeTypes().Any(t => t.Equals(MimeType, StringComparison.OrdinalIgnoreCase))) + return Links.ClientSource.Style.Images.AttachmentTypes.document_png; + + // Spreadsheet icon + if (SpreadsheetMimeTypes().Any(t => t.Equals(MimeType, StringComparison.OrdinalIgnoreCase))) + return Links.ClientSource.Style.Images.AttachmentTypes.spreadsheet_png; // Generic 'image' icon if (MimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) return Links.ClientSource.Style.Images.AttachmentTypes.image_png; + // Generic 'video' icon + if (MimeType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) + return Links.ClientSource.Style.Images.AttachmentTypes.video_png; + + if (MimeType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) + return Links.ClientSource.Style.Images.AttachmentTypes.audio_png; + + // Generic 'text' icon + if (MimeType.StartsWith("text/", StringComparison.OrdinalIgnoreCase)) + return Links.ClientSource.Style.Images.AttachmentTypes.txt_png; + + // Archive icons + if (ArchiveMimeTypes().Any(t => t.Equals(MimeType, StringComparison.OrdinalIgnoreCase))) + return Links.ClientSource.Style.Images.AttachmentTypes.archive_png; + + if ("application/binary".Equals(MimeType, StringComparison.OrdinalIgnoreCase) || + "application/octet-stream".Equals(MimeType, StringComparison.OrdinalIgnoreCase)) + return Links.ClientSource.Style.Images.AttachmentTypes.binary_png; + // All other Attachments return Links.ClientSource.Style.Images.AttachmentTypes.unknown_png; } diff --git a/Disco.Web/ClientSource/Style/Images/AttachmentTypes/archive.png b/Disco.Web/ClientSource/Style/Images/AttachmentTypes/archive.png new file mode 100644 index 0000000000000000000000000000000000000000..cb683674786144d8808d44ac56badac21e4fb7d4 GIT binary patch literal 2332 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 IM6N<$f&+2wzW@LL literal 0 HcmV?d00001 diff --git a/Disco.Web/ClientSource/Style/Images/AttachmentTypes/binary.png b/Disco.Web/ClientSource/Style/Images/AttachmentTypes/binary.png new file mode 100644 index 0000000000000000000000000000000000000000..99a380aa58119a1540753ee3f5fd682a54ae1426 GIT binary patch literal 1380 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 LNkvXXu0mjfJ*fBF diff --git a/Disco.Web/ClientSource/Style/Images/AttachmentTypes/video.png b/Disco.Web/ClientSource/Style/Images/AttachmentTypes/video.png new file mode 100644 index 0000000000000000000000000000000000000000..471703a79d116d25f3d20cbb9e0b42f279445beb GIT binary patch literal 1362 zcmV-Y1+DstP)%n@i!Q`ObY1$eC{dI?E<&gaDG0g<>!L`gpu32Oh#JWNI*K|eabxAk0+hf`;C#Nx0(p>rnZ=RZVL>Rgm zU<6^X{6UEsSRxF!ah*{j0&1LL4s963G`hHsqsFb*qV)%kLU|p4#NpHth#Cdt{N>xp)<%e35G+le(t`9%VmUxQm%Ms*?34OI#(;|{j6lc(vXgot8u zWka-ZvTe9s5F2JG@9_canM;vqya-H5iyX~-EhgQzmYuxGN@f$_G9g+3n2hgqRCMqx zeZ0V(lz=K~fG~ANvROAbnbw?mx_E=_JjDV^xH#L>5V>LMyK2G!K_<`&R$ue%z<4=qT8@S7Y^F2m(Am|fuIW$Wx|p>Y%we{18RO-C zqmv8uBLFFj=9}moeSFCUM(ZjV&1;eMV&5hOuKo%6jL$jEAhq}nzc zKIUgaA{+%wJWshC{z6v%x>TV0&oOp!kbfA(U?|47HVH%v4dm5O*AUSc>Emn8GlC;X zOkzCE!X(B93r~fU3u=R9{Qy&6FFC@yfM`;z`?Nc0HRhUF4RE#;L+kz{YNEth6Sx zOirocG}a~CprK7oAmg)=Y1Q;?&dstQsDp5=0P4lG)}r1QEj6$$jL{4tD=2MUCYz~< z$v-ob0tinymce.js Always + + + + + + Always diff --git a/Disco.Web/Extensions/T4MVC/API.DeviceController.generated.cs b/Disco.Web/Extensions/T4MVC/API.DeviceController.generated.cs index d387e176..a9381709 100644 --- a/Disco.Web/Extensions/T4MVC/API.DeviceController.generated.cs +++ b/Disco.Web/Extensions/T4MVC/API.DeviceController.generated.cs @@ -480,7 +480,7 @@ namespace Disco.Web.Areas.API.Controllers public class ActionParamsClass_AttachmentUpload { public readonly string id = "id"; - public readonly string Comments = "Comments"; + public readonly string comments = "comments"; } static readonly ActionParamsClass_Attachment s_params_Attachment = new ActionParamsClass_Attachment(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] @@ -812,15 +812,15 @@ namespace Disco.Web.Areas.API.Controllers } [NonAction] - partial void AttachmentUploadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id, string Comments); + partial void AttachmentUploadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id, string comments); [NonAction] - public override System.Web.Mvc.ActionResult AttachmentUpload(string id, string Comments) + public override System.Web.Mvc.ActionResult AttachmentUpload(string id, string comments) { var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentUpload); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); - ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Comments", Comments); - AttachmentUploadOverride(callInfo, id, Comments); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "comments", comments); + AttachmentUploadOverride(callInfo, id, comments); return callInfo; } diff --git a/Disco.Web/Extensions/T4MVC/API.JobController.generated.cs b/Disco.Web/Extensions/T4MVC/API.JobController.generated.cs index 7ba2ad30..41eb76e8 100644 --- a/Disco.Web/Extensions/T4MVC/API.JobController.generated.cs +++ b/Disco.Web/Extensions/T4MVC/API.JobController.generated.cs @@ -1175,7 +1175,7 @@ namespace Disco.Web.Areas.API.Controllers public class ActionParamsClass_AttachmentUpload { public readonly string id = "id"; - public readonly string Comments = "Comments"; + public readonly string comments = "comments"; } static readonly ActionParamsClass_Attachment s_params_Attachment = new ActionParamsClass_Attachment(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] @@ -1253,7 +1253,7 @@ namespace Disco.Web.Areas.API.Controllers [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public class ActionParamsClass_Export { - public readonly string Model = "Model"; + public readonly string model = "model"; } static readonly ActionParamsClass_ExportRetrieve s_params_ExportRetrieve = new ActionParamsClass_ExportRetrieve(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] @@ -2052,15 +2052,15 @@ namespace Disco.Web.Areas.API.Controllers } [NonAction] - partial void AttachmentUploadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, string Comments); + partial void AttachmentUploadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, string comments); [NonAction] - public override System.Web.Mvc.ActionResult AttachmentUpload(int id, string Comments) + public override System.Web.Mvc.ActionResult AttachmentUpload(int id, string comments) { var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentUpload); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); - ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Comments", Comments); - AttachmentUploadOverride(callInfo, id, Comments); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "comments", comments); + AttachmentUploadOverride(callInfo, id, comments); return callInfo; } @@ -2189,14 +2189,14 @@ namespace Disco.Web.Areas.API.Controllers } [NonAction] - partial void ExportOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, Disco.Web.Models.Job.ExportModel Model); + partial void ExportOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, Disco.Web.Models.Job.ExportModel model); [NonAction] - public override System.Web.Mvc.ActionResult Export(Disco.Web.Models.Job.ExportModel Model) + public override System.Web.Mvc.ActionResult Export(Disco.Web.Models.Job.ExportModel model) { var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Export); - ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Model", Model); - ExportOverride(callInfo, Model); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "model", model); + ExportOverride(callInfo, model); return callInfo; } diff --git a/Disco.Web/Extensions/T4MVC/API.SystemController.generated.cs b/Disco.Web/Extensions/T4MVC/API.SystemController.generated.cs index 4494a5b3..6d0fb76a 100644 --- a/Disco.Web/Extensions/T4MVC/API.SystemController.generated.cs +++ b/Disco.Web/Extensions/T4MVC/API.SystemController.generated.cs @@ -260,7 +260,7 @@ namespace Disco.Web.Areas.API.Controllers [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public class ActionParamsClass_DeleteOrganisationAddress { - public readonly string Id = "Id"; + public readonly string id = "id"; public readonly string redirect = "redirect"; } static readonly ActionParamsClass_UpdateMultiSiteMode s_params_UpdateMultiSiteMode = new ActionParamsClass_UpdateMultiSiteMode(); @@ -498,15 +498,15 @@ namespace Disco.Web.Areas.API.Controllers } [NonAction] - partial void DeleteOrganisationAddressOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int Id, bool redirect); + partial void DeleteOrganisationAddressOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, bool redirect); [NonAction] - public override System.Web.Mvc.ActionResult DeleteOrganisationAddress(int Id, bool redirect) + public override System.Web.Mvc.ActionResult DeleteOrganisationAddress(int id, bool redirect) { var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.DeleteOrganisationAddress); - ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Id", Id); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "redirect", redirect); - DeleteOrganisationAddressOverride(callInfo, Id, redirect); + DeleteOrganisationAddressOverride(callInfo, id, redirect); return callInfo; } diff --git a/Disco.Web/Extensions/T4MVC/API.UserController.generated.cs b/Disco.Web/Extensions/T4MVC/API.UserController.generated.cs index f026a6b5..24e1c13d 100644 --- a/Disco.Web/Extensions/T4MVC/API.UserController.generated.cs +++ b/Disco.Web/Extensions/T4MVC/API.UserController.generated.cs @@ -179,7 +179,7 @@ namespace Disco.Web.Areas.API.Controllers { public readonly string id = "id"; public readonly string Domain = "Domain"; - public readonly string Comments = "Comments"; + public readonly string comments = "comments"; } static readonly ActionParamsClass_Attachment s_params_Attachment = new ActionParamsClass_Attachment(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] @@ -278,16 +278,16 @@ namespace Disco.Web.Areas.API.Controllers } [NonAction] - partial void AttachmentUploadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id, string Domain, string Comments); + partial void AttachmentUploadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id, string Domain, string comments); [NonAction] - public override System.Web.Mvc.ActionResult AttachmentUpload(string id, string Domain, string Comments) + public override System.Web.Mvc.ActionResult AttachmentUpload(string id, string Domain, string comments) { var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentUpload); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Domain", Domain); - ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Comments", Comments); - AttachmentUploadOverride(callInfo, id, Domain, Comments); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "comments", comments); + AttachmentUploadOverride(callInfo, id, Domain, comments); return callInfo; } diff --git a/Disco.Web/Extensions/T4MVC/T4MVC.cs b/Disco.Web/Extensions/T4MVC/T4MVC.cs index 1ea0e2b7..8854d476 100644 --- a/Disco.Web/Extensions/T4MVC/T4MVC.cs +++ b/Disco.Web/Extensions/T4MVC/T4MVC.cs @@ -648,11 +648,17 @@ namespace Links public const string UrlPath = "~/ClientSource/Style/Images/AttachmentTypes"; public static string Url() { return T4MVCHelpers.ProcessVirtualPath(UrlPath); } public static string Url(string fileName) { return T4MVCHelpers.ProcessVirtualPath(UrlPath + "/" + fileName); } + public static readonly string archive_png = Url("archive.png"); + public static readonly string audio_png = Url("audio.png"); + public static readonly string binary_png = Url("binary.png"); public static readonly string document_png = Url("document.png"); public static readonly string expressionBrowserIcons_png = Url("expressionBrowserIcons.png"); public static readonly string image_png = Url("image.png"); public static readonly string pdf_png = Url("pdf.png"); + public static readonly string spreadsheet_png = Url("spreadsheet.png"); + public static readonly string txt_png = Url("txt.png"); public static readonly string unknown_png = Url("unknown.png"); + public static readonly string video_png = Url("video.png"); } public static readonly string BackgroundDocument_png = Url("BackgroundDocument.png"); diff --git a/Disco.Web/Views/Job/JobParts/Resources.cshtml b/Disco.Web/Views/Job/JobParts/Resources.cshtml index a31de59e..a94c6798 100644 --- a/Disco.Web/Views/Job/JobParts/Resources.cshtml +++ b/Disco.Web/Views/Job/JobParts/Resources.cshtml @@ -69,7 +69,7 @@ @{if (!string.IsNullOrEmpty(ja.DocumentTemplateId)) { @ja.DocumentTemplate.Description} else - { @ja.Comments }} + { @(ja.Comments ?? ja.Filename) }} @ja.TechUser.ToStringFriendly()@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ja.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase))) {}@ja.Timestamp.ToFullDateTime() diff --git a/Disco.Web/Views/Job/JobParts/Resources.generated.cs b/Disco.Web/Views/Job/JobParts/Resources.generated.cs index 6cda1bb9..32d6fd6e 100644 --- a/Disco.Web/Views/Job/JobParts/Resources.generated.cs +++ b/Disco.Web/Views/Job/JobParts/Resources.generated.cs @@ -489,14 +489,14 @@ WriteLiteral(">\r\n"); #line hidden #line 72 "..\..\Views\Job\JobParts\Resources.cshtml" - Write(ja.Comments); + Write(ja.Comments ?? ja.Filename); #line default #line hidden #line 72 "..\..\Views\Job\JobParts\Resources.cshtml" - } + } #line default #line hidden @@ -549,14 +549,14 @@ WriteLiteral(" data-livestamp=\""); #line hidden WriteLiteral("\""); -WriteAttribute("title", Tuple.Create(" title=\"", 4634), Tuple.Create("\"", 4672) +WriteAttribute("title", Tuple.Create(" title=\"", 4651), Tuple.Create("\"", 4689) #line 74 "..\..\Views\Job\JobParts\Resources.cshtml" - , Tuple.Create(Tuple.Create("", 4642), Tuple.Create(ja.Timestamp.ToFullDateTime() + , Tuple.Create(Tuple.Create("", 4659), Tuple.Create(ja.Timestamp.ToFullDateTime() #line default #line hidden -, 4642), false) +, 4659), false) ); WriteLiteral(">"); diff --git a/Disco.Web/Views/User/UserParts/_Resources.cshtml b/Disco.Web/Views/User/UserParts/_Resources.cshtml index 0e138ad2..9d4bada7 100644 --- a/Disco.Web/Views/User/UserParts/_Resources.cshtml +++ b/Disco.Web/Views/User/UserParts/_Resources.cshtml @@ -37,7 +37,7 @@ @{if (!string.IsNullOrEmpty(ua.DocumentTemplateId)) { @ua.DocumentTemplate.Description} else - { @ua.Comments }} + { @(ua.Comments ?? ua.Filename) }} @ua.TechUser.ToStringFriendly()@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ua.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase))) {}@ua.Timestamp.ToFullDateTime() diff --git a/Disco.Web/Views/User/UserParts/_Resources.generated.cs b/Disco.Web/Views/User/UserParts/_Resources.generated.cs index 81d784a7..67ccf713 100644 --- a/Disco.Web/Views/User/UserParts/_Resources.generated.cs +++ b/Disco.Web/Views/User/UserParts/_Resources.generated.cs @@ -250,14 +250,14 @@ WriteLiteral(">\r\n"); #line hidden #line 40 "..\..\Views\User\UserParts\_Resources.cshtml" - Write(ua.Comments); + Write(ua.Comments ?? ua.Filename); #line default #line hidden #line 40 "..\..\Views\User\UserParts\_Resources.cshtml" - } + } #line default #line hidden @@ -310,14 +310,14 @@ WriteLiteral(" data-livestamp=\""); #line hidden WriteLiteral("\""); -WriteAttribute("title", Tuple.Create(" title=\"", 2671), Tuple.Create("\"", 2709) +WriteAttribute("title", Tuple.Create(" title=\"", 2688), Tuple.Create("\"", 2726) #line 42 "..\..\Views\User\UserParts\_Resources.cshtml" - , Tuple.Create(Tuple.Create("", 2679), Tuple.Create(ua.Timestamp.ToFullDateTime() + , Tuple.Create(Tuple.Create("", 2696), Tuple.Create(ua.Timestamp.ToFullDateTime() #line default #line hidden -, 2679), false) +, 2696), false) ); WriteLiteral(">");