This commit is contained in:
Zel
2025-02-23 18:47:21 +08:00
parent eaaffeeccb
commit e46a7ca31c
104 changed files with 2630 additions and 2516 deletions

View File

@@ -6,14 +6,14 @@ namespace ZelWiki.Library
public static class ConfirmActionHelper
{
/// <summary>
/// Generates a link that navigates via GET to a "confirm action" page where the yes link is RED, but the NO button is still GREEN.
/// 生成一个链接通过GET导航到“确认操作”页面其中“是”链接为红色但“否”按钮仍为绿色。
/// </summary>
/// <param name="message">The message to be displayed.</param>
/// <param name="linkLabel">the label for the link that will redirect to this confirm action page.</param>
/// <param name="controllerURL">The URL which will handle the click of the "yes" or "no" for the confirm action page.</param>
/// <param name="parameter">An optional parameter to pass to the page and controller function.</param>
/// <param name="yesOrDefaultRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected YES (or NO, if the NO link is not specified.</param>
/// <param name="noRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected NO, if not specified, the same link that is provided to yesOrDefaultRedirectURL is used.</param>
/// <param name="basePath"></param>
/// <param name="message"></param>
/// <param name="linkLabel"></param>
/// <param name="controllerURL"></param>
/// <param name="yesOrDefaultRedirectURL"></param>
/// <param name="noRedirectURL"></param>
/// <returns></returns>
public static string GenerateDangerLink(string basePath, string message, string linkLabel, string controllerURL,
string? yesOrDefaultRedirectURL, string? noRedirectURL = null)
@@ -30,18 +30,19 @@ namespace ZelWiki.Library
param.Append($"&Message={Uri.EscapeDataString(message)}");
param.Append($"&Style=Danger");
return $"<a class=\"btn btn-danger btn-thin\" href=\"{basePath}/Utility/ConfirmAction?{param}\">{linkLabel}</a>";
return
$"<a class=\"btn btn-danger btn-thin\" href=\"{basePath}/Utility/ConfirmAction?{param}\">{linkLabel}</a>";
}
/// <summary>
/// Generates a link that navigates via GET to a "confirm action" page where the yes link is GREEN.
/// 生成一个链接通过GET导航到“确认操作”页面其中“是”链接为绿色。
/// </summary>
/// <param name="message">The message to be displayed.</param>
/// <param name="linkLabel">the label for the link that will redirect to this confirm action page.</param>
/// <param name="controllerURL">The URL which will handle the click of the "yes" or "no" for the confirm action page.</param>
/// <param name="parameter">An optional parameter to pass to the page and controller function.</param>
/// <param name="yesOrDefaultRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected YES (or NO, if the NO link is not specified.</param>
/// <param name="noRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected NO, if not specified, the same link that is provided to yesOrDefaultRedirectURL is used.</param>
/// <param name="basePath"></param>
/// <param name="message"></param>
/// <param name="linkLabel"></param>
/// <param name="controllerURL"></param>
/// <param name="yesOrDefaultRedirectURL"></param>
/// <param name="noRedirectURL"></param>
/// <returns></returns>
public static string GenerateSafeLink(string basePath, string message, string linkLabel, string controllerURL,
string? yesOrDefaultRedirectURL, string? noRedirectURL = null)
@@ -58,18 +59,19 @@ namespace ZelWiki.Library
param.Append($"&Message={Uri.EscapeDataString(message)}");
param.Append($"&Style=Safe");
return $"<a class=\"btn btn-success btn-thin\" href=\"{basePath}/Utility/ConfirmAction?{param}\">{linkLabel}</a>";
return
$"<a class=\"btn btn-success btn-thin\" href=\"{basePath}/Utility/ConfirmAction?{param}\">{linkLabel}</a>";
}
/// <summary>
/// Generates a link that navigates via GET to a "confirm action" page where the yes link is YELLOW, but the NO button is still GREEN.
/// 生成一个链接通过GET导航到“确认操作”页面其中“是”链接为黄色但“否”按钮仍为绿色。
/// </summary>
/// <param name="message">The message to be displayed.</param>
/// <param name="linkLabel">the label for the link that will redirect to this confirm action page.</param>
/// <param name="controllerURL">The URL which will handle the click of the "yes" or "no" for the confirm action page.</param>
/// <param name="parameter">An optional parameter to pass to the page and controller function.</param>
/// <param name="yesOrDefaultRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected YES (or NO, if the NO link is not specified.</param>
/// <param name="noRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected NO, if not specified, the same link that is provided to yesOrDefaultRedirectURL is used.</param>
/// <param name="basePath"></param>
/// <param name="message"></param>
/// <param name="linkLabel"></param>
/// <param name="controllerURL"></param>
/// <param name="yesOrDefaultRedirectURL"></param>
/// <param name="noRedirectURL"></param>
/// <returns></returns>
public static string GenerateWarnLink(string basePath, string message, string linkLabel, string controllerURL,
string? yesOrDefaultRedirectURL, string? noRedirectURL = null)
@@ -86,19 +88,19 @@ namespace ZelWiki.Library
param.Append($"&Message={Uri.EscapeDataString(message)}");
param.Append($"&Style=Warn");
return $"<a class=\"btn btn-warning btn-thin\" href=\"{basePath}/Utility/ConfirmAction?{param}\">{linkLabel}</a>";
return
$"<a class=\"btn btn-warning btn-thin\" href=\"{basePath}/Utility/ConfirmAction?{param}\">{linkLabel}</a>";
}
/*
/// <summary>
/// Generates a link that navigates via POST to a "confirm action" page where the yes button is RED, but the NO button is still GREEN.
///
/// </summary>
/// <param name="message">The message to be displayed.</param>
/// <param name="buttonLabel">the label for the button that will redirect to this confirm action page.</param>
/// <param name="controllerURL">The URL which will handle the click of the "yes" or "no" for the confirm action page.</param>
/// <param name="parameter">An optional parameter to pass to the page and controller function.</param>
/// <param name="yesOrDefaultRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected YES (or NO, if the NO link is not specified.</param>
/// <param name="noRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected NO, if not specified, the same link that is provided to yesOrDefaultRedirectURL is used.</param>
/// <param name="message"></param>
/// <param name="buttonLabel"></param>
/// <param name="controllerURL"></param>
/// <param name="yesOrDefaultRedirectURL"></param>
/// <param name="noRedirectURL"></param>
/// <returns></returns>
public static string GenerateDangerButton(string message, string buttonLabel, string controllerURL,
string? yesOrDefaultRedirectURL, string? noRedirectURL = null)
@@ -115,21 +117,22 @@ namespace ZelWiki.Library
html.Append($"<input type='hidden' name='NoRedirectURL' value='{noRedirectURL}' />");
html.Append($"<input type='hidden' name='Message' value='{message}' />");
html.Append($"<input type='hidden' name='Style' value='Danger' />");
html.Append($"<button type='submit' class='btn btn-danger rounded-0' name='ActionToConfirm' value='PurgeDeletedPages'>{buttonLabel}</button>");
html.Append(
$"<button type='submit' class='btn btn-danger rounded-0' name='ActionToConfirm' value='PurgeDeletedPages'>{buttonLabel}</button>");
html.Append("</form>");
return html.ToString();
}
/// <summary>
/// Generates a link that navigates via POST to a "confirm action" page where the yes and no buttons are GREEN.
///
/// </summary>
/// <param name="message">The message to be displayed.</param>
/// <param name="buttonLabel">the label for the button that will redirect to this confirm action page.</param>
/// <param name="controllerURL">The URL which will handle the click of the "yes" or "no" for the confirm action page.</param>
/// <param name="parameter">An optional parameter to pass to the page and controller function.</param>
/// <param name="yesOrDefaultRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected YES (or NO, if the NO link is not specified.</param>
/// <param name="noRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected NO, if not specified, the same link that is provided to yesOrDefaultRedirectURL is used.</param>
/// <param name="message"></param>
/// <param name="buttonLabel"></param>
/// <param name="controllerURL"></param>
/// <param name="yesOrDefaultRedirectURL"></param>
/// <param name="noRedirectURL"></param>
/// <returns></returns>
public static string GenerateSafeButton(string message, string buttonLabel, string controllerURL,
string? yesOrDefaultRedirectURL, string? noRedirectURL = null)
{
@@ -146,21 +149,22 @@ namespace ZelWiki.Library
html.Append($"<input type='hidden' name='NoRedirectURL' value='{noRedirectURL}' />");
html.Append($"<input type='hidden' name='Message' value='{message}' />");
html.Append($"<input type='hidden' name='Style' value='Safe' />");
html.Append($"<button type='submit' class='btn btn-success rounded-0' name='ActionToConfirm' value='PurgeDeletedPages'>{buttonLabel}</button>");
html.Append(
$"<button type='submit' class='btn btn-success rounded-0' name='ActionToConfirm' value='PurgeDeletedPages'>{buttonLabel}</button>");
html.Append("</form>");
return html.ToString();
}
/// <summary>
/// Generates a link that navigates via POST to a "confirm action" page where the yes button is YELLOW, but the NO button is still GREEN.
///
/// </summary>
/// <param name="message">The message to be displayed.</param>
/// <param name="buttonLabel">the label for the button that will redirect to this confirm action page.</param>
/// <param name="controllerURL">The URL which will handle the click of the "yes" or "no" for the confirm action page.</param>
/// <param name="parameter">An optional parameter to pass to the page and controller function.</param>
/// <param name="yesOrDefaultRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected YES (or NO, if the NO link is not specified.</param>
/// <param name="noRedirectURL">The URL to redirect to AFTER the controller has been called if the user selected NO, if not specified, the same link that is provided to yesOrDefaultRedirectURL is used.</param>
/// <param name="message"></param>
/// <param name="buttonLabel"></param>
/// <param name="controllerURL"></param>
/// <param name="yesOrDefaultRedirectURL"></param>
/// <param name="noRedirectURL"></param>
/// <returns></returns>
public static string GenerateWarnButton(string message, string buttonLabel, string controllerURL,
string? yesOrDefaultRedirectURL, string? noRedirectURL = null)
{
@@ -177,11 +181,11 @@ namespace ZelWiki.Library
html.Append($"<input type='hidden' name='NoRedirectURL' value='{noRedirectURL}' />");
html.Append($"<input type='hidden' name='Message' value='{message}' />");
html.Append($"<input type='hidden' name='Style' value='Warn' />");
html.Append($"<button type='submit' class='btn btn-warning rounded-0' name='ActionToConfirm' value='PurgeDeletedPages'>{buttonLabel}</button>");
html.Append(
$"<button type='submit' class='btn btn-warning rounded-0' name='ActionToConfirm' value='PurgeDeletedPages'>{buttonLabel}</button>");
html.Append("</form>");
return html.ToString();
}
*/
}
}
}

