-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WRS-2173 - studio ui multi-page (#244)
Co-authored-by: sebastian-mereuta <sebastian.mereuta93@gmail.com>
- Loading branch information
1 parent
2c2dcc8
commit 56ed8ac
Showing
11 changed files
with
256 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { ITheme } from '@chili-publish/grafx-shared-components'; | ||
import styled from 'styled-components'; | ||
|
||
export const Container = styled.div<{ themeStyles: ITheme; isMobileSize: boolean }>` | ||
box-sizing: border-box; | ||
display: flex; | ||
justify-content: center; | ||
max-width: ${({ isMobileSize }) => (!isMobileSize ? 'calc(100vw - 18.875rem)' : '100%')}; | ||
height: 7.5rem; | ||
background: ${({ themeStyles }) => themeStyles.panel.backgroundColor}; | ||
border-top: 2px solid ${({ themeStyles }) => themeStyles.panel.borderColor}; | ||
`; | ||
export const ScrollableContainer = styled.div` | ||
display: flex; | ||
height: 100%; | ||
padding: 0 0.625rem; | ||
align-items: center; | ||
overflow-x: auto; | ||
width: auto; | ||
white-space: nowrap; | ||
overflow-y: hidden; | ||
`; | ||
export const Card = styled.div<{ themeStyles: ITheme; selected?: boolean }>` | ||
box-sizing: border-box; | ||
width: 5rem; | ||
height: 5rem; | ||
margin: 0 0.625rem; | ||
flex-shrink: 0; | ||
border-radius: 0.5rem; | ||
border: 1px solid | ||
${({ selected, themeStyles }) => | ||
selected ? themeStyles.previewCard.card.selected.borderColor : themeStyles.previewCard.card.borderColor}; | ||
background-color: ${({ themeStyles }) => themeStyles.canvas.backgroundColor}; | ||
&:hover { | ||
border-color: ${({ themeStyles }) => themeStyles.previewCard.card.hover.borderColor}; | ||
} | ||
[data-id^='gsc-preview-container-'] { | ||
border-radius: 0.5rem; | ||
} | ||
`; | ||
export const NumberBadge = styled.div` | ||
position: absolute; | ||
bottom: 0.315rem; | ||
left: 0.9375rem; | ||
width: 1.5rem; | ||
height: 1.5rem; | ||
background-color: rgba(37, 37, 37, 0.75); | ||
color: white; | ||
font-size: 0.75rem; | ||
border-radius: 0.25rem; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
`; | ||
export const Wrapper = styled.div` | ||
position: relative; | ||
display: flex; | ||
justify-items: center; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { useCallback, useEffect, useState } from 'react'; | ||
import { Page } from '@chili-publish/studio-sdk'; | ||
import { | ||
PreviewCard, | ||
PreviewCardVariant, | ||
PreviewType, | ||
ScrollbarWrapper, | ||
useMobileSize, | ||
useTheme, | ||
} from '@chili-publish/grafx-shared-components'; | ||
import { ScrollableContainer, Card, Container } from './Pages.styles'; | ||
import { PREVIEW_FALLBACK } from '../../utils/constants'; | ||
import { PageSnapshot } from '../../types/types'; | ||
import { PreviewCardBadge } from './PreviewCardBadge'; | ||
|
||
interface PagesProps { | ||
pages: Page[]; | ||
activePageId: string | null; | ||
pagesToRefresh: string[]; | ||
setPagesToRefresh: React.Dispatch<React.SetStateAction<string[]>>; | ||
} | ||
|
||
function Pages({ pages, activePageId, pagesToRefresh, setPagesToRefresh }: PagesProps) { | ||
const theme = useTheme(); | ||
const [pageSnapshots, setPageSnapshots] = useState<PageSnapshot[]>([]); | ||
const isMobileSize = useMobileSize(); | ||
|
||
const handleSelectPage = async (pageId: string) => { | ||
await window.StudioUISDK.page.select(pageId); | ||
}; | ||
|
||
const getPagesSnapshot = useCallback(async (ids: string[]) => { | ||
const snapArray = ids.map((id) => | ||
window.SDK.page.getSnapshot(id).then((snapshot) => ({ | ||
id, | ||
snapshot: snapshot as unknown as Uint8Array, | ||
})), | ||
); | ||
const awaitedArray = await Promise.all(snapArray); | ||
setPageSnapshots(awaitedArray); | ||
return awaitedArray as PageSnapshot[]; | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (pages?.length && !pageSnapshots.length) { | ||
getPagesSnapshot(pages.map((i) => i.id)); | ||
} | ||
}, [pages, pageSnapshots, getPagesSnapshot]); | ||
|
||
useEffect(() => { | ||
if (!pagesToRefresh.length) return; | ||
|
||
const updateSnapshots = async () => { | ||
const snapshotsArray = await getPagesSnapshot(pagesToRefresh); | ||
const updatedSnapshots = await Promise.all(snapshotsArray); | ||
|
||
// Update state once with all new snapshots | ||
setPageSnapshots((prevSnapshots) => { | ||
const filteredSnapshots = prevSnapshots.filter((snap) => { | ||
return pages.find((p) => p.id === snap.id); | ||
}); | ||
updatedSnapshots.forEach(({ id, snapshot }) => { | ||
const idx = filteredSnapshots.findIndex((item) => item.id === id); | ||
if (idx !== -1) { | ||
filteredSnapshots[idx] = { ...filteredSnapshots[idx], snapshot }; | ||
} | ||
}); | ||
return filteredSnapshots; | ||
}); | ||
|
||
setPagesToRefresh([]); | ||
}; | ||
|
||
const timeoutId = setTimeout(updateSnapshots, 1000); | ||
|
||
// eslint-disable-next-line consistent-return | ||
return () => { | ||
clearTimeout(timeoutId); | ||
}; | ||
}, [pagesToRefresh, setPagesToRefresh, getPagesSnapshot]); | ||
Check warning on line 80 in src/components/pagesPanel/Pages.tsx
|
||
|
||
return ( | ||
<Container themeStyles={theme} isMobileSize={isMobileSize}> | ||
<ScrollbarWrapper invertScrollbarColors> | ||
<ScrollableContainer> | ||
{!!pages?.length && | ||
pages.map((item, index) => ( | ||
<PreviewCardBadge badgeNumber={index + 1} key={`badge-${item.id}`}> | ||
<Card themeStyles={theme} selected={item.id === activePageId} key={`card-${item.id}`}> | ||
<PreviewCard | ||
key={`${item.id}-preview-card`} | ||
path={ | ||
pageSnapshots[index] && | ||
URL.createObjectURL( | ||
new Blob([pageSnapshots[index].snapshot.buffer], { type: 'image/png' }), | ||
) | ||
} | ||
type={PreviewType.IMAGE} | ||
itemId={item.id} | ||
fallback={PREVIEW_FALLBACK} | ||
padding="0" | ||
options={[]} | ||
renamingDisabled | ||
variant={PreviewCardVariant.LIST} | ||
selected={item.id === activePageId} | ||
onClickCard={() => { | ||
handleSelectPage(item.id); | ||
}} | ||
/> | ||
</Card> | ||
</PreviewCardBadge> | ||
))} | ||
</ScrollableContainer> | ||
</ScrollbarWrapper> | ||
</Container> | ||
); | ||
} | ||
export default Pages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { ReactNode } from 'react'; | ||
import { NumberBadge, Wrapper } from './Pages.styles'; | ||
|
||
interface PreviewCardBadgeProps { | ||
badgeNumber?: number; | ||
children: ReactNode; | ||
} | ||
|
||
export function PreviewCardBadge({ badgeNumber, children }: PreviewCardBadgeProps) { | ||
return ( | ||
<Wrapper key={`card-wrapped-${badgeNumber}`}> | ||
{children} | ||
{badgeNumber && <NumberBadge>{badgeNumber}</NumberBadge>} | ||
</Wrapper> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export const APP_WRAPPER_ID = 'studio-ui-application'; | ||
export const PREVIEW_FALLBACK = 'https://studio-cdn.chiligrafx.com/shared/assets/preview-fallback-padded.svg'; | ||
export const SESSION_USER_INTEFACE_ID_KEY = 'userInterfaceId'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters