Skip to content

Commit

Permalink
Copy Views from VocaDbWeb to VocaDbWeb.Core
Browse files Browse the repository at this point in the history
  • Loading branch information
ycanardeau committed Dec 21, 2020
1 parent 29bf06b commit a5a512b
Show file tree
Hide file tree
Showing 319 changed files with 14,943 additions and 1 deletion.
2 changes: 1 addition & 1 deletion VocaDbWeb.Core/Code/GravatarUserIconFactory.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#nullable disable

using Microsoft.Web.Helpers;
using VocaDb.Model.DataContracts;
using VocaDb.Model.DataContracts.Users;
using VocaDb.Model.Domain.Images;
using VocaDb.Model.Domain.Users;
using VocaDb.Model.Helpers;
using VocaDb.Web.Helpers;

namespace VocaDb.Web.Code
{
Expand Down
9 changes: 9 additions & 0 deletions VocaDbWeb.Core/Code/VocaDbPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ public IHtmlContent ToJS(object obj)
public VocaUrlMapper UrlMapper => new VocaUrlMapper();

public IUserPermissionContext UserContext => Context.RequestServices.GetRequiredService<IUserPermissionContext>();

// Code from: https://github.com/aspnet/AspNetWebStack/blob/749384689e027a2fcd29eb79a9137b94cea611a8/src/System.Web.WebPages/WebPageRenderingBase.cs#L178
public string Culture => Thread.CurrentThread.CurrentCulture.Name;

// Code from: https://github.com/aspnet/AspNetWebStack/blob/749384689e027a2fcd29eb79a9137b94cea611a8/src/System.Web.WebPages/WebPageRenderingBase.cs#L192
public string UICulture => Thread.CurrentThread.CurrentUICulture.Name;
}

public abstract class VocaDbPage : RazorPage
Expand Down Expand Up @@ -118,6 +124,9 @@ public IHtmlContent ToJS(object obj)

public IUserPermissionContext UserContext => Context.RequestServices.GetRequiredService<IUserPermissionContext>();

// Code from: https://github.com/aspnet/AspNetWebStack/blob/749384689e027a2fcd29eb79a9137b94cea611a8/src/System.Web.WebPages/WebPageRenderingBase.cs#L178
public string Culture => Thread.CurrentThread.CurrentCulture.Name;

// Code from: https://github.com/aspnet/AspNetWebStack/blob/749384689e027a2fcd29eb79a9137b94cea611a8/src/System.Web.WebPages/WebPageRenderingBase.cs#L192
public string UICulture => Thread.CurrentThread.CurrentUICulture.Name;
}
Expand Down
96 changes: 96 additions & 0 deletions VocaDbWeb.Core/Helpers/ArchivedEntryHtmlExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#nullable disable

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using VocaDb.Model.DataContracts;
using VocaDb.Model.DataContracts.Versioning;
using VocaDb.Model.Domain;
using VocaDb.Model.Domain.Globalization;
using VocaDb.Web.Models.Shared.Partials.ArchivedEntry;