View File

@@ -3,9 +3,9 @@
public static class Constants
{
public const string CRYPTOCHECK = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public const string DEFAULTUSERNAME = "admin@tightwiki.com";
public const string DEFAULTUSERNAME = "admin@ipangci.top";
public const string DEFAULTACCOUNT = "admin";
public const string DEFAULTPASSWORD = "2Tight2Wiki@";
public const string DEFAULTPASSWORD = "Zhu0906.";
public enum WikiTheme
{
@@ -16,15 +16,15 @@
public enum AdminPasswordChangeState
{
/// <summary>
/// The password has not been changed, display a big warning.
/// 密码为默认
/// </summary>
IsDefault,
/// <summary>
/// All is well!
/// 已修改密码
/// </summary>
HasBeenChanged,
/// <summary>
/// The default password status does not exist and the password needs to be set to default.
/// 默认密码状态不存在,需要将密码设置为默认值
/// </summary>
NeedsToBeSet
}
@@ -45,19 +45,19 @@
public static class Roles
{
/// <summary>
/// Administrators can do anything. Add, edit, delete, pages, users, etc.
///管理员可以做任何事情。添加、编辑、删除、页面、用户等。
/// </summary>
public const string Administrator = "Administrator";
/// <summary>
/// Read-only user with a profile.
/// 成员
/// </summary>
public const string Member = "Member";
/// <summary>
/// Contributor can add and edit pages.
/// 版主
/// </summary>
public const string Contributor = "Contributor";
/// <summary>
/// Moderators can add, edit and delete pages.
/// 主持
/// </summary>
public const string Moderator = "Moderator";
}

View File

@@ -14,7 +14,7 @@ namespace ZelWiki.Library
foreach (var ci in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
{
var regionInfo = new RegionInfo(ci.Name);
if (list.Where(o => o.Value == regionInfo.Name).Any() == false)
if (list.Any(o => o.Value == regionInfo.Name) == false)
{
list.Add(new CountryItem
{

View File

@@ -57,7 +57,7 @@ namespace ZelWiki.Library
image.SaveAsBmp(ms);
return preferredContentType;
case "image/gif":
throw new NotImplementedException("Use [ResizeGifImage] for saving animated images.");
throw new NotImplementedException("使用 [ResizeGifImage] 保存动图");
//image.SaveAsGif(ms);
//return preferredContentType;
case "image/tiff":

View File

@@ -9,36 +9,36 @@ namespace ZelWiki.Library.Interfaces
IQueryCollection? QueryString { get; set; }
/// <summary>
/// Is the current user (or anonymous) allowed to view?
///
/// </summary>
public bool CanView => true;
/// <summary>
/// Is the current user allowed to edit?
///
/// </summary>
public bool CanEdit { get; }
/// <summary>
/// Is the current user allowed to perform administrative functions?
/// 是否允许当前用户执行管理功能?
/// </summary>
public bool CanAdmin { get; }
/// <summary>
/// Is the current user allowed to moderate content (such as delete comments, and view moderation tools)?
/// 是否允许当前用户审核内容(如删除评论和查看审核工具)?
/// </summary>
public bool CanModerate { get; }
/// <summary>
/// Is the current user allowed to create pages?
///是否允许当前用户创建页面?
/// </summary>
public bool CanCreate { get; }
/// <summary>
/// Is the current user allowed to delete unprotected pages?
/// 是否允许当前用户删除未受保护的页面?
/// </summary>
public bool CanDelete { get; }
public DateTime LocalizeDateTime(DateTime datetime);
public TimeZoneInfo GetPreferredTimeZone();
}
}
}

View File

@@ -21,7 +21,7 @@ namespace ZelWiki.Library
name = name.Substring(0, name.IndexOf('(')).Trim();
}
if (list.Where(o => o.Value == name).Any() == false)
if (list.Any(o => o.Value == name) == false)
{
list.Add(new LanguageItem
{

View File

@@ -5,14 +5,14 @@ namespace ZelWiki.Library
internal static class MimeTypes
{
/// <summary>
/// Given a file path, determine the MIME type
/// 给定文件路径确定MIME类型
/// </summary>
/// <param name="subpath">A file path</param>
/// <param name="filePath">A file path</param>
/// <param name="contentType">The resulting MIME type</param>
/// <returns>True if MIME type could be determined</returns>
public static bool TryGetContentType(string filePath, [MaybeNullWhen(false)] out string contentType)
{
string extension = Path.GetExtension(filePath);
var extension = Path.GetExtension(filePath);
if (extension == null)
{
contentType = null;
@@ -20,8 +20,7 @@ namespace ZelWiki.Library
}
return Collection.TryGetValue(extension, out contentType);
}
//Borrowed from FileExtensionContentTypeProvider().TryGetContentType
public static Dictionary<string, string> Collection = new(StringComparer.OrdinalIgnoreCase)
{
{ ".323", "text/h323" },
@@ -78,7 +77,7 @@ namespace ZelWiki.Library
{ ".crt", "application/x-x509-ca-cert" },
{ ".csh", "application/x-csh" },
{ ".css", "text/css" },
{ ".csv", "text/csv" }, // https://tools.ietf.org/html/rfc7111#section-5.1
{ ".csv", "text/csv" },
{ ".cur", "application/octet-stream" },
{ ".dcr", "application/x-director" },
{ ".deploy", "application/octet-stream" },
@@ -106,7 +105,7 @@ namespace ZelWiki.Library
{ ".eps", "application/postscript" },
{ ".etx", "text/x-setext" },
{ ".evy", "application/envoy" },
{ ".exe", "application/vnd.microsoft.portable-executable" }, // https://www.iana.org/assignments/media-types/application/vnd.microsoft.portable-executable
{ ".exe", "application/vnd.microsoft.portable-executable" },
{ ".fdf", "application/vnd.fdf" },
{ ".fif", "application/fractals" },
{ ".fla", "application/octet-stream" },
@@ -347,7 +346,7 @@ namespace ZelWiki.Library
{ ".wcm", "application/vnd.ms-works" },
{ ".wdb", "application/vnd.ms-works" },
{ ".webm", "video/webm" },
{ ".webmanifest", "application/manifest+json" }, // https://w3c.github.io/manifest/#media-type-registration
{ ".webmanifest", "application/manifest+json" },
{ ".webp", "image/webp" },
{ ".wks", "application/vnd.ms-works" },
{ ".wm", "video/x-ms-wm" },
@@ -362,8 +361,8 @@ namespace ZelWiki.Library
{ ".wmv", "video/x-ms-wmv" },
{ ".wmx", "video/x-ms-wmx" },
{ ".wmz", "application/x-ms-wmz" },
{ ".woff", "application/font-woff" }, // https://www.w3.org/TR/WOFF/#appendix-b
{ ".woff2", "font/woff2" }, // https://www.w3.org/TR/WOFF2/#IMT
{ ".woff", "application/font-woff" },
{ ".woff2", "font/woff2" },
{ ".wps", "application/vnd.ms-works" },
{ ".wri", "application/x-mswrite" },
{ ".wrl", "x-world/x-vrml" },

View File

@@ -29,6 +29,7 @@ namespace ZelWiki.Library
{
return Page;
}
return $"{Namespace}::{Page}";
}
set
@@ -49,9 +50,9 @@ namespace ZelWiki.Library
}
/// <summary>
/// Creates a new instance of NamespaceNavigation.
///
/// </summary>
/// <param name="givenCanonical">Page navigation with optional namespace.</param>
/// <param name="givenCanonical"></param>
public NamespaceNavigation(string givenCanonical)
{
_lowerCase = true;
@@ -59,10 +60,10 @@ namespace ZelWiki.Library
}
/// <summary>
/// Creates a new instance of NamespaceNavigation.
///
/// </summary>
/// <param name="givenCanonical">Page navigation with optional namespace.</param>
/// <param name="lowerCase">If false, the namespace and page name will not be lowercased.</param>
/// <param name="givenCanonical"></param>
/// <param name="lowerCase"></param>
public NamespaceNavigation(string givenCanonical, bool lowerCase)
{
_lowerCase = lowerCase;
@@ -75,10 +76,10 @@ namespace ZelWiki.Library
}
/// <summary>
/// Takes a page name with optional namespace and returns the cleaned version that can be used for matching Navigations.
///
/// </summary>
/// <param name="givenCanonical">Page navigation with optional namespace.</param>
/// <param name="lowerCase">If false, the namespace and page name will not be lowercased.</param>
/// <param name="str"></param>
/// <param name="lowerCase"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static string CleanAndValidate(string? str, bool lowerCase = true)
@@ -88,7 +89,6 @@ namespace ZelWiki.Library
return string.Empty;
}
//Fix names like "::Page" or "Namespace::".
str = str.Trim().Trim([':']).Trim();
if (str.Contains("::"))
@@ -96,23 +96,22 @@ namespace ZelWiki.Library
var parts = str.Split("::");
if (parts.Length != 2)
{
throw new Exception("Navigation can not contain more than one namespace.");
throw new Exception("导航不能包含多个命名空间");
}
return $"{CleanAndValidate(parts[0].Trim())}::{CleanAndValidate(parts[1].Trim(), lowerCase)}";
}
// Decode common HTML entities
str = str.Replace("&quot;", "\"")
.Replace("&amp;", "&")
.Replace("&lt;", "<")
.Replace("&gt;", ">")
.Replace("&nbsp;", " ");
.Replace("&amp;", "&")
.Replace("&lt;", "<")
.Replace("&gt;", ">")
.Replace("&nbsp;", " ");
// Normalize backslashes to forward slashes
str = str.Replace('\\', '/');
var sb = new StringBuilder();
foreach (char c in str)
foreach (var c in str)
{
if (char.IsWhiteSpace(c) || c == '.')
{
@@ -124,21 +123,13 @@ namespace ZelWiki.Library
}
}
string result = sb.ToString();
var result = sb.ToString();
// Remove multiple consecutive underscores or slashes
result = Regex.Replace(result, @"[_]{2,}", "_");
result = Regex.Replace(result, @"[/]{2,}", "/");
if (lowerCase)
{
return result.TrimEnd(['/', '\\']).ToLowerInvariant();
}
else
{
return result.TrimEnd(['/', '\\']);
}
return lowerCase ? result.TrimEnd(['/', '\\']).ToLowerInvariant() : result.TrimEnd(['/', '\\']);
}
}
}
}

