qol: wait for attachment thumbnail generation and show additional file type-specific icons

This commit is contained in:
Gary Sharp
2024-12-18 19:37:15 +11:00
parent 9f10eeeb70
commit 7550e0e45d
24 changed files with 226 additions and 116 deletions
@@ -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;
}
}
+3
View File
@@ -141,6 +141,9 @@
<HintPath>..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="System.Security" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+1
View File
@@ -29,5 +29,6 @@
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net45" />
<package id="SqlServerCompact" version="4.0.8854.1" targetFramework="net40" />
<package id="SSH.NET" version="2023.0.0" targetFramework="net462" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" />
<package id="WebActivatorEx" version="2.0.5" targetFramework="net45" />
</packages>
@@ -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");
}
@@ -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");
}
@@ -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");
}
@@ -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<string> 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<string> 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<string> 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;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

+6
View File
@@ -1634,6 +1634,12 @@
<DependentUpon>tinymce.js</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="ClientSource\Style\Images\AttachmentTypes\archive.png" />
<Content Include="ClientSource\Style\Images\AttachmentTypes\audio.png" />
<Content Include="ClientSource\Style\Images\AttachmentTypes\binary.png" />
<Content Include="ClientSource\Style\Images\AttachmentTypes\spreadsheet.png" />
<Content Include="ClientSource\Style\Images\AttachmentTypes\txt.png" />
<Content Include="ClientSource\Style\Images\AttachmentTypes\video.png" />
<Content Include="ClientSource\Style\Images\UnknownPhoto.png" />
<Content Include="ClientSource\Style\Shadowbox.min.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
+6
View File
@@ -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");
@@ -69,7 +69,7 @@
@{if (!string.IsNullOrEmpty(ja.DocumentTemplateId))
{ @ja.DocumentTemplate.Description}
else
{ @ja.Comments }}
{ @(ja.Comments ?? ja.Filename) }}
</span><span class="author">@ja.TechUser.ToStringFriendly()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ja.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(ja.Timestamp.ToUnixEpoc())" title="@ja.Timestamp.ToFullDateTime()">@ja.Timestamp.ToFullDateTime()</span>
</a>
@@ -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<System.Object, System.Int32>(ja.Timestamp.ToFullDateTime()
, Tuple.Create(Tuple.Create("", 4659), Tuple.Create<System.Object, System.Int32>(ja.Timestamp.ToFullDateTime()
#line default
#line hidden
, 4642), false)
, 4659), false)
);
WriteLiteral(">");
@@ -37,7 +37,7 @@
@{if (!string.IsNullOrEmpty(ua.DocumentTemplateId))
{ @ua.DocumentTemplate.Description}
else
{ @ua.Comments }}
{ @(ua.Comments ?? ua.Filename) }}
</span><span class="author">@ua.TechUser.ToStringFriendly()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ua.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(ua.Timestamp.ToUnixEpoc())" title="@ua.Timestamp.ToFullDateTime()">@ua.Timestamp.ToFullDateTime()</span>
</a>
@@ -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<System.Object, System.Int32>(ua.Timestamp.ToFullDateTime()
, Tuple.Create(Tuple.Create("", 2696), Tuple.Create<System.Object, System.Int32>(ua.Timestamp.ToFullDateTime()
#line default
#line hidden
, 2679), false)
, 2696), false)
);
WriteLiteral(">");