namespace VocaDb.Web.Helpers
{
public static class ArchivedEntryHtmlExtensions
{
public static IHtmlContent DataRow<T>(this IHtmlHelper htmlHelper, string name, T primary, T compared, Func<T, object> valGetter, bool preserveLineBreaks = false)
where T : class
{

var val1 = valGetter(primary);
var val2 = (compared != null ? valGetter(compared) : null);

return htmlHelper.Partial("Partials/ArchivedEntry/_DataRow", new DataRowViewModel(name, val1, val2, preserveLineBreaks));

}

public static IHtmlContent DataRow<T>(this IHtmlHelper htmlHelper, string name, ComparedVersionsContract<T> comparedVersions, Func<T, object> valGetter, bool preserveLineBreaks = false)
where T : class
{

var val1 = valGetter(comparedVersions.FirstData);
var val2 = (comparedVersions.SecondData != null ? valGetter(comparedVersions.SecondData) : null);

return htmlHelper.Partial("Partials/ArchivedEntry/_DataRow", new DataRowViewModel(name, val1, val2, preserveLineBreaks));

}

public static IHtmlContent DataRowList<T>(this IHtmlHelper htmlHelper, string name, T primary, T compared, Func<T, IEnumerable<IHtmlContent>> valGetter)
where T : class
{

var val1 = valGetter(primary);
var val2 = (compared != null ? valGetter(compared) : null);

return htmlHelper.Partial("Partials/ArchivedEntry/_DataRowList", new DataRowListViewModel(name, val1, val2));

}

public static IHtmlContent DataRowList<T>(this IHtmlHelper htmlHelper, string name, ComparedVersionsContract<T> comparedVersions, Func<T, IEnumerable<IHtmlContent>> valGetter)
where T : class
{

var val1 = valGetter(comparedVersions.FirstData);
var val2 = (comparedVersions.SecondData != null ? valGetter(comparedVersions.SecondData) : null);

return htmlHelper.Partial("Partials/ArchivedEntry/_DataRowList", new DataRowListViewModel(name, val1, val2));

}

public static string FormatReleaseDate(OptionalDateTimeContract contract)
{
return OptionalDateTime.ToDateTime(contract.Year, contract.Month, contract.Day).ToShortDateString();
}

public static IHtmlContent ObjectRefList<T>(this IHtmlHelper htmlHelper, string name, ComparedVersionsContract<T> comparedVersions,
Func<T, IEnumerable<ObjectRefContract>> valGetter) where T : class
{

return DataRowList(htmlHelper, name, comparedVersions, d => DataFormatUtils.GenerateHtml(valGetter(d), objRef => htmlHelper.Partial("Partials/ArchivedEntry/_ObjectRefInfo", new ObjectRefInfoViewModel(objRef))));

}

public static IHtmlContent PictureRow<T>(this IHtmlHelper htmlHelper, string name, ComparedVersionsContract<T> comparedVersions, Func<int, string> urlGetter)
where T : class
{

var val1 = urlGetter(comparedVersions.FirstId);
var val2 = (comparedVersions.SecondId != 0 ? urlGetter(comparedVersions.SecondId) : null);

return htmlHelper.Partial("Partials/ArchivedEntry/_PictureRow", new PictureRowViewModel(name, val1, val2));

}

public static IHtmlContent TranslatedNameRow<T>(this IHtmlHelper htmlHelper, ComparedVersionsContract<T> comparedVersions, Func<T, ITranslatedString> valGetter)
where T : class
{

var val1 = valGetter(comparedVersions.FirstData);
var val2 = comparedVersions.SecondData != null ? valGetter(comparedVersions.SecondData) : null;

return htmlHelper.Partial("Partials/ArchivedEntry/_TranslatedNameRow", new TranslatedNameRowViewModel(val1, val2));

}
}
}
47 changes: 47 additions & 0 deletions VocaDbWeb.Core/Helpers/Gravatar.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Code from: https://github.com/mono/aspnetwebstack/blob/6248bfd24c31356e75a31c1b1030d4d96f669a6a/src/Microsoft.Web.Helpers/Gravatar.cs

using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.AspNetCore.Html;
using Microsoft.Web.Helpers;