View File

@@ -3,6 +3,9 @@ using System.Text.RegularExpressions;
namespace ZelWiki.Library
{
/// <summary>
/// 导航
/// </summary>
public class Navigation
{
public static string Clean(string? str)
@@ -11,30 +14,26 @@ namespace ZelWiki.Library
{
return string.Empty;
}
//Fix names like "::Page" or "Namespace::".
str = str.Trim().Trim([':']).Trim();
if (str.Contains("::"))
{
throw new Exception("Navigation can not contain a namespace.");
throw new Exception("导航不能包含命名空间");
}
// Decode common HTML entities
str = str.Replace("&quot;", "\"")
.Replace("&amp;", "&")
.Replace("&lt;", "<")
.Replace("&gt;", ">")
.Replace("&nbsp;", " ");
// Normalize backslashes to forward slashes
str = str.Replace('\\', '/');
// Replace special sequences
str = str.Replace("::", "_").Trim();
var sb = new StringBuilder();
foreach (char c in str)
foreach (var c in str)
{
if (char.IsWhiteSpace(c) || c == '.')
{
@@ -46,9 +45,8 @@ namespace ZelWiki.Library
}
}
string result = sb.ToString();
var result = sb.ToString();
// Remove multiple consecutive underscores or slashes
result = Regex.Replace(result, @"[_]{2,}", "_");
result = Regex.Replace(result, @"[/]{2,}", "/");

View File

@@ -42,25 +42,25 @@ namespace ZelWiki.Library
sb.Append($"<center>");
if (currentPage > 1)
{
sb.Append($"<a href=\"{url}?{QueryStringConverter.FromCollection(firstPage)}\">&lt;&lt; First</a>");
sb.Append($"<a href=\"{url}?{QueryStringConverter.FromCollection(firstPage)}\">&lt;&lt; 首页</a>");
sb.Append("&nbsp; | &nbsp;");
sb.Append($"<a href=\"{url}?{QueryStringConverter.FromCollection(prevPage)}\">&lt; Previous</a>");
sb.Append($"<a href=\"{url}?{QueryStringConverter.FromCollection(prevPage)}\">&lt; 上一页</a>");
}
else
{
sb.Append($"&lt;&lt; First &nbsp; | &nbsp; &lt; Previous");
sb.Append($"&lt;&lt; 首页 &nbsp; | &nbsp; &lt; 上一页");
}
sb.Append("&nbsp; | &nbsp;");
if (currentPage < totalPageCount)
{
sb.Append($"<a href=\"{url}?{QueryStringConverter.FromCollection(nextPage)}\">Next &gt;</a>");
sb.Append($"<a href=\"{url}?{QueryStringConverter.FromCollection(nextPage)}\">下一页 &gt;</a>");
sb.Append("&nbsp; | &nbsp;");
sb.Append($"<a href=\"{url}?{QueryStringConverter.FromCollection(lastPage)}\">Last &gt;&gt;</a>");
sb.Append($"<a href=\"{url}?{QueryStringConverter.FromCollection(lastPage)}\">尾页 &gt;&gt;</a>");
}
else
{
sb.Append("Next &gt; &nbsp; | &nbsp; Last &gt;&gt;");
sb.Append("下一页 &gt; &nbsp; | &nbsp; 尾页 &gt;&gt;");
}
sb.Append($"</center>");
}

View File

@@ -8,18 +8,19 @@ namespace ZelWiki.Library
public static class QueryStringConverter
{
/// <summary>
/// Takes the current page query string and upserts the given order-by field,
/// if the string already sorts on the given field then the order is inverted (asc/desc).
/// 排序
/// </summary>
/// <param name="context"></param>
/// <param name="value"></param>
/// <returns></returns>
public static string OrderHelper(ISessionState context, string value)
{
string orderByKey = "OrderBy";
string orderByDirectionKey = "OrderByDirection";
string? currentDirection = "asc";
var orderByKey = "OrderBy";
var orderByDirectionKey = "OrderByDirection";
var currentDirection = "asc";
var collection = ToDictionary(context.QueryString);
//Check to see if we are sorting on the value that we are already sorted on, this would mean we need to invert the sort.
if (collection.TryGetValue(orderByKey, out var currentValue))
{
bool invertDirection = string.Equals(currentValue, value, StringComparison.InvariantCultureIgnoreCase);
@@ -28,14 +29,7 @@ namespace ZelWiki.Library
{
if (collection.TryGetValue(orderByDirectionKey, out currentDirection))
{
if (currentDirection == "asc")
{
currentDirection = "desc";
}
else
{
currentDirection = "asc";
}
currentDirection = currentDirection == "asc" ? "desc" : "asc";
}
}
else
@@ -53,13 +47,13 @@ namespace ZelWiki.Library
return FromCollection(collection);
}
/// <summary>
/// Takes the current page query string and upserts a query key/value, replacing any conflicting query string entry.
/// </summary>
/// <param name="queryString"></param>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
/// <summary>
///
/// </summary>
/// <param name="queryString"></param>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
public static string Upsert(IQueryCollection? queryString, string name, string value)
{
var collection = ToDictionary(queryString);
@@ -79,8 +73,6 @@ namespace ZelWiki.Library
foreach (var item in queryString)
{
//Technically, keys can be duplicated in a IQueryCollection but we do not
//support this. Use .Single() to throw exception if duplicates are found.
dictionary.Add(item.Key, item.Value.Single() ?? string.Empty);
}
@@ -98,13 +90,11 @@ namespace ZelWiki.Library
return dictionary;
}
// If the query string starts with '?', remove it
if (queryString.StartsWith('?'))
{
queryString = queryString.Substring(1);
}
// Split the query string into key-value pairs
var keyValuePairs = queryString.Split('&');
foreach (var kvp in keyValuePairs)
@@ -158,6 +148,7 @@ namespace ZelWiki.Library
{
queryString.Append('&');
}
queryString.Append($"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}");
}
@@ -176,7 +167,8 @@ namespace ZelWiki.Library
{
clone.Add(kvp.Key, kvp.Value);
}
return clone;
}
}
}
}

