Skip to content

Commit 557c69f

Browse files
authored
Add ability to convert items between types and UX improvements for context menus (#106)
* Update dependencies Signed-off-by: Axel Boberg <git@axelboberg.se> * Remove a call to populate item data when dropped into the rundown by moving it to createItem Signed-off-by: Axel Boberg <git@axelboberg.se> * Add ability to convert items to other types through the rundown Signed-off-by: Axel Boberg <git@axelboberg.se> * Update changelog Signed-off-by: Axel Boberg <git@axelboberg.se> * Keep tinting ancestor menu items in context menus when their child menus are opened Signed-off-by: Axel Boberg <git@axelboberg.se> * Update changelog Signed-off-by: Axel Boberg <git@axelboberg.se> --------- Signed-off-by: Axel Boberg <git@axelboberg.se>
1 parent bef1856 commit 557c69f

6 files changed

Lines changed: 130 additions & 45 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## 1.0.0-beta.9 - [UNRELEASED]
44
### Added
55
- Support for named urls when sharing links to workspaces
6+
- Ability to convert items to other types by right-clicking
7+
- Ancestor items in context menus now stay tinted when their child menus are opened
68
### Fixed
79
- An issue where the inspector started to scroll horisontally on overflow
810
- Closing electron windows may cause a loop preventing user defaults from being saved

app/components/ContextMenuItem/index.jsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ const MOUSE_LEAVE_DELAY_MS = 150
2020

2121
export const ContextMenuItem = ({ text, children = [], onClick = () => {} }) => {
2222
const elRef = React.useRef()
23+
24+
/*
25+
Delayed hover is used for preventing unmounting of
26+
child menus when the cursor leaves the item,
27+
regular hover is used for tinting the item
28+
*/
29+
const [delayedHover, setDelayedHover] = React.useState(false)
2330
const [hover, setHover] = React.useState(false)
31+
2432
const childArr = Array.isArray(children) ? children : [children]
2533

2634
const timeoutRef = React.useRef()
@@ -29,12 +37,14 @@ export const ContextMenuItem = ({ text, children = [], onClick = () => {} }) =>
2937
if (timeoutRef.current) {
3038
clearTimeout(timeoutRef.current)
3139
}
40+
setDelayedHover(true)
3241
setHover(true)
3342
}
3443

3544
function handleMouseLeave () {
45+
setHover(false)
3646
timeoutRef.current = setTimeout(() => {
37-
setHover(false)
47+
setDelayedHover(false)
3848
}, MOUSE_LEAVE_DELAY_MS)
3949
}
4050

@@ -45,6 +55,7 @@ export const ContextMenuItem = ({ text, children = [], onClick = () => {} }) =>
4555
}
4656

4757
function handleFocus (e) {
58+
setDelayedHover(true)
4859
setHover(true)
4960
}
5061

@@ -53,7 +64,7 @@ export const ContextMenuItem = ({ text, children = [], onClick = () => {} }) =>
5364
return (
5465
<div
5566
ref={elRef}
56-
className='ContextMenuItem'
67+
className={`ContextMenuItem ${hover ? 'is-hovered' : ''}`}
5768
onMouseEnter={handleMouseEnter}
5869
onMouseLeave={handleMouseLeave}
5970
onClick={() => onClick()}
@@ -69,7 +80,7 @@ export const ContextMenuItem = ({ text, children = [], onClick = () => {} }) =>
6980
<Icon name='arrowRight' color='black' />
7081
}
7182
{
72-
hover && childArr.length > 0
83+
delayedHover && childArr.length > 0
7384
? (
7485
<ContextMenu x={bounds?.x + CTX_MENU_OFFSET_X_PX} y={bounds?.y + bounds?.height / 2}>
7586
{children}

app/components/ContextMenuItem/style.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
--base-color: black;
3030
}
3131

32-
.ContextMenuItem:hover > .ContextMenuItem-text {
32+
.ContextMenuItem:hover > .ContextMenuItem-text,
33+
.ContextMenuItem.is-hovered > .ContextMenuItem-text {
3334
background: rgb(228, 228, 228);
3435
}
3536

package-lock.json

Lines changed: 96 additions & 38 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/rundown/app/components/RundownList/index.jsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,7 @@ export function RundownList ({
281281
console.warn('Dropped spec is missing type')
282282
return
283283
}
284-
const itemId = await bridge.items.createItem(spec.type)
285-
286-
bridge.items.applyItem(itemId, spec)
284+
const itemId = await bridge.items.createItem(spec.type, spec?.data)
287285
bridge.commands.executeCommand('rundown.moveItem', rundownId, newIndex, itemId)
288286
} catch (_) {
289287
console.warn('Tried to drop an invalid spec')

plugins/rundown/app/components/RundownListItem/index.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ export function RundownListItem ({
128128
label: 'Add after',
129129
children: contextMenu.generateAddContextMenuItems(types, typeId => handleAdd(typeId))
130130
},
131+
{
132+
type: 'item',
133+
label: 'Convert to',
134+
children: contextMenu.generateAddContextMenuItems(types, typeId => handleConvertTo(typeId))
135+
},
131136
{
132137
type: 'item',
133138
label: 'Create reference',
@@ -189,6 +194,16 @@ export function RundownListItem ({
189194
bridge.commands.executeCommand('rundown.moveItem', rundownId, index + 1, itemId)
190195
}
191196

197+
async function handleConvertTo (typeId) {
198+
if (!item?.id) {
199+
return
200+
}
201+
202+
await bridge.items.applyItem(item?.id, {
203+
type: typeId
204+
})
205+
}
206+
192207
async function handleCreateReference () {
193208
const newItemId = await bridge.items.createItem('bridge.types.reference')
194209

0 commit comments

Comments
 (0)