Skip to content

Commit 8d93f66

Browse files
committed
feat: grid stuff
1 parent 4426310 commit 8d93f66

File tree

3 files changed

+80
-217
lines changed

3 files changed

+80
-217
lines changed

electron/renderer/components/grid/grid-item.tsx

+67-23
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,66 @@ import { useCallback, useMemo, useRef } from 'react';
2424

2525
export interface GridItemMetadata {
2626
itemId: string;
27-
title: string;
27+
itemTitle: string;
2828
isFocused: boolean;
2929
x: number;
3030
y: number;
3131
width: number;
3232
height: number;
3333
}
3434

35+
/**
36+
* The dimension for the grid where the item may be dragged and resized.
37+
*/
38+
export interface GridItemBoundary {
39+
/**
40+
* The max height of the grid in pixels.
41+
*/
42+
height: number;
43+
/**
44+
* The max width of the grid in pixels.
45+
*/
46+
width: number;
47+
}
48+
49+
/**
50+
* The positional layout for the grid item.
51+
*/
52+
export interface GridItemLayout {
53+
/**
54+
* The x coordinate for the grid item.
55+
* The leftmost edge of the grid item.
56+
*/
57+
x: number;
58+
/**
59+
* The y coordinate for the grid item.
60+
* The topmost edge of the grid item.
61+
*/
62+
y: number;
63+
/**
64+
* The width dimension for the grid item.
65+
* The horizontal length of the grid item.
66+
* Rightmost edge is `x + width`.
67+
*/
68+
width: number;
69+
/**
70+
* The height dimension for the grid item.
71+
* The vertical length of the grid item.
72+
* Bottommost edge is `y + height`.
73+
*/
74+
height: number;
75+
}
76+
3577
export interface GridItemProps {
3678
/**
3779
* The dimension for the grid where the item may be dragged and resized.
3880
*/
39-
boundary: {
40-
/**
41-
* The max height of the grid in pixels.
42-
*/
43-
height: number;
44-
/**
45-
* The max width of the grid in pixels.
46-
*/
47-
width: number;
48-
};
81+
boundary: GridItemBoundary;
82+
/**
83+
* The positional layout for the grid item.
84+
* If not specified then a default location will be used.
85+
*/
86+
layout?: GridItemLayout;
4987
/**
5088
* The unique identifier for the grid item.
5189
*/
@@ -55,7 +93,7 @@ export interface GridItemProps {
5593
* Note the prop `title` is reserved and refers to titling a DOM element,
5694
* not for passing data to child components. So using a more specific name.
5795
*/
58-
titleBarText: string;
96+
itemTitle: string;
5997
/**
6098
* Handler when the user clicks the close button in the title bar.
6199
* Passes the `itemId` of the grid item being closed.
@@ -84,36 +122,42 @@ export interface GridItemProps {
84122
children?: ReactNode;
85123
}
86124

125+
const DEFAULT_GRID_ITEM_LAYOUT: GridItemLayout = {
126+
x: 0,
127+
y: 0,
128+
width: 500,
129+
height: 500,
130+
};
131+
87132
export const GridItem: React.FC<GridItemProps> = (
88133
props: GridItemProps
89134
): ReactNode => {
90-
const { boundary, itemId, titleBarText, isFocused = false, children } = props;
135+
const { itemId, itemTitle, isFocused = false, children } = props;
136+
const { boundary, layout = DEFAULT_GRID_ITEM_LAYOUT } = props;
91137
const { onFocus, onClose, onMoveResize } = props;
92138

93139
const { euiTheme } = useEuiTheme();
94140

95141
// Set default position and size for the grid item.
96-
const [{ x, y, width, height }, sizeApi] = useSpring(() => ({
97-
x: 0,
98-
y: 0,
99-
width: 100,
100-
height: 100,
101-
}));
142+
// Like `useState`, we can provide the default value, but as a function.
143+
const [{ x, y, width, height }, sizeApi] = useSpring<GridItemLayout>(() => {
144+
return layout;
145+
}, [layout]);
102146

103147
const dragHandleRef = useRef<HTMLDivElement>(null);
104148
const resizeHandleRef = useRef<HTMLDivElement>(null);
105149

106-
const getItemMetadata = useCallback(() => {
150+
const getItemMetadata = useCallback((): GridItemMetadata => {
107151
return {
108152
itemId,
109-
title: titleBarText,
153+
itemTitle,
110154
isFocused,
111155
x: x.get(),
112156
y: y.get(),
113157
width: width.get(),
114158
height: height.get(),
115159
};
116-
}, [itemId, titleBarText, isFocused, x, y, width, height]);
160+
}, [itemId, itemTitle, isFocused, x, y, width, height]);
117161

118162
// Handle when the user clicks the close button in the title bar.
119163
const onCloseClick = useCallback(() => {
@@ -318,7 +362,7 @@ export const GridItem: React.FC<GridItemProps> = (
318362
<EuiIcon type="grabOmnidirectional" />
319363
</EuiFlexItem>
320364
<EuiFlexItem grow={true}>
321-
<EuiText size="xs">{titleBarText}</EuiText>
365+
<EuiText size="xs">{itemTitle}</EuiText>
322366
</EuiFlexItem>
323367
</EuiFlexGroup>
324368
</EuiFlexItem>

electron/renderer/components/grid/grid.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export const Grid: React.FC<GridProps> = (props: GridProps): ReactNode => {
7777
<GridItem
7878
key={contentItem.layout.itemId}
7979
itemId={contentItem.layout.itemId}
80-
titleBarText={contentItem.layout.title}
80+
itemTitle={contentItem.layout.itemTitle}
8181
isFocused={contentItem.layout.itemId === focusedItemId}
8282
onFocus={onItemFocus}
8383
onClose={onItemClose}

electron/renderer/pages/grid.tsx

+12-193
Original file line numberDiff line numberDiff line change
@@ -340,187 +340,6 @@ const GridPage: React.FC = (): ReactNode => {
340340
const [gridWidthRef, { width: gridWidth }] = useMeasure<HTMLDivElement>();
341341
const gridHeight = windowSize.height - bottomBarSize.height - 40;
342342

343-
// TODO read layout from storage to detmine the items to show on the grid
344-
// TODO when a user adds an item, we subscribe to that event/callback and update the injected list
345-
// TODO when a user removes an item, we subscribe to that event/callback and update the injected list
346-
// In short, the Grid cmp should not determine what items it has, it receives the items and shows them
347-
const gridItems = [
348-
{
349-
itemId: 'room',
350-
title: 'Room',
351-
content: (
352-
<GameStream gameStreamIds={['room']} stream$={gameLogLineSubject$} />
353-
),
354-
},
355-
{
356-
itemId: 'experience',
357-
title: 'Experience',
358-
content: (
359-
<GameStream
360-
gameStreamIds={['experience']}
361-
stream$={gameLogLineSubject$}
362-
/>
363-
),
364-
},
365-
// {
366-
// itemId: 'percWindow',
367-
// title: 'Spells',
368-
// content: (
369-
// <GameStream
370-
// gameStreamIds={['percWindow']}
371-
// stream$={gameLogLineSubject$}
372-
// />
373-
// ),
374-
// },
375-
// {
376-
// itemId: 'inv',
377-
// title: 'Inventory',
378-
// content: (
379-
// <GameStream
380-
// gameStreamIds={['inv']}
381-
// stream$={gameLogLineSubject$}
382-
// />
383-
// ),
384-
// },
385-
// {
386-
// itemId: 'familiar',
387-
// title: 'Familiar',
388-
// content: (
389-
// <GameStream
390-
// gameStreamIds={['familiar']}
391-
// stream$={gameLogLineSubject$}
392-
// />
393-
// ),
394-
// },
395-
// {
396-
// itemId: 'thoughts',
397-
// title: 'Thoughts',
398-
// content: (
399-
// <GameStream
400-
// gameStreamIds={['thoughts']}
401-
// stream$={gameLogLineSubject$}
402-
// />
403-
// ),
404-
// },
405-
// {
406-
// itemId: 'combat',
407-
// title: 'Combat',
408-
// content: (
409-
// <GameStream
410-
// gameStreamIds={['combat']}
411-
// stream$={gameLogLineSubject$}
412-
// />
413-
// ),
414-
// },
415-
// {
416-
// itemId: 'assess',
417-
// title: 'Assess',
418-
// content: (
419-
// <GameStream
420-
// gameStreamIds={['assess']}
421-
// stream$={gameLogLineSubject$}
422-
// />
423-
// ),
424-
// },
425-
// {
426-
// itemId: 'logons',
427-
// title: 'Arrivals',
428-
// content: (
429-
// <GameStream
430-
// gameStreamIds={['logons']}
431-
// stream$={gameLogLineSubject$}
432-
// />
433-
// ),
434-
// },
435-
// {
436-
// itemId: 'death',
437-
// title: 'Deaths',
438-
// content: (
439-
// <GameStream
440-
// gameStreamIds={['death']}
441-
// stream$={gameLogLineSubject$}
442-
// />
443-
// ),
444-
// },
445-
// {
446-
// itemId: 'atmospherics',
447-
// title: 'Atmospherics',
448-
// content: (
449-
// <GameStream
450-
// gameStreamIds={['atmospherics']}
451-
// stream$={gameLogLineSubject$}
452-
// />
453-
// ),
454-
// },
455-
// {
456-
// itemId: 'chatter',
457-
// title: 'Chatter',
458-
// content: (
459-
// <GameStream
460-
// gameStreamIds={['chatter']}
461-
// stream$={gameLogLineSubject$}
462-
// />
463-
// ),
464-
// },
465-
// {
466-
// itemId: 'conversation',
467-
// title: 'Conversation',
468-
// content: (
469-
// <GameStream
470-
// gameStreamIds={['conversation']}
471-
// stream$={gameLogLineSubject$}
472-
// />
473-
// ),
474-
// },
475-
// {
476-
// itemId: 'whispers',
477-
// title: 'Whispers',
478-
// content: (
479-
// <GameStream
480-
// gameStreamIds={['whispers']}
481-
// stream$={gameLogLineSubject$}
482-
// />
483-
// ),
484-
// },
485-
// {
486-
// itemId: 'talk',
487-
// title: 'Talk',
488-
// content: (
489-
// <GameStream
490-
// gameStreamIds={['talk']}
491-
// stream$={gameLogLineSubject$}
492-
// />
493-
// ),
494-
// },
495-
// {
496-
// itemId: 'ooc',
497-
// title: 'OOC',
498-
// content: (
499-
// <GameStream
500-
// gameStreamIds={['ooc']}
501-
// stream$={gameLogLineSubject$}
502-
// />
503-
// ),
504-
// },
505-
// {
506-
// itemId: 'group',
507-
// title: 'Group',
508-
// content: (
509-
// <GameStream
510-
// gameStreamIds={['group']}
511-
// stream$={gameLogLineSubject$}
512-
// />
513-
// ),
514-
// },
515-
{
516-
itemId: 'main',
517-
title: 'Main',
518-
content: (
519-
<GameStream gameStreamIds={['']} stream$={gameLogLineSubject$} />
520-
),
521-
},
522-
];
523-
524343
interface GridConfigItem {
525344
itemId: string; // 'room'
526345
title: string; // 'Room'
@@ -566,27 +385,27 @@ const GridPage: React.FC = (): ReactNode => {
566385

567386
layoutGridItems.push({
568387
itemId: 'room',
569-
title: 'Room',
388+
itemTitle: 'Room',
570389
isFocused: false,
571390
x: 0,
572391
y: 0,
573392
width: 100,
574393
height: 100,
575394
});
576395

577-
// layoutGridItems.push({
578-
// itemId: 'experience',
579-
// title: 'Experience',
580-
// isFocused: false,
581-
// x: 200,
582-
// y: 0,
583-
// width: 100,
584-
// height: 100,
585-
// });
396+
layoutGridItems.push({
397+
itemId: 'experience',
398+
itemTitle: 'Experience',
399+
isFocused: false,
400+
x: 200,
401+
y: 0,
402+
width: 100,
403+
height: 100,
404+
});
586405

587406
layoutGridItems.push({
588407
itemId: 'main',
589-
title: 'Main',
408+
itemTitle: 'Main',
590409
isFocused: true,
591410
x: 0,
592411
y: 200,
@@ -628,7 +447,7 @@ const GridPage: React.FC = (): ReactNode => {
628447
contentGridItems.push({
629448
layout: {
630449
...layoutItem,
631-
title: configItem?.title ?? layoutItem.title,
450+
itemTitle: configItem?.title ?? layoutItem.itemTitle,
632451
},
633452
content: (
634453
<GameStream

0 commit comments

Comments
 (0)