View File

@@ -2,13 +2,28 @@
{
public class Theme
{
public string Name { get; set; } = string.Empty;
public string DelimitedFiles { get; set; } = string.Empty;
public string ClassNavBar { get; set; } = string.Empty;
public string ClassNavLink { get; set; } = string.Empty;
public string ClassDropdown { get; set; } = string.Empty;
public string ClassBranding { get; set; } = string.Empty;
public string EditorTheme { get; set; } = string.Empty;
public List<string> Files { get; set; } = new();
/// <summary>
///
/// </summary>
public Theme()
{
Name = string.Empty;
DelimitedFiles = string.Empty;
ClassNavBar = string.Empty;
ClassNavLink = string.Empty;
ClassDropdown = string.Empty;
ClassBranding = string.Empty;
EditorTheme = string.Empty;
Files = new();
}
public string Name { get; set; }
public string DelimitedFiles { get; set; }
public string ClassNavBar { get; set; }
public string ClassNavLink { get; set; }
public string ClassDropdown { get; set; }
public string ClassBranding { get; set; }
public string EditorTheme { get; set; }
public List<string> Files { get; set; }
}
}
}

View File

@@ -2,8 +2,17 @@
{
public class TimeZoneItem
{
public string Text { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
/// <summary>
///
/// </summary>
public TimeZoneItem()
{
Text = string.Empty;
Value = string.Empty;
}
public string Text { get; set; }
public string Value { get; set; }
public static List<TimeZoneItem> GetAll()
{
@@ -17,4 +26,4 @@
return list.OrderBy(o => o.Text).ToList();
}
}
}
}

View File

@@ -10,7 +10,6 @@ namespace ZelWiki.Library
public static string SanitizeAccountName(string fileName, char[]? extraInvalidCharacters = null)
{
// Get array of invalid characters for file names
var invalidChars = Path.GetInvalidFileNameChars().ToList();
if (extraInvalidCharacters != null)
@@ -27,7 +26,7 @@ namespace ZelWiki.Library
}
/// <summary>
/// Take a height and width and enforces a max on both dimensions while maintaining the ratio.
///
/// </summary>
/// <param name="originalWidth"></param>
/// <param name="originalHeight"></param>
@@ -35,20 +34,16 @@ namespace ZelWiki.Library
/// <returns></returns>
public static (int Width, int Height) ScaleToMaxOf(int originalWidth, int originalHeight, int maxSize)
{
// Calculate aspect ratio
float aspectRatio = (float)originalWidth / originalHeight;
// Determine new dimensions based on the larger dimension
var aspectRatio = (float)originalWidth / originalHeight;
int newWidth, newHeight;
if (originalWidth > originalHeight)
{
// Scale down the width to the maxSize and calculate the height
newWidth = maxSize;
newHeight = (int)(maxSize / aspectRatio);
}
else
{
// Scale down the height to the maxSize and calculate the width
newHeight = maxSize;
newWidth = (int)(maxSize * aspectRatio);
}
@@ -72,7 +67,7 @@ namespace ZelWiki.Library
public static byte[] ConvertHttpFileToBytes(IFormFile image)
{
using var stream = image.OpenReadStream();
using BinaryReader reader = new BinaryReader(stream);
using var reader = new BinaryReader(stream);
return reader.ReadBytes((int)image.Length);
}
@@ -80,7 +75,7 @@ namespace ZelWiki.Library
{
if (data == null)
{
return Array.Empty<byte>();
return [];
}
using var compressedStream = new MemoryStream();
@@ -88,15 +83,15 @@ namespace ZelWiki.Library
{
compressor.Write(data, 0, data.Length);
}
return compressedStream.ToArray();
}
public static byte[] Decompress(byte[] data)
{
if (data == null)
{
return Array.Empty<byte>();
}
return [];
using var compressedStream = new MemoryStream(data);
using var decompressor = new GZipStream(compressedStream, CompressionMode.Decompress);
@@ -105,4 +100,4 @@ namespace ZelWiki.Library
return decompressedStream.ToArray();
}
}
}
}