namespace VocaDb.Web.Helpers
{
public static class Gravatar
{
// review - extract conversion of anonymous object to html attributes string into separate helper
public static HtmlString GetHtml(string email, int imageSize = 80, string? defaultImage = null, GravatarRating rating = GravatarRating.Default, string? imageExtension = null, object? attributes = null)
{
var altSpecified = false;
var url = GetUrl(email, imageSize, defaultImage, rating, imageExtension);
var html = new StringBuilder(string.Format(CultureInfo.InvariantCulture, "<img src=\"{0}\" ", url));
if (attributes != null)
{
foreach (var p in attributes.GetType().GetProperties().OrderBy(p => p.Name))
{
if (!p.Name.Equals("src", StringComparison.OrdinalIgnoreCase))
{
var value = p.GetValue(attributes, null);
if (value != null)
{
var encodedValue = HttpUtility.HtmlAttributeEncode(value.ToString());
html.Append(string.Format(CultureInfo.InvariantCulture, "{0}=\"{1}\" ", p.Name, encodedValue));
}
if (p.Name.Equals("alt", StringComparison.OrdinalIgnoreCase))
altSpecified = true;
}
}
}
if (!altSpecified)
html.Append("alt=\"gravatar\" ");
html.Append("/>");
return new HtmlString(html.ToString());
}

public static string GetUrl(string email, int imageSize = 80, string? defaultImage = null, GravatarRating rating = GravatarRating.Default, string? imageExtension = null)
=> Microsoft.Web.Helpers.Gravatar.GetUrl(email, imageSize, defaultImage, rating, imageExtension);
}
}
102 changes: 102 additions & 0 deletions VocaDbWeb.Core/Helpers/HtmlPrefixScopeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Code from: https://github.com/saad749/BeginCollectionItemCore/blob/6614c505fde60fa72430c9da18999b8ceb7918f7/BeginCollectionItemCore/HtmlPrefixScopeExtensions.cs

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.IO;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace VocaDb.Web.Helpers
{
public static class HtmlPrefixScopeExtensions
{
private const string IdsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";

public static IDisposable BeginCollectionItem(this IHtmlHelper html, string collectionName)
{
return BeginCollectionItem(html, collectionName, html.ViewContext.Writer);
}

public static IDisposable BeginCollectionItem(this IHtmlHelper html, string collectionName, TextWriter writer)
{
/*
* added Nested collection support for newly added collection items
* as per this http://stackoverflow.com/questions/33916004/nested-list-of-lists-with-begincollectionitem
* and this http://www.joe-stevens.com/2011/06/06/editing-and-binding-nested-lists-with-asp-net-mvc-2/
*/
if (html.ViewData["ContainerPrefix"] != null)
collectionName = string.Concat(html.ViewData["ContainerPrefix"], ".", collectionName);

var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
var itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();

string htmlFieldPrefix = $"{collectionName}[{itemIndex}]";
html.ViewData["ContainerPrefix"] = htmlFieldPrefix;

/*
* html.Name(); has been removed
* because of incorrect naming of collection items
* e.g.
* let collectionName = "Collection"
* the first item's name was Collection[0].Collection[<GUID>]
* instead of Collection[<GUID>]
*/
string indexInputName = $"{collectionName}.index";

// autocomplete="off" is needed to work around a very annoying Chrome behaviour
// whereby it reuses old values after the user clicks "Back", which causes the
// xyz.index and xyz[...] values to get out of sync.
writer.WriteLine($@"<input type=""hidden"" name=""{indexInputName}"" autocomplete=""off"" value=""{html.Encode(itemIndex)}"" />");


return BeginHtmlFieldPrefixScope(html, htmlFieldPrefix);
}

public static IDisposable BeginHtmlFieldPrefixScope(this IHtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}

private static Queue<string> GetIdsToReuse(HttpContext httpContext, string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,
// otherwise the framework won't render the validation error messages next to each item.
var key = IdsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null)
{
httpContext.Items[key] = queue = new Queue<string>();

if (httpContext.Request.Method == "POST" && httpContext.Request.HasFormContentType)
{
StringValues previouslyUsedIds = httpContext.Request.Form[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (var previouslyUsedId in previouslyUsedIds)
queue.Enqueue(previouslyUsedId);
}
}
return queue;
}

internal class HtmlFieldPrefixScope : IDisposable
{
internal readonly TemplateInfo TemplateInfo;
internal readonly string PreviousHtmlFieldPrefix;

public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
TemplateInfo = templateInfo;

PreviousHtmlFieldPrefix = TemplateInfo.HtmlFieldPrefix;
TemplateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}

public void Dispose()
{
TemplateInfo.HtmlFieldPrefix = PreviousHtmlFieldPrefix;
}
}
}
}
22 changes: 22 additions & 0 deletions VocaDbWeb.Core/Views/ActivityEntry/FollowedArtistActivity.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@using VocaDb.Web.Models.Shared.Partials.Activityfeed
@model VocaDb.Model.DataContracts.Activityfeed.ActivityEntryForApiContract[]

