mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-07-12 16:21:28 +00:00
Simplify rank badges and implement profile tags (#880)
* Simplify website rank badges to use semantic classes * Fix ambiguity between partial display types * Add profile vanity tags and needed migration * Make form field read only to non-administrators * Display lock icon if user is not admin to minimize confusion * Also display lock icon for username field since it's readonly * Fix up naming consistency issues and edit migration accordingly * Apply suggestions from code review * Add space between placeholder property and ternary operator
This commit is contained in:
parent
a316c866c5
commit
be5a29d3c9
10 changed files with 83 additions and 19 deletions
|
@ -27,4 +27,7 @@
|
||||||
<data name="title" xml:space="preserve">
|
<data name="title" xml:space="preserve">
|
||||||
<value>{0}'s user page</value>
|
<value>{0}'s user page</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="profile_tag" xml:space="preserve">
|
||||||
|
<value>Profile Tag</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -5,6 +5,7 @@ public static class ProfileStrings
|
||||||
public static readonly TranslatableString Title = create("title");
|
public static readonly TranslatableString Title = create("title");
|
||||||
public static readonly TranslatableString Biography = create("biography");
|
public static readonly TranslatableString Biography = create("biography");
|
||||||
public static readonly TranslatableString NoBiography = create("no_biography");
|
public static readonly TranslatableString NoBiography = create("no_biography");
|
||||||
|
public static readonly TranslatableString ProfileTag = create("profile_tag");
|
||||||
|
|
||||||
private static TranslatableString create(string key) => new(TranslationAreas.Profile, key);
|
private static TranslatableString create(string key) => new(TranslationAreas.Profile, key);
|
||||||
}
|
}
|
|
@ -28,7 +28,7 @@ public static class FormattingExtensions
|
||||||
return permissionLevel switch
|
return permissionLevel switch
|
||||||
{
|
{
|
||||||
PermissionLevel.Administrator => "red",
|
PermissionLevel.Administrator => "red",
|
||||||
PermissionLevel.Moderator => "rgb(200, 130, 0)",
|
PermissionLevel.Moderator => "orange",
|
||||||
_ => "",
|
_ => "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,16 @@
|
||||||
<a href="~/user/@Model.UserId">@Model.Username</a>
|
<a href="~/user/@Model.UserId">@Model.Username</a>
|
||||||
@if (Model.IsModerator)
|
@if (Model.IsModerator)
|
||||||
{
|
{
|
||||||
<span class="permissionBadge" style="background-color: @Model.PermissionLevel.ToHtmlColor();">
|
<span class="profile-tag ui label @Model.PermissionLevel.ToHtmlColor()">
|
||||||
@Model.PermissionLevel.ToString()
|
@Model.PermissionLevel.ToString()
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
@if (!string.IsNullOrWhiteSpace(Model.ProfileTag))
|
||||||
|
{
|
||||||
|
<span class="profile-tag ui label">
|
||||||
|
@Model.ProfileTag
|
||||||
|
</span>
|
||||||
|
}
|
||||||
</h2>
|
</h2>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -37,10 +43,16 @@
|
||||||
@Model.Username
|
@Model.Username
|
||||||
@if (Model.IsModerator)
|
@if (Model.IsModerator)
|
||||||
{
|
{
|
||||||
<span class="permissionBadge" style="background-color: @Model.PermissionLevel.ToHtmlColor();">
|
<span class="profile-tag ui label @Model.PermissionLevel.ToHtmlColor()">
|
||||||
@Model.PermissionLevel.ToString()
|
@Model.PermissionLevel.ToString()
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
@if (!string.IsNullOrWhiteSpace(Model.ProfileTag))
|
||||||
|
{
|
||||||
|
<span class="profile-tag ui label">
|
||||||
|
@Model.ProfileTag
|
||||||
|
</span>
|
||||||
|
}
|
||||||
</h1>
|
</h1>
|
||||||
}
|
}
|
||||||
@{
|
@{
|
||||||
|
|
|
@ -61,7 +61,7 @@ function onSubmit(e){
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label style="text-align: left" for="username">@Model.Translate(GeneralStrings.Username)</label>
|
<label style="text-align: left" for="username">@Model.Translate(GeneralStrings.Username) <i class="ui icon lock"></i></label>
|
||||||
<input type="text" name="username" id="username" value="@Model.ProfileUser.Username" placeholder="Username" readonly>
|
<input type="text" name="username" id="username" value="@Model.ProfileUser.Username" placeholder="Username" readonly>
|
||||||
</div>
|
</div>
|
||||||
@if (ServerConfiguration.Instance.Mail.MailEnabled && (Model.User == Model.ProfileUser || Model.User!.IsAdmin))
|
@if (ServerConfiguration.Instance.Mail.MailEnabled && (Model.User == Model.ProfileUser || Model.User!.IsAdmin))
|
||||||
|
@ -71,6 +71,16 @@ function onSubmit(e){
|
||||||
<input type="text" name="email" id="email" required value="@Model.ProfileUser.EmailAddress" placeholder="Email Address">
|
<input type="text" name="email" id="email" required value="@Model.ProfileUser.EmailAddress" placeholder="Email Address">
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
<div class="field">
|
||||||
|
<label style="text-align: left" for="profileTag">
|
||||||
|
@Model.Translate(ProfileStrings.ProfileTag)
|
||||||
|
@if (!Model.User!.IsAdmin)
|
||||||
|
{
|
||||||
|
<i class="ui icon lock"></i>
|
||||||
|
}
|
||||||
|
</label>
|
||||||
|
<input type="text" name="profileTag" id="profileTag" value="@Model.ProfileUser.ProfileTag" placeholder="Profile Tag" @(!Model.User!.IsAdmin ? "readonly" : "")>
|
||||||
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label style="text-align: left" for="biography">@Model.Translate(ProfileStrings.Biography)</label>
|
<label style="text-align: left" for="biography">@Model.Translate(ProfileStrings.Biography)</label>
|
||||||
<textarea name="biography" id="biography" spellcheck="false" placeholder="Biography">@HttpUtility.HtmlDecode(Model.ProfileUser.Biography)</textarea>
|
<textarea name="biography" id="biography" spellcheck="false" placeholder="Biography">@HttpUtility.HtmlDecode(Model.ProfileUser.Biography)</textarea>
|
||||||
|
|
|
@ -20,7 +20,17 @@ public class UserSettingsPage : BaseLayout
|
||||||
{}
|
{}
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "SpecifyStringComparison")]
|
[SuppressMessage("ReSharper", "SpecifyStringComparison")]
|
||||||
public async Task<IActionResult> OnPost([FromRoute] int userId, [FromForm] string? avatar, [FromForm] string? username, [FromForm] string? email, [FromForm] string? biography, [FromForm] string? timeZone, [FromForm] string? language)
|
public async Task<IActionResult> OnPost
|
||||||
|
(
|
||||||
|
[FromRoute] int userId,
|
||||||
|
[FromForm] string? avatar,
|
||||||
|
[FromForm] string? username,
|
||||||
|
[FromForm] string? email,
|
||||||
|
[FromForm] string profileTag,
|
||||||
|
[FromForm] string? biography,
|
||||||
|
[FromForm] string? timeZone,
|
||||||
|
[FromForm] string? language
|
||||||
|
)
|
||||||
{
|
{
|
||||||
this.ProfileUser = await this.Database.Users.FirstOrDefaultAsync(u => u.UserId == userId);
|
this.ProfileUser = await this.Database.Users.FirstOrDefaultAsync(u => u.UserId == userId);
|
||||||
if (this.ProfileUser == null) return this.NotFound();
|
if (this.ProfileUser == null) return this.NotFound();
|
||||||
|
@ -33,6 +43,8 @@ public class UserSettingsPage : BaseLayout
|
||||||
|
|
||||||
if (avatarHash != null) this.ProfileUser.IconHash = avatarHash;
|
if (avatarHash != null) this.ProfileUser.IconHash = avatarHash;
|
||||||
|
|
||||||
|
if (this.User.IsAdmin) this.ProfileUser.ProfileTag = profileTag;
|
||||||
|
|
||||||
if (biography != null)
|
if (biography != null)
|
||||||
{
|
{
|
||||||
biography = CensorHelper.FilterMessage(biography);
|
biography = CensorHelper.FilterMessage(biography);
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
using LBPUnion.ProjectLighthouse.Database;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace ProjectLighthouse.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DatabaseContext))]
|
||||||
|
[Migration("20230827004014_AddProfileVanityTagsToUsers")]
|
||||||
|
public partial class AddProfileVanityTagsToUsers : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "ProfileTag",
|
||||||
|
table: "Users",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ProfileTag",
|
||||||
|
table: "Users");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ namespace ProjectLighthouse.Migrations
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "7.0.8")
|
.HasAnnotation("ProductVersion", "7.0.10")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Entities.Interaction.HeartedLevelEntity", b =>
|
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Entities.Interaction.HeartedLevelEntity", b =>
|
||||||
|
@ -858,6 +858,9 @@ namespace ProjectLighthouse.Migrations
|
||||||
b.Property<string>("PlanetHashLBPVita")
|
b.Property<string>("PlanetHashLBPVita")
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("ProfileTag")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<int>("ProfileVisibility")
|
b.Property<int>("ProfileVisibility")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
|
|
@ -244,19 +244,9 @@ div.cardStatsUnderTitle > span {
|
||||||
|
|
||||||
/*#region User permission badge */
|
/*#region User permission badge */
|
||||||
|
|
||||||
.permissionBadge {
|
.profile-tag {
|
||||||
width: auto;
|
position: relative;
|
||||||
height: auto;
|
bottom: 0.45rem;
|
||||||
color: white;
|
|
||||||
background-color: inherit;
|
|
||||||
border: 0px solid black;
|
|
||||||
border-radius: 50px;
|
|
||||||
font-weight: 200;
|
|
||||||
font-size: 10pt;
|
|
||||||
padding: 1px;
|
|
||||||
padding-left: 6px;
|
|
||||||
padding-right: 6px;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#endregion User permission badge */
|
/*#endregion User permission badge */
|
|
@ -72,6 +72,7 @@ public class UserEntity
|
||||||
|
|
||||||
public string PlanetHashLBP2 { get; set; } = "";
|
public string PlanetHashLBP2 { get; set; } = "";
|
||||||
|
|
||||||
|
// ReSharper disable once InconsistentNaming
|
||||||
public string PlanetHashLBP2CC { get; set; } = "";
|
public string PlanetHashLBP2CC { get; set; } = "";
|
||||||
|
|
||||||
public string PlanetHashLBP3 { get; set; } = "";
|
public string PlanetHashLBP3 { get; set; } = "";
|
||||||
|
@ -131,6 +132,8 @@ public class UserEntity
|
||||||
// should not be adjustable by user
|
// should not be adjustable by user
|
||||||
public bool CommentsEnabled { get; set; } = true;
|
public bool CommentsEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
public string ProfileTag { get; set; } = "";
|
||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue