Skip to content

Commit c2c3b56

Browse files
Merge pull request #353 from lightningrodlabs/canvas-pan
adding panning for edge of screen
2 parents f983fc7 + 98cf055 commit c2c3b56

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1655
-1205
lines changed

web/src/components/ContextMenu/ContextMenu.scss

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
color: var(--text-color-dark-bg);
44
font: 0.825rem var(--font-family-primary-medium);
55
box-shadow: 0rem 0rem 0.75rem var(--shadow-color);
6-
padding: 0.5rem;
6+
padding: 0.75rem 0.625rem;
77
box-sizing: border-box;
88
border-radius: 0.75rem;
99
cursor: pointer;
@@ -18,17 +18,18 @@
1818
display: flex;
1919
flex-direction: row;
2020
align-items: center;
21-
padding: 0.325rem 0.25rem;
21+
padding: 0.325rem 0.5rem;
2222
border-radius: 0.625rem;
2323
transition: 0.075s all ease;
24+
line-height: 1.5;
2425

2526
&:hover {
2627
background-color: var(--bg-color-hover-dark);
2728
box-shadow: 0px 0rem 0.5rem var(--bg-color-hover-dark);
2829
}
2930

3031
.context-menu-action-icon {
31-
margin-right: 0.375rem;
32+
margin-right: 0.5rem;
3233

3334
.icon {
3435
height: 0.875rem;

web/src/components/ContextMenu/ContextMenu.tsx

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,52 @@
1-
import React from 'react'
1+
import React, { useEffect, useRef } from 'react'
22
import { ActionHashB64 } from '../../types/shared'
33
import Icon from '../Icon/Icon'
44
import './ContextMenu.scss'
55

66
export type ContextMenuProps = {
77
// proptypes
8-
menuWidth?: string
8+
menuWidth: string
99
outcomeActionHash: ActionHashB64
1010
actions: {
1111
key: string
1212
icon?: string
1313
text: string
1414
onClick?: (outcomeActionHash: ActionHashB64) => void
1515
}[]
16+
setMenuHeight: (height: number) => void
1617
}
1718

1819
const ContextMenu: React.FC<ContextMenuProps> = ({
19-
// prop declarations
20-
menuWidth = '11rem',
20+
menuWidth,
2121
actions,
2222
outcomeActionHash,
23+
setMenuHeight,
2324
}) => {
25+
const ref = useRef<HTMLDivElement>(null)
26+
27+
useEffect(() => {
28+
if (ref.current) {
29+
const height = ref.current.offsetHeight
30+
// send the height back to the parent
31+
setMenuHeight(height)
32+
}
33+
}, [ref.current])
34+
35+
// adjust height when number of actions changes
36+
useEffect(() => {
37+
if (ref.current) {
38+
const height = ref.current.offsetHeight
39+
// send the height back to the parent
40+
setMenuHeight(height)
41+
}
42+
}, [actions.length])
43+
2444
return (
25-
<div className="context-menu-wrapper" style={{ width: menuWidth }}>
45+
<div
46+
className="context-menu-wrapper"
47+
style={{ width: menuWidth }}
48+
ref={ref}
49+
>
2650
<div className="context-menu-actions">
2751
{actions.map((action) => (
2852
<div

web/src/components/ExpandedViewMode/EVMiddleColumn/TabContent/EvComments/EvComments.component.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ const EvComments: React.FC<EvCommentsProps> = ({
112112
}`}
113113
/>
114114
<div className="comments-posted-wrapper" ref={commentHistoryRef}>
115+
{comments.length === 0 && (
116+
<div className="comments-posted-list-item">
117+
<div className="comments-posted-list-item-empty">
118+
There are no comments on this outcome yet.
119+
</div>
120+
</div>
121+
)}
115122
{comments
116123
// just in case we don't have someones profile, don't show them for now
117124
// so only keep ones whose profiles we have

web/src/components/ExpandedViewMode/EVMiddleColumn/TabContent/EvComments/EvComments.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
margin-bottom: 0.5rem;
1010
transition: 0.2s background-color ease;
1111

12+
.comments-posted-list-item-empty {
13+
color: var(--text-color-tertiary);
14+
}
15+
1216
&:first-child {
1317
margin-top: 1rem;
1418
}

web/src/components/ExpandedViewMode/ExpandedViewMode.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
left: 50%;
1313
-ms-transform: translate(-50%, -50%);
1414
transform: translate(-50%, -50%);
15-
z-index: 3;
15+
z-index: 4;
1616

1717
.button-close-wrapper {
1818
position: absolute;
@@ -30,14 +30,14 @@
3030
overflow-y: hidden;
3131
position: fixed;
3232
top: 0;
33-
z-index: 2;
33+
z-index: 4;
3434
}
3535

3636
.breadcrumbs-overlay {
3737
position: fixed;
3838
top: 0.5rem;
3939
left: 1rem;
40-
z-index: 3;
40+
z-index: 5;
4141
}
4242

4343
// breadcrumbs css transitions (animation)

web/src/components/Footer/Footer.scss

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,19 @@
11
.footer {
22
max-height: 48px;
3-
z-index: 3;
3+
44
}
55

66
/* Buttom Left Panel */
77

8-
.bottom-panel {
8+
.bottom-left-panel {
99
position: fixed;
1010
bottom: 10px;
1111
left: 10px;
1212
display: flex;
1313
align-items: center;
1414
flex-direction: row;
1515
height: 48px;
16-
}
17-
18-
.bottom-panel-entry-points {
19-
background: rgba(255, 255, 255, 0.9) 0% 0% no-repeat padding-box;
20-
border-radius: 10px;
21-
height: 46px;
22-
width: 46px;
23-
margin-left: 10px;
24-
display: flex;
25-
align-items: center;
26-
justify-content: space-evenly;
27-
}
28-
29-
.bottom-panel-entry-points .icon {
30-
height: 26px;
31-
width: 26px;
32-
padding: 2px;
33-
display: inline-block;
34-
position: relative;
35-
}
36-
37-
/* when Entry Point Icon is open: */
38-
39-
.bottom-panel-entry-points .icon.active .inner-icon {
40-
background-color: var(--text-color-link);
16+
z-index: 4;
4117
}
4218

4319
/* Buttom Right Panel */
@@ -54,6 +30,7 @@
5430
align-items: center;
5531
flex-direction: row;
5632
height: 48px;
33+
z-index: 3;
5734

5835
.map-viewing-options-button-wrapper {
5936
position: relative;

web/src/components/Footer/Footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ const Footer: React.FC<FooterProps> = ({
104104
return (
105105
<div className="footer" ref={ref}>
106106
{/* Report Issue Button */}
107-
<div className="bottom-panel">
107+
<div className="bottom-left-panel">
108108
<a
109109
href="https://github.com/lightningrodlabs/acorn/issues/new"
110110
target="_blank"
Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
import React, { useContext } from 'react'
1+
import React, { useContext, useEffect, useState } from 'react'
22
import { ActionHashB64, CellIdString } from '../../types/shared'
33

44
import './MapViewContextMenu.scss'
55
import ContextMenu from '../ContextMenu/ContextMenu'
66
import ToastContext, { ShowToast } from '../../context/ToastContext'
7+
import useContainWithinScreen from '../../hooks/useContainWithinScreen'
78

8-
export type CheckboxProps = {
9+
export type MapViewContextMenuProps = {
910
projectCellId: CellIdString
1011
outcomeActionHash: ActionHashB64
1112
outcomeStatement: string
1213
isCollapsed: boolean
1314
hasChildren: boolean
14-
contextMenuCoordinate: {
15+
contextMenuClickCoordinate: {
1516
x: number
1617
y: number
1718
}
@@ -26,20 +27,19 @@ export type CheckboxProps = {
2627
unsetContextMenu: () => void
2728
}
2829

29-
const Checkbox: React.FC<CheckboxProps> = ({
30+
const MapViewContextMenu: React.FC<MapViewContextMenuProps> = ({
3031
projectCellId,
3132
outcomeActionHash,
3233
outcomeStatement,
3334
isCollapsed,
3435
hasChildren,
35-
contextMenuCoordinate,
36+
contextMenuClickCoordinate,
3637
expandOutcome,
3738
collapseOutcome,
3839
unsetContextMenu,
3940
}) => {
40-
41-
// pull in the toast context
42-
const { setToastState } = useContext(ToastContext)
41+
// pull in the toast context
42+
const { setToastState } = useContext(ToastContext)
4343

4444
const wrappedCollapseOutcome = () => {
4545
collapseOutcome(projectCellId, outcomeActionHash)
@@ -60,42 +60,94 @@ const { setToastState } = useContext(ToastContext)
6060
}
6161

6262
const actions = []
63+
64+
actions.push({
65+
key: 'copy-outcome',
66+
icon: 'file-copy.svg',
67+
text: 'Copy Outcome',
68+
onClick: copyOutcomeStatement,
69+
})
70+
6371
actions.push({
6472
key: 'copy-statement',
6573
icon: 'text-align-left.svg',
6674
text: 'Copy Statement',
6775
onClick: copyOutcomeStatement,
6876
})
6977

78+
// only show this if the outcome has children
79+
if (hasChildren) {
80+
actions.push({
81+
key: 'copy-subtree',
82+
icon: 'file-copy.svg',
83+
text: 'Copy Subtree',
84+
onClick: copyOutcomeStatement,
85+
})
86+
}
87+
88+
// only show this if the outcome has children
89+
if (hasChildren) {
90+
actions.push({
91+
key: 'export-subtree',
92+
icon: 'export.svg',
93+
text: 'Export Subtree',
94+
onClick: copyOutcomeStatement,
95+
})
96+
}
97+
98+
// only enable if the outcome is has children BUT
99+
// children should not have multiple parents
70100
if (hasChildren && isCollapsed) {
71101
actions.push({
72102
key: 'expand',
73-
icon: 'leaf.svg',
74-
text: 'Expand Outcome',
103+
icon: 'expand2.svg',
104+
text: 'Expand Subtree',
75105
onClick: wrappedExpandOutcome,
76106
})
77107
}
78-
// DISABLED: collapsing outcomes
79-
// else if (hasChildren) {
80-
// actions.push({
81-
// key: 'collapse',
82-
// icon: 'leaf.svg',
83-
// text: 'Collapse Outcome',
84-
// onClick: wrappedCollapseOutcome,
85-
// })
86-
// }
108+
// only enable if the outcome is has children BUT
109+
// TODO: if only children do not have multiple parents
110+
else if (hasChildren) {
111+
actions.push({
112+
key: 'collapse',
113+
icon: 'collapse.svg',
114+
text: 'Collapse Subtree',
115+
onClick: wrappedCollapseOutcome,
116+
})
117+
}
118+
119+
// set menu width in pixels
120+
const menuWidth = 176
121+
122+
// use this hook to make sure the menu is contained within the screen
123+
const {
124+
initialized,
125+
setItemHeight: setMenuHeight,
126+
renderCoordinate,
127+
} = useContainWithinScreen({
128+
initialWidth: menuWidth,
129+
initialHeight: 0,
130+
cursorCoordinate: contextMenuClickCoordinate,
131+
})
87132

88133
return (
89134
<div
90135
className="map-view-context-menu"
91136
style={{
92-
top: `${contextMenuCoordinate.y}px`,
93-
left: `${contextMenuCoordinate.x}px`,
137+
top: `${renderCoordinate.y}px`,
138+
left: `${renderCoordinate.x}px`,
139+
// make sure the menu is not visible until the height is calculated
140+
visibility: initialized ? 'visible' : 'hidden',
94141
}}
95142
>
96-
<ContextMenu outcomeActionHash={outcomeActionHash} actions={actions} />
143+
<ContextMenu
144+
menuWidth={`${menuWidth}px`}
145+
setMenuHeight={setMenuHeight}
146+
outcomeActionHash={outcomeActionHash}
147+
actions={actions}
148+
/>
97149
</div>
98150
)
99151
}
100152

101-
export default Checkbox
153+
export default MapViewContextMenu

0 commit comments

Comments
 (0)