mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-11 21:56:11 -05:00
Fix SendouQ looking page flickers and animation glitches
Caused by rendering my instances of "useMainContentWidth" that return different values
This commit is contained in:
@@ -17,7 +17,6 @@ import { useUser } from "~/features/auth/core/user";
|
||||
import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "~/features/leaderboards/leaderboards-constants";
|
||||
import { ordinalToRoundedSp } from "~/features/mmr/mmr-utils";
|
||||
import type { TieredSkill } from "~/features/mmr/tiered.server";
|
||||
import { useMainContentWidth } from "~/hooks/useMainContentWidth";
|
||||
import { languagesUnified } from "~/modules/i18n/config";
|
||||
import { SPLATTERCOLOR_SCREEN_ID } from "~/modules/in-game-lists/weapon-ids";
|
||||
import { inGameNameWithoutDiscriminator } from "~/utils/strings";
|
||||
@@ -34,11 +33,7 @@ import type {
|
||||
SQGroupMember,
|
||||
SQOwnGroup,
|
||||
} from "../core/SendouQ.server";
|
||||
import {
|
||||
FULL_GROUP_SIZE,
|
||||
IS_Q_LOOKING_MOBILE_BREAKPOINT,
|
||||
SENDOUQ,
|
||||
} from "../q-constants";
|
||||
import { FULL_GROUP_SIZE, SENDOUQ } from "../q-constants";
|
||||
import { resolveFutureMatchModes } from "../q-utils";
|
||||
import styles from "./GroupCard.module.css";
|
||||
|
||||
@@ -58,6 +53,7 @@ export function GroupCard({
|
||||
showAddNote,
|
||||
showNote = false,
|
||||
ownGroup,
|
||||
layout = "desktop",
|
||||
}: {
|
||||
group: SQGroup | SQOwnGroup;
|
||||
action?: "LIKE" | "UNLIKE" | "GROUP_UP" | "MATCH_UP" | "MATCH_UP_RECHALLENGE";
|
||||
@@ -68,6 +64,7 @@ export function GroupCard({
|
||||
showAddNote?: SqlBool;
|
||||
showNote?: boolean;
|
||||
ownGroup?: SQOwnGroup;
|
||||
layout?: "mobile" | "desktop";
|
||||
}) {
|
||||
const { t } = useTranslation(["q"]);
|
||||
const user = useUser();
|
||||
@@ -88,7 +85,11 @@ export function GroupCard({
|
||||
const enableKicking = group.usersRole === "OWNER" && !displayOnly;
|
||||
|
||||
return (
|
||||
<GroupCardContainer groupId={group.id} isOwnGroup={isOwnGroup}>
|
||||
<GroupCardContainer
|
||||
groupId={group.id}
|
||||
isOwnGroup={isOwnGroup}
|
||||
layout={layout}
|
||||
>
|
||||
<section className={styles.group} data-testid="sendouq-group-card">
|
||||
{group.members ? (
|
||||
<div className="stack md">
|
||||
@@ -240,15 +241,14 @@ export function GroupCard({
|
||||
function GroupCardContainer({
|
||||
isOwnGroup,
|
||||
groupId,
|
||||
layout,
|
||||
children,
|
||||
}: {
|
||||
isOwnGroup: boolean;
|
||||
groupId: number;
|
||||
layout: "mobile" | "desktop";
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const width = useMainContentWidth();
|
||||
const layout = width < IS_Q_LOOKING_MOBILE_BREAKPOINT ? "mobile" : "desktop";
|
||||
|
||||
// we don't want it to animate
|
||||
if (isOwnGroup) return <>{children}</>;
|
||||
|
||||
|
||||
@@ -229,15 +229,19 @@ function Groups() {
|
||||
|
||||
const width = useMainContentWidth();
|
||||
|
||||
if (!isHydrated) return null;
|
||||
// width === 0 means the main content hasn't been measured yet; rendering the
|
||||
// Flipper before measurement makes it snapshot the width-0 (mobile) default
|
||||
// layout and then morph every card into the real layout on first navigation
|
||||
if (!isHydrated || width === 0) return null;
|
||||
|
||||
const isMobile = width < IS_Q_LOOKING_MOBILE_BREAKPOINT;
|
||||
const layout = isMobile ? "mobile" : "desktop";
|
||||
const isFullGroup =
|
||||
data.ownGroup && data.ownGroup.members.length === FULL_GROUP_SIZE;
|
||||
|
||||
const invitedGroupsDesktop = (
|
||||
<div className="stack sm">
|
||||
<ColumnHeader>
|
||||
<ColumnHeader isMobile={isMobile}>
|
||||
{t(
|
||||
isFullGroup
|
||||
? "q:looking.columns.challenged"
|
||||
@@ -256,6 +260,7 @@ function Groups() {
|
||||
action="UNLIKE"
|
||||
showNote
|
||||
ownGroup={data.ownGroup}
|
||||
layout={layout}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -264,7 +269,9 @@ function Groups() {
|
||||
|
||||
const ownGroupElement = data.ownGroup ? (
|
||||
<div className="stack sm">
|
||||
<ColumnHeader>{t("q:looking.columns.myGroup")}</ColumnHeader>
|
||||
<ColumnHeader isMobile={isMobile}>
|
||||
{t("q:looking.columns.myGroup")}
|
||||
</ColumnHeader>
|
||||
<GroupCard group={data.ownGroup} showNote ownGroup={data.ownGroup} />
|
||||
{data.ownGroup.inviteCode ? (
|
||||
<MemberAdder
|
||||
@@ -330,7 +337,9 @@ function Groups() {
|
||||
</SendouTabList>
|
||||
<SendouTabPanel id="groups">
|
||||
<div className="stack sm">
|
||||
<ColumnHeader>{t("q:looking.columns.available")}</ColumnHeader>
|
||||
<ColumnHeader isMobile={isMobile}>
|
||||
{t("q:looking.columns.available")}
|
||||
</ColumnHeader>
|
||||
{(isMobile
|
||||
? data.groups.filter(
|
||||
(group) =>
|
||||
@@ -353,6 +362,7 @@ function Groups() {
|
||||
}
|
||||
showNote
|
||||
ownGroup={data.ownGroup}
|
||||
layout={layout}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -380,6 +390,7 @@ function Groups() {
|
||||
action={action()}
|
||||
showNote
|
||||
ownGroup={data.ownGroup}
|
||||
layout={layout}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -390,7 +401,7 @@ function Groups() {
|
||||
</div>
|
||||
{!isMobile ? (
|
||||
<div className="stack sm">
|
||||
<ColumnHeader>
|
||||
<ColumnHeader isMobile={isMobile}>
|
||||
{t(
|
||||
isFullGroup
|
||||
? "q:looking.columns.challenges"
|
||||
@@ -417,6 +428,7 @@ function Groups() {
|
||||
action={action()}
|
||||
showNote
|
||||
ownGroup={data.ownGroup}
|
||||
layout={layout}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -427,11 +439,13 @@ function Groups() {
|
||||
);
|
||||
}
|
||||
|
||||
function ColumnHeader({ children }: { children: React.ReactNode }) {
|
||||
const width = useMainContentWidth();
|
||||
|
||||
const isMobile = width < IS_Q_LOOKING_MOBILE_BREAKPOINT;
|
||||
|
||||
function ColumnHeader({
|
||||
isMobile,
|
||||
children,
|
||||
}: {
|
||||
isMobile: boolean;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
if (isMobile) return null;
|
||||
|
||||
return <div className={styles.header}>{children}</div>;
|
||||
|
||||
Reference in New Issue
Block a user