Files
TheGame/packages/web/utils/layoutHelpers.ts
δυς 317ba7c9e5 Refactor Setup Wizard & Profile Modal Configuration Panes (#1127)
* incorporating configuration panes from #1078

* standardizing player hero subcomponents & removing `owner` var from `useProfileField` 🚪

* switching box type, ambiguating overly-specific names, & massaging heights 📱

* reordering profile details sections, updating deployment environment, & conditionally wrapping the hero elements 🎬

* fixing render of color disposition selector 🕍

* self code review changes: removed some `;`s 🎋

* getting yarn typecheck && yarn lint to pass post rebase 🏇🏾

* handling "missing <div> in <button>" error with mounted check & setting HTTP return codes for OpenSea API endpoint 🕺

* `ProfileWizard` extends `Wizard`, roles display better on mobile, & pronouns use `ProfileWizardPane` 🍊

* properly encapsulating ETH address regex 🚲

* adding some tasks 🏥

* fixed skills layou

* handling default values? 

* corrections for revision comments from @dan13ram (UI bugs to follow) 🌋

* cleaning up memberships & explorer type 🧫

* refactoring player roles configuration and display to use `WizardPane` 🔮

* bunches of mobile fixes & repairing the display of deserialized skills 📟

* removing redirect in static props & formatting memberships display for responsiveness 🪆

* improving comprehensability of `/me` & more mobile tweaking 🍦

* various spacing fixes & a “try again” button for connecting 🫕

* maybe fixed issue with saving images for fields with default values 🇩🇿

* switched roles selection to a bounded `SimpleGrid` to fix sizing weirdness 🧰

* fix: removed verify on brightId button

* fix: clean up username page

* formatting & fixing skills issues 🥩

* reformatting NFT display 🚂

* adding `/join` 🚉

* style: peth's suggestions

* added mainnet required message

* style: slight tweak of megamenu item positions

* chore(release): 0.2.0

Co-authored-by: tenfinney <scott@1box.onmicrosoft.com>
Co-authored-by: dan13ram <dan13ram@gmail.com>
Co-authored-by: vidvidvid <weetopol@gmail.com>
2022-02-28 14:06:16 -05:00

143 lines
3.3 KiB
TypeScript

import {
getBoxLayoutItemDefaults,
GRID_ROW_HEIGHT,
HEIGHT_MODIFIER,
LayoutItem,
ProfileLayoutData,
} from 'components/Player/Section/config';
import { Layout, Layouts } from 'react-grid-layout';
import {
BoxMetadata,
BoxType,
BoxTypes,
createBoxKey,
getBoxType,
} from 'utils/boxTypes';
export const removeBoxFromLayouts = (
layouts: Layouts,
boxKey: string,
): Layouts =>
Object.fromEntries(
Object.entries(layouts).map(([key, items]) => [
key,
items.filter((item) => item.i !== boxKey),
]),
);
export const addBoxToLayouts = (
layouts: Layouts,
type: BoxType,
metadata: BoxMetadata = {},
opts: Partial<Layout> = {},
): Layouts =>
Object.fromEntries(
Object.entries(layouts).map(([key, items]) => {
const heroItem = items.find(
(item) => item.i === createBoxKey(BoxTypes.PLAYER_HERO),
);
return [
key,
[
...items,
{
...getBoxLayoutItemDefaults(type),
x: 0,
y: heroItem ? heroItem.y + heroItem.h : 0,
i: createBoxKey(type, metadata),
...opts,
},
],
];
}),
);
export const updatedLayouts = (
layouts: Layouts,
heights: Record<string, number>,
): Layouts =>
Object.fromEntries(
Object.entries(layouts).map(([key, items]) => [
key,
items.map((item) => {
const itemHeight =
(heights[item.i] ?? 0) / (GRID_ROW_HEIGHT * HEIGHT_MODIFIER);
const type = getBoxType(item.i);
return type === BoxTypes.PLAYER_ADD_BOX
? item
: {
...item,
h: Math.max(itemHeight, 1),
};
}),
]),
);
export const disableAddBox = ({
layouts,
layoutItems,
}: ProfileLayoutData): ProfileLayoutData => ({
layouts: removeBoxFromLayouts(layouts, createBoxKey(BoxTypes.PLAYER_ADD_BOX)),
layoutItems: layoutItems.filter(
(item) => item.type !== BoxTypes.PLAYER_ADD_BOX,
),
});
export const enableAddBox = ({
layouts,
layoutItems,
}: ProfileLayoutData): ProfileLayoutData => ({
layouts: addBoxToLayouts(
layouts,
BoxTypes.PLAYER_ADD_BOX,
{},
{ x: 1, y: -1 },
),
layoutItems: [
...layoutItems,
{
type: BoxTypes.PLAYER_ADD_BOX,
key: createBoxKey(BoxTypes.PLAYER_ADD_BOX),
},
],
});
const layoutItemSorter = (i: LayoutItem, j: LayoutItem) =>
i.key.localeCompare(j.key);
const layoutSorter = (i: Layout, j: Layout) => {
let diff = i.x - j.x;
if (diff === 0) {
diff = i.y - j.y;
}
return diff;
};
export const isSameLayouts = (
inputA: ProfileLayoutData,
inputB: ProfileLayoutData,
) => {
const a = disableAddBox(inputA);
const b = disableAddBox(inputB);
const itemsA = a.layoutItems.sort(layoutItemSorter);
const itemsB = b.layoutItems.sort(layoutItemSorter);
const isSameItems = itemsA.reduce(
(t, item, i) => t && item.key === itemsB[i].key,
true,
);
if (isSameItems) {
return ['sm', 'md', 'lg']
.map((key) => {
const layoutA = a.layouts[key].sort(layoutSorter);
const layoutB = b.layouts[key].sort(layoutSorter);
return layoutA.reduce(
(t, item, i) =>
t && item.x === layoutB[i].x && item.i === layoutB[i].i,
true,
);
})
.reduce((t, item) => t && item, true);
}
return false;
};