diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/TwoFactorLoginSettings.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/TwoFactorLoginSettings.Edit.cshtml index 5a949e1687d..43620811571 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/TwoFactorLoginSettings.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/TwoFactorLoginSettings.Edit.cshtml @@ -4,7 +4,9 @@ @inject IOptions CookieAuthenticationOptions @model OrchardCore.Users.Models.TwoFactorLoginSettings - +@{ + var duration = await DisplayAsync(await New.Duration(timeSpan: CookieAuthenticationOptions.Value.ExpireTimeSpan)); +}
@T["Two-Factor Settings"] @@ -13,9 +15,8 @@ - - @T["When selected, users may use Remember Client during login to avoid having to provide a token every time."] - @T["The client will be remembered for:"] @await DisplayAsync(await New.Duration(timeSpan: CookieAuthenticationOptions.Value.ExpireTimeSpan)) + + @T["When selected, users may use Remember Client during login to avoid having to provide a token every time. The client will be remembered for: {0}", duration] diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/DateTimeShapes.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/DateTimeShapes.cs index da840e3f0a4..ea689571ac9 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/DateTimeShapes.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/DateTimeShapes.cs @@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.Extensions.Localization; using OrchardCore.DisplayManagement.Descriptors; -using OrchardCore.DisplayManagement.Html; using OrchardCore.Modules; namespace OrchardCore.DisplayManagement.Shapes; @@ -110,8 +109,18 @@ public IHtmlContent TimeSpan(DateTime? Utc, DateTime? Origin) } return time.TotalMilliseconds > 0 - ? H["a moment ago"] - : H["in a moment"]; + ? H["a moment ago"] + : H["in a moment"]; + } + + [Shape] + public async Task DateTime(IHtmlHelper Html, DateTime? Utc, string Format) + { + Utc ??= _clock.UtcNow; + var zonedTime = await _localClock.ConvertToLocalAsync(Utc.Value); + Format ??= S[LongDateTimeFormat].Value; + + return Html.Raw(Html.Encode(zonedTime.ToString(Format, CultureInfo.CurrentUICulture))); } [Shape] @@ -122,58 +131,65 @@ public IHtmlContent Duration(TimeSpan? timeSpan) return HtmlString.Empty; } - var days = (int)timeSpan.Value.TotalDays; - var hours = timeSpan.Value.Hours; - var minutes = timeSpan.Value.Minutes; - var seconds = timeSpan.Value.Seconds; - - var builder = new HtmlContentBuilder(); - - if (days > 0) + if (timeSpan.Value.Days > 0) { - builder.AppendHtml(H.Plural(days, "{1} day", "{1} days", days)); + return GetDurationInDays(timeSpan.Value); } - if (hours > 0) + if (timeSpan.Value.Hours > 0) { - if (builder.Count > 0) - { - builder.AppendWhitespace(); - } - builder.AppendHtml(H.Plural(hours, "{1} hour", "{1} hours", hours)); + return GetDurationInHours(timeSpan.Value); } - if (minutes > 0) + if (timeSpan.Value.Minutes > 0) { - if (builder.Count > 0) - { - builder.AppendWhitespace(); - } - - builder.AppendHtml(H.Plural(hours, "{1} minute", "{1} minutes", minutes)); + return GetDurationInMinutes(timeSpan.Value); } + var seconds = timeSpan.Value.Seconds; + if (seconds > 0) { - if (builder.Count > 0) - { - builder.AppendWhitespace(); - } + return H.Plural(seconds, "1 second", "{0} seconds"); + } + + return H["less than a second"]; + } + + private LocalizedHtmlString GetDurationInDays(TimeSpan timeSpan) + { + var totalDays = timeSpan.TotalDays; + + if (timeSpan.Days == totalDays) + { + return H.Plural(timeSpan.Days, "1 day", "{0} days"); + } - builder.AppendHtml(H.Plural(seconds, "{1} second", "{1} seconds", seconds)); + return H.Plural((int)Math.Round(totalDays), "approximately a day", "approximately {0} days"); + } + + private LocalizedHtmlString GetDurationInHours(TimeSpan timeSpan) + { + var totalHours = timeSpan.TotalHours; + + if (timeSpan.Hours == totalHours) + { + return H.Plural(timeSpan.Hours, "1 hour", "{0} hours"); } - return builder; + return H.Plural((int)Math.Round(totalHours), "approximately an hour", "approximately {0} hours"); } - [Shape] - public async Task DateTime(IHtmlHelper Html, DateTime? Utc, string Format) + private LocalizedHtmlString GetDurationInMinutes(TimeSpan timeSpan) { - Utc ??= _clock.UtcNow; - var zonedTime = await _localClock.ConvertToLocalAsync(Utc.Value); - Format ??= S[LongDateTimeFormat].Value; + var totalMinutes = timeSpan.TotalMinutes; - return Html.Raw(Html.Encode(zonedTime.ToString(Format, CultureInfo.CurrentUICulture))); + if (timeSpan.Minutes == totalMinutes) + { + return H.Plural(timeSpan.Minutes, "1 minute", "{0} minutes"); + } + + return H.Plural((int)Math.Round(totalMinutes), "approximately a minute", "approximately {0} minutes"); } }