@{
PageProperties.Title = "New activity by followed artists";
}

<ul class="nav nav-pills">
<li>
@Html.ActionLink("All activity", "Index")
</li>
<li class="active">
@Html.ActionLink("Only followed artists", "FollowedArtistActivity")
</li>
<li>
@Html.ActionLink("Comments", "Index", "Comment")
</li>
</ul>

@foreach (var entry in Model) {
@Html.Partial("Partials/Activityfeed/_ActivityEntry", new ActivityEntryViewModel(entry))
}
55 changes: 55 additions & 0 deletions VocaDbWeb.Core/Views/ActivityEntry/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@using VocaDb.Web.Models.Shared.Partials.Activityfeed
@using VocaDb.Web.Helpers
@using Res = VocaDb.Web.Resources.Views.ActivityEntry.IndexStrings
@inherits VocaDb.Web.Code.VocaDbPage
@inject LaravelMixHelper LaravelMixHelper
@inject Login Login

@{
PageProperties.Title = Res.RecentActivity;
}

<!-- Binding context: ActivityEntryListViewModel -->

<ul class="nav nav-pills">
<li class="active">
@Html.ActionLink(Res.AllActivity, "Index")
</li>
@if (Login.IsLoggedIn) {
<li>
@Html.ActionLink(Res.FollowedArtists, "FollowedArtistActivity")
</li>
}
<li>
@Html.ActionLink(Res.Comments, "Index", "Comment")
</li>
</ul>

<div data-bind="foreach: entries, show" class="js-cloak">
@Html.Partial("Partials/Activityfeed/_ActivityEntryKnockout", new ActivityEntryKnockoutViewModel("$parent.getEntryTypeName", "$parent.getActivityFeedEventName", "$parents[1].getChangedFieldNames", true))
</div>

<hr />
<h3>
<a href="#" data-bind="click: loadMore">@Res.ViewMore</a>
</h3>

@section BodyScripts {
<script src="@LaravelMixHelper.GetPathToVersionedMixFile("~/bundles/ActivityEntry/Index.js")"></script>
<script type="text/javascript">
$(function () {
moment.locale('@Culture');
ko.punches.enableAll();
var urlMapper = new app.UrlMapper("@RootPath");
var resourceRepo = new app.ResourceRepository('@RootPath');
var languageSelection = '@UserContext.LanguagePreference';
var cultureCode = '@UICulture';
var vm = new app.ActivityEntryListViewModel(urlMapper, resourceRepo, languageSelection, cultureCode);
ko.applyBindings(vm);
});
</script>
}
28 changes: 28 additions & 0 deletions VocaDbWeb.Core/Views/Admin/ActiveEdits.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@using VocaDb.Web.Helpers
@model Tuple<VocaDb.Model.DataContracts.Api.EntryForApiContract, VocaDb.Model.DataContracts.Users.UserContract, DateTime>[]

@{
PageProperties.Title = "Active editors";
ViewBag.Parents = new[] {
Html.ActionLink("Manage", "Index"),
};
}

<table>
<thead>
<tr>
<th>Entry</th>
<th>Editor</th>
<th>Time</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td><a href="@Url.EntryDetails(item.Item1)">@item.Item1.Name</a></td>
<td><a href="@Url.UserDetails(item.Item2)">@item.Item2.Name</a></td>
<td>@item.Item3</td>
</tr>
}
</tbody>
</table>
Loading

0 comments on commit a5a512b

Please sign in to comment.