Move notifications trigger to toolbar (#333)
* Move notification trigger to toolbar * Make notifications unpinned by default
This commit is contained in:
parent
455ac7736d
commit
cb8fa2f20f
4 changed files with 74 additions and 53 deletions
|
@ -302,28 +302,16 @@ const Button = styled.button<{danger?: boolean}>`
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const Dots = styled.span`
|
|
||||||
display: flex;
|
|
||||||
gap: 4px;
|
|
||||||
`
|
|
||||||
|
|
||||||
const NotificationsDot = styled.div<{type: NotificationType}>`
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
border-radius: 999999px;
|
|
||||||
background-color: ${({type}) => COLORS[type]};
|
|
||||||
`
|
|
||||||
|
|
||||||
const NotifierContainer = styled.div`
|
const NotifierContainer = styled.div`
|
||||||
z-index: 9999;
|
z-index: 10;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
bottom: 8px;
|
top: 50px;
|
||||||
width: 500px;
|
width: 500px;
|
||||||
height: 50vh;
|
height: 85vh;
|
||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -371,42 +359,10 @@ export const Notifier = () => {
|
||||||
const {startPause, endPause} = handlers
|
const {startPause, endPause} = handlers
|
||||||
|
|
||||||
const pinNotifications =
|
const pinNotifications =
|
||||||
useVal(getStudio().atomP.ahistoric.pinNotifications) ?? true
|
useVal(getStudio().atomP.ahistoric.pinNotifications) ?? false
|
||||||
const togglePinNotifications = () =>
|
|
||||||
getStudio().transaction(({stateEditors, drafts}) => {
|
|
||||||
stateEditors.studio.ahistoric.setPinNotifications(
|
|
||||||
!(drafts.ahistoric.pinNotifications ?? true),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NotifierContainer>
|
<NotifierContainer>
|
||||||
<ButtonContainer align="side">
|
|
||||||
<>
|
|
||||||
{pinNotifications && toasts.length > 0 && (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
notificationTypeChecker.clear()
|
|
||||||
notificationUniquenessChecker.clear()
|
|
||||||
toast.remove()
|
|
||||||
}}
|
|
||||||
danger
|
|
||||||
>
|
|
||||||
Clear
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<Button onClick={() => togglePinNotifications()}>
|
|
||||||
<span>Notifications</span>
|
|
||||||
{notificationTypeChecker.types.length > 0 && (
|
|
||||||
<Dots>
|
|
||||||
{notificationTypeChecker.types.map((type) => (
|
|
||||||
<NotificationsDot type={type} key={type} />
|
|
||||||
))}
|
|
||||||
</Dots>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
</ButtonContainer>
|
|
||||||
{!pinNotifications ? null : toasts.length > 0 ? (
|
{!pinNotifications ? null : toasts.length > 0 ? (
|
||||||
<NotificationScroller onMouseEnter={startPause} onMouseLeave={endPause}>
|
<NotificationScroller onMouseEnter={startPause} onMouseLeave={endPause}>
|
||||||
<div>
|
<div>
|
||||||
|
@ -427,6 +383,28 @@ export const Notifier = () => {
|
||||||
Notifications will appear here when you get them.
|
Notifications will appear here when you get them.
|
||||||
</EmptyState>
|
</EmptyState>
|
||||||
)}
|
)}
|
||||||
|
<ButtonContainer align="side">
|
||||||
|
{pinNotifications && toasts.length > 0 && (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
notificationTypeChecker.clear()
|
||||||
|
notificationUniquenessChecker.clear()
|
||||||
|
toast.remove()
|
||||||
|
}}
|
||||||
|
danger
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</ButtonContainer>
|
||||||
</NotifierContainer>
|
</NotifierContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useNotifications = () => {
|
||||||
|
const {toasts} = useToaster()
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasNotifications: toasts.length > 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,12 +9,18 @@ import BasicTooltip from '@theatre/studio/uiComponents/Popover/BasicTooltip'
|
||||||
import {val} from '@theatre/dataverse'
|
import {val} from '@theatre/dataverse'
|
||||||
import ExtensionToolbar from './ExtensionToolbar/ExtensionToolbar'
|
import ExtensionToolbar from './ExtensionToolbar/ExtensionToolbar'
|
||||||
import PinButton from './PinButton'
|
import PinButton from './PinButton'
|
||||||
import {Details, Ellipsis, Outline} from '@theatre/studio/uiComponents/icons'
|
import {
|
||||||
|
Details,
|
||||||
|
Ellipsis,
|
||||||
|
Outline,
|
||||||
|
Bell,
|
||||||
|
} from '@theatre/studio/uiComponents/icons'
|
||||||
import DoubleChevronLeft from '@theatre/studio/uiComponents/icons/DoubleChevronLeft'
|
import DoubleChevronLeft from '@theatre/studio/uiComponents/icons/DoubleChevronLeft'
|
||||||
import DoubleChevronRight from '@theatre/studio/uiComponents/icons/DoubleChevronRight'
|
import DoubleChevronRight from '@theatre/studio/uiComponents/icons/DoubleChevronRight'
|
||||||
import ToolbarIconButton from '@theatre/studio/uiComponents/toolbar/ToolbarIconButton'
|
import ToolbarIconButton from '@theatre/studio/uiComponents/toolbar/ToolbarIconButton'
|
||||||
import usePopover from '@theatre/studio/uiComponents/Popover/usePopover'
|
import usePopover from '@theatre/studio/uiComponents/Popover/usePopover'
|
||||||
import MoreMenu from './MoreMenu/MoreMenu'
|
import MoreMenu from './MoreMenu/MoreMenu'
|
||||||
|
import {useNotifications} from '@theatre/studio/notify'
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
height: 36px;
|
height: 36px;
|
||||||
|
@ -47,9 +53,9 @@ const SubContainer = styled.div`
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const HasUpdatesBadge = styled.div`
|
const HasUpdatesBadge = styled.div<{type: 'info' | 'warning'}>`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: #40aaa4;
|
background: ${({type}) => (type === 'info' ? '#40aaa4' : '#f59e0b')};
|
||||||
width: 6px;
|
width: 6px;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
@ -139,6 +145,8 @@ const GlobalToolbar: React.FC = () => {
|
||||||
return hasUpdates
|
return hasUpdates
|
||||||
}, [hasUpdates])
|
}, [hasUpdates])
|
||||||
|
|
||||||
|
const {hasNotifications} = useNotifications()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<SubContainer>
|
<SubContainer>
|
||||||
|
@ -166,6 +174,18 @@ const GlobalToolbar: React.FC = () => {
|
||||||
<ExtensionToolbar showLeftDivider toolbarId="global" />
|
<ExtensionToolbar showLeftDivider toolbarId="global" />
|
||||||
</SubContainer>
|
</SubContainer>
|
||||||
<SubContainer>
|
<SubContainer>
|
||||||
|
<ToolbarIconButton
|
||||||
|
onClick={() => {
|
||||||
|
getStudio().transaction(({stateEditors, drafts}) => {
|
||||||
|
stateEditors.studio.ahistoric.setPinNotifications(
|
||||||
|
!(drafts.ahistoric.pinNotifications ?? false),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Bell />
|
||||||
|
{hasNotifications && <HasUpdatesBadge type="warning" />}
|
||||||
|
</ToolbarIconButton>
|
||||||
{moreMenu.node}
|
{moreMenu.node}
|
||||||
<ToolbarIconButton
|
<ToolbarIconButton
|
||||||
ref={moreMenuTriggerRef}
|
ref={moreMenuTriggerRef}
|
||||||
|
@ -174,7 +194,7 @@ const GlobalToolbar: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Ellipsis />
|
<Ellipsis />
|
||||||
{showUpdatesBadge && <HasUpdatesBadge />}
|
{showUpdatesBadge && <HasUpdatesBadge type="info" />}
|
||||||
</ToolbarIconButton>
|
</ToolbarIconButton>
|
||||||
<PinButton
|
<PinButton
|
||||||
ref={triggerButtonRef as $IntentionalAny}
|
ref={triggerButtonRef as $IntentionalAny}
|
||||||
|
|
22
theatre/studio/src/uiComponents/icons/Bell.tsx
Normal file
22
theatre/studio/src/uiComponents/icons/Bell.tsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import * as React from 'react'
|
||||||
|
|
||||||
|
function Bell(props: React.SVGProps<SVGSVGElement>) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8 1.57c-.416 0-.752.36-.752.804v.482c-1.715.372-3.006 1.994-3.006 3.938v.473c0 1.18-.407 2.32-1.14 3.205l-.173.208a.85.85 0 00-.125.864.75.75 0 00.686.475h9.019a.752.752 0 00.686-.475.845.845 0 00-.125-.864l-.174-.208a5.026 5.026 0 01-1.139-3.205v-.473c0-1.944-1.291-3.566-3.006-3.938v-.482c0-.445-.336-.804-.752-.804zm1.063 12.39c.282-.301.44-.71.44-1.138H6.496c0 .428.158.837.44 1.138.281.302.664.47 1.063.47.4 0 .783-.168 1.064-.47z"
|
||||||
|
fill="#fff"
|
||||||
|
fillOpacity={0.6}
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Bell
|
|
@ -14,3 +14,4 @@ export {default as Ellipsis} from './Ellipsis'
|
||||||
export {default as GlobeSimple} from './GlobeSimple'
|
export {default as GlobeSimple} from './GlobeSimple'
|
||||||
export {default as Resize} from './Resize'
|
export {default as Resize} from './Resize'
|
||||||
export {default as Package} from './Package'
|
export {default as Package} from './Package'
|
||||||
|
export {default as Bell} from './Bell'
|
||||||
|
|
Loading…
Reference in a new issue