diff --git a/Foxnouns.Backend/Database/DatabaseQueryExtensions.cs b/Foxnouns.Backend/Database/DatabaseQueryExtensions.cs index d5df79d..60d4499 100644 --- a/Foxnouns.Backend/Database/DatabaseQueryExtensions.cs +++ b/Foxnouns.Backend/Database/DatabaseQueryExtensions.cs @@ -71,7 +71,6 @@ public static class DatabaseQueryExtensions { member = await context.Members .Include(m => m.User) - .Include(m => m.ProfileFlags) .Where(m => !m.User.Deleted) .FirstOrDefaultAsync(m => m.Id == snowflake && m.UserId == userId, ct); if (member != null) return member; @@ -79,7 +78,6 @@ public static class DatabaseQueryExtensions member = await context.Members .Include(m => m.User) - .Include(m => m.ProfileFlags) .Where(m => !m.User.Deleted) .FirstOrDefaultAsync(m => m.Name == memberRef && m.UserId == userId, ct); if (member != null) return member; diff --git a/Foxnouns.Backend/Middleware/ErrorHandlerMiddleware.cs b/Foxnouns.Backend/Middleware/ErrorHandlerMiddleware.cs index c28b58e..6b6da6d 100644 --- a/Foxnouns.Backend/Middleware/ErrorHandlerMiddleware.cs +++ b/Foxnouns.Backend/Middleware/ErrorHandlerMiddleware.cs @@ -1,6 +1,5 @@ using System.Net; using Foxnouns.Backend.Utils; -using Microsoft.AspNetCore.Mvc.ModelBinding; using Newtonsoft.Json; namespace Foxnouns.Backend.Middleware; diff --git a/Foxnouns.Backend/Services/MemberRendererService.cs b/Foxnouns.Backend/Services/MemberRendererService.cs index 9ebea49..0fdaa53 100644 --- a/Foxnouns.Backend/Services/MemberRendererService.cs +++ b/Foxnouns.Backend/Services/MemberRendererService.cs @@ -24,14 +24,13 @@ public class MemberRendererService(DatabaseContext db, Config config) return members.Select(m => RenderPartialMember(m, renderUnlisted)); } - public MemberResponse RenderMember(Member member, Token? token = null) + public MemberResponse RenderMember(Member member, Token? token) { var renderUnlisted = token?.UserId == member.UserId && token.HasScope("user.read_hidden"); return new MemberResponse( member.Id, member.Sid, member.Name, member.DisplayName, member.Bio, AvatarUrlFor(member), member.Links, member.Names, member.Pronouns, member.Fields, - member.ProfileFlags.Select(f => RenderPrideFlag(f.PrideFlag)), RenderPartialUser(member.User), renderUnlisted ? member.Unlisted : null); } @@ -51,9 +50,6 @@ public class MemberRendererService(DatabaseContext db, Config config) private string ImageUrlFor(PrideFlag flag) => $"{config.MediaBaseUrl}/flags/{flag.Hash}.webp"; - private UserRendererService.PrideFlagResponse RenderPrideFlag(PrideFlag flag) => - new(flag.Id, ImageUrlFor(flag), flag.Name, flag.Description); - public record PartialMember( Snowflake Id, string Sid, @@ -77,7 +73,6 @@ public class MemberRendererService(DatabaseContext db, Config config) IEnumerable Names, IEnumerable Pronouns, IEnumerable Fields, - IEnumerable Flags, UserRendererService.PartialUser User, [property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] bool? Unlisted); diff --git a/Foxnouns.Frontend/app/app.scss b/Foxnouns.Frontend/app/app.scss index 0d30b1e..45a8ee5 100644 --- a/Foxnouns.Frontend/app/app.scss +++ b/Foxnouns.Frontend/app/app.scss @@ -21,9 +21,3 @@ @import "@fontsource/firago/400.css"; @import "@fontsource/firago/400-italic.css"; @import "@fontsource/firago/700.css"; - -.pride-flag { - height: 1.5rem; - max-width: 200px; - border-radius: 3px; -} diff --git a/Foxnouns.Frontend/app/components/profile/ProfileField.tsx b/Foxnouns.Frontend/app/components/ProfileField.tsx similarity index 89% rename from Foxnouns.Frontend/app/components/profile/ProfileField.tsx rename to Foxnouns.Frontend/app/components/ProfileField.tsx index 92d8a46..ed5577d 100644 --- a/Foxnouns.Frontend/app/components/profile/ProfileField.tsx +++ b/Foxnouns.Frontend/app/components/ProfileField.tsx @@ -1,5 +1,5 @@ import { CustomPreference, FieldEntry, Pronoun } from "~/lib/api/user"; -import StatusLine from "~/components/profile/StatusLine"; +import StatusLine from "~/components/StatusLine"; export default function ProfileField({ name, diff --git a/Foxnouns.Frontend/app/components/profile/ProfileLink.tsx b/Foxnouns.Frontend/app/components/ProfileLink.tsx similarity index 100% rename from Foxnouns.Frontend/app/components/profile/ProfileLink.tsx rename to Foxnouns.Frontend/app/components/ProfileLink.tsx diff --git a/Foxnouns.Frontend/app/components/profile/PronounLink.tsx b/Foxnouns.Frontend/app/components/PronounLink.tsx similarity index 100% rename from Foxnouns.Frontend/app/components/profile/PronounLink.tsx rename to Foxnouns.Frontend/app/components/PronounLink.tsx diff --git a/Foxnouns.Frontend/app/components/profile/StatusIcon.tsx b/Foxnouns.Frontend/app/components/StatusIcon.tsx similarity index 100% rename from Foxnouns.Frontend/app/components/profile/StatusIcon.tsx rename to Foxnouns.Frontend/app/components/StatusIcon.tsx diff --git a/Foxnouns.Frontend/app/components/profile/StatusLine.tsx b/Foxnouns.Frontend/app/components/StatusLine.tsx similarity index 89% rename from Foxnouns.Frontend/app/components/profile/StatusLine.tsx rename to Foxnouns.Frontend/app/components/StatusLine.tsx index 3729e8a..704df75 100644 --- a/Foxnouns.Frontend/app/components/profile/StatusLine.tsx +++ b/Foxnouns.Frontend/app/components/StatusLine.tsx @@ -7,8 +7,8 @@ import { Pronoun, } from "~/lib/api/user"; import classNames from "classnames"; -import StatusIcon from "~/components/profile/StatusIcon"; -import PronounLink from "~/components/profile/PronounLink"; +import StatusIcon from "~/components/StatusIcon"; +import PronounLink from "~/components/PronounLink"; export default function StatusLine({ entry, diff --git a/Foxnouns.Frontend/app/components/profile/BaseProfile.tsx b/Foxnouns.Frontend/app/components/profile/BaseProfile.tsx deleted file mode 100644 index 4017877..0000000 --- a/Foxnouns.Frontend/app/components/profile/BaseProfile.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { CustomPreference, User } from "~/lib/api/user"; -import { Member } from "~/lib/api/member"; -import { defaultAvatarUrl } from "~/lib/utils"; -import ProfileFlag from "~/components/profile/ProfileFlag"; -import ProfileLink from "~/components/profile/ProfileLink"; -import ProfileField from "~/components/profile/ProfileField"; -import { useTranslation } from "react-i18next"; -import { renderMarkdown } from "~/lib/markdown"; - -export type Props = { - name: string; - fullName?: string; - avatarI18nKey: string; - profile: User | Member; - customPreferences: Record; -}; - -export default function BaseProfile({ - name, - avatarI18nKey, - fullName, - profile, - customPreferences, -}: Props) { - const { t } = useTranslation(); - const bio = renderMarkdown(profile.bio); - - return ( - <> -
-
-
- {t(avatarI18nKey, - {profile.flags && profile.bio && ( -
- {profile.flags.map((f, i) => ( - - ))} -
- )} -
-
- {profile.display_name ? ( - <> -

{profile.display_name}

-

{fullName || `@${name}`}

- - ) : ( - <> -

{fullName || `@${name}`}

- - )} - {bio && ( - <> -
-

- - )} -
- {profile.links.length > 0 && ( -
-
    - {profile.links.map((l, i) => ( - - ))} -
-
- )} -
-
- {profile.names.length > 0 && ( - - )} - {profile.pronouns.length > 0 && ( - - )} - {profile.fields.map((f, i) => ( - - ))} -
-
- {/* If a user or member has no bio, flags are displayed in a row below the other profile info, rather than just below the avatar */} - {profile.flags && !profile.bio && ( -
- {profile.flags.map((f, i) => ( - - ))} -
- )} - - ); -} diff --git a/Foxnouns.Frontend/app/components/profile/ProfileFlag.tsx b/Foxnouns.Frontend/app/components/profile/ProfileFlag.tsx deleted file mode 100644 index 756783d..0000000 --- a/Foxnouns.Frontend/app/components/profile/ProfileFlag.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import type { PrideFlag } from "~/lib/api/user"; -import { OverlayTrigger, Tooltip } from "react-bootstrap"; - -export default function ProfileFlag({ flag }: { flag: PrideFlag }) { - return ( - - - {flag.description ?? flag.name} - - } - > - - {flag.description - - {" "} - {flag.name} - - ); -} diff --git a/Foxnouns.Frontend/app/lib/api/member.ts b/Foxnouns.Frontend/app/lib/api/member.ts deleted file mode 100644 index 7827f0a..0000000 --- a/Foxnouns.Frontend/app/lib/api/member.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Field, PartialMember, PrideFlag } from "~/lib/api/user"; - -export type Member = PartialMember & { - fields: Field[]; - flags: PrideFlag[]; - links: string[]; -}; diff --git a/Foxnouns.Frontend/app/lib/api/user.ts b/Foxnouns.Frontend/app/lib/api/user.ts index 0b6f375..5dc969c 100644 --- a/Foxnouns.Frontend/app/lib/api/user.ts +++ b/Foxnouns.Frontend/app/lib/api/user.ts @@ -13,7 +13,6 @@ export type User = PartialUser & { names: FieldEntry[]; pronouns: Pronoun[]; fields: Field[]; - flags: PrideFlag[]; }; export type UserWithMembers = User & { members: PartialMember[] }; @@ -51,13 +50,6 @@ export type Field = { entries: FieldEntry[]; }; -export type PrideFlag = { - id: string; - image_url: string; - name: string; - description: string | null; -}; - export type CustomPreference = { icon: string; tooltip: string; diff --git a/Foxnouns.Frontend/app/routes/$username/route.tsx b/Foxnouns.Frontend/app/routes/$username/route.tsx index 48aee01..c19b5e7 100644 --- a/Foxnouns.Frontend/app/routes/$username/route.tsx +++ b/Foxnouns.Frontend/app/routes/$username/route.tsx @@ -6,10 +6,12 @@ import { loader as rootLoader } from "~/root"; import { Alert, Button, Pagination } from "react-bootstrap"; import { Trans, useTranslation } from "react-i18next"; import { renderMarkdown } from "~/lib/markdown"; +import ProfileLink from "~/components/ProfileLink"; +import ProfileField from "~/components/ProfileField"; import { PersonPlusFill } from "react-bootstrap-icons"; +import { defaultAvatarUrl } from "~/lib/utils"; import MemberCard from "~/routes/$username/MemberCard"; import { ReactNode } from "react"; -import BaseProfile from "~/components/profile/BaseProfile"; export const meta: MetaFunction = ({ data }) => { const { user } = data!; @@ -42,6 +44,7 @@ export default function UserPage() { const { meUser } = useRouteLoaderData("root") || { meUser: undefined }; const isMeUser = meUser && meUser.id === user.id; + const bio = renderMarkdown(user.bio); const paginationItems: ReactNode[] = []; for (let i = 0; i < pageCount; i++) { @@ -79,12 +82,70 @@ export default function UserPage() { )} - +
+
+
+ {t("user.avatar-alt", +
+
+ {user.display_name ? ( + <> +

{user.display_name}

+

@{user.username}

+ + ) : ( + <> +

@{user.username}

+ + )} + {bio && ( + <> +
+

+ + )} +
+ {user.links.length > 0 && ( +
+
    + {user.links.map((l, i) => ( + + ))} +
+
+ )} +
+
+ {user.names.length > 0 && ( + + )} + {user.pronouns.length > 0 && ( + + )} + {user.fields.map((f, i) => ( + + ))} +
+
{(members.length > 0 || isMeUser) && ( <>