Skip to content

Commit 9a33088

Browse files
committed
feat: embeds stay locked while using Hand tool
- Updated LockIndicator to accept appState as a prop, allowing it to respond to hand tool activation. - Improved visibility logic for the lock icon based on scrolling and hand tool state. - Added new styles for lock icon text in CustomEmbeddableRenderer.scss to enhance user feedback during interactions.
1 parent 9c9cadf commit 9a33088

File tree

2 files changed

+64
-15
lines changed

2 files changed

+64
-15
lines changed

src/frontend/src/CustomEmbeddableRenderer.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535
&.visible {
3636
opacity: 1;
3737
}
38+
39+
&__text {
40+
margin-left: 4px;
41+
font-size: 12px;
42+
font-weight: 600;
43+
font-family: 'Roboto', sans-serif;
44+
color: #afafaf;
45+
opacity: 0.7;
46+
}
3847
}
3948

4049
&__content {

src/frontend/src/CustomEmbeddableRenderer.tsx

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export const renderCustomEmbeddable = (
7373
<div className="custom-embed">
7474
<div className="custom-embed__title-bar">
7575
<div className="custom-embed__title-bar__text">{title}</div>
76-
<LockIndicator />
76+
<LockIndicator appState={appState} />
7777
</div>
7878
<div className="custom-embed__content">
7979
{content}
@@ -87,7 +87,7 @@ export const renderCustomEmbeddable = (
8787
<div className="custom-embed">
8888
<div className="custom-embed__title-bar">
8989
<div className="custom-embed__title-bar__text">{title}</div>
90-
<LockIndicator />
90+
<LockIndicator appState={appState} />
9191
</div>
9292
<div className="custom-embed__content">
9393
<iframe className="custom-embed__content--iframe" src={element.link} />
@@ -97,13 +97,15 @@ export const renderCustomEmbeddable = (
9797
}
9898
};
9999

100-
// Lock icon component that shows when scrolling
101-
const LockIndicator = () => {
102-
const [visible, setVisible] = useState(false);
100+
// Lock icon component that shows when scrolling or when hand tool is active
101+
const LockIndicator = ({ appState }: { appState?: AppState }) => {
102+
const [isScrolling, setIsScrolling] = useState(false);
103+
const [isHandToolActive, setIsHandToolActive] = useState(false);
103104

105+
// Effect to handle scroll state changes
104106
useEffect(() => {
105107
const handleScrollStateChange = (event: CustomEvent<{ isScrolling: boolean }>) => {
106-
setVisible(event.detail.isScrolling);
108+
setIsScrolling(event.detail.isScrolling);
107109
};
108110

109111
// Add event listener for scroll state changes
@@ -115,15 +117,46 @@ const LockIndicator = () => {
115117
};
116118
}, []);
117119

120+
// Separate effect to handle hand tool state changes
121+
useEffect(() => {
122+
// Check hand tool state
123+
const handToolActive = appState?.activeTool?.type === "hand";
124+
const wasHandToolActive = isHandToolActive;
125+
setIsHandToolActive(handToolActive);
126+
127+
// If hand tool was active but is now deactivated
128+
if (wasHandToolActive && !handToolActive) {
129+
// Force reset of global scrolling state
130+
globalIsScrolling = false;
131+
document.documentElement.style.setProperty('--embeddable-pointer-events', 'all');
132+
133+
// Dispatch event to update all components
134+
scrollStateChangeEvent.detail.isScrolling = false;
135+
document.dispatchEvent(scrollStateChangeEvent);
136+
137+
// Update component state
138+
setIsScrolling(false);
139+
} else if (handToolActive) {
140+
// Set pointer-events to none when hand tool is active
141+
document.documentElement.style.setProperty('--embeddable-pointer-events', 'none');
142+
}
143+
}, [appState]);
144+
145+
// Determine if the lock should be visible
146+
const visible = isScrolling || isHandToolActive;
147+
118148
return (
119149
<div className={`custom-embed__lock-icon ${visible ? 'visible' : ''}`}>
120150
<Lock size={16} />
151+
<span className={`custom-embed__lock-icon__text ${isHandToolActive ? 'visible' : ''}`}>
152+
(Hand tool)
153+
</span>
121154
</div>
122155
);
123156
};
124157

125-
// Track scrolling state
126-
let isScrolling = false;
158+
// Track scrolling state globally
159+
let globalIsScrolling = false;
127160
// Create a custom event for scrolling state changes
128161
const scrollStateChangeEvent = new CustomEvent('scrollStateChange', { detail: { isScrolling: false } });
129162

@@ -137,7 +170,7 @@ const getDebouncedScrollEnd = (() => {
137170
if (currentDebounceTime !== lastDebounceTime || !debouncedFn) {
138171
lastDebounceTime = currentDebounceTime;
139172
debouncedFn = debounce(() => {
140-
isScrolling = false;
173+
globalIsScrolling = false;
141174
// Set pointer-events back to all when not scrolling
142175
document.documentElement.style.setProperty('--embeddable-pointer-events', 'all');
143176
// Dispatch event with updated scrolling state
@@ -153,16 +186,23 @@ export const lockEmbeddables = (appState?: AppState) => {
153186
// Get the debounce time from settings, with fallback to default
154187
const debounceTime = appState?.pad?.userSettings?.embedLockDebounceTime || 350;
155188

156-
if (!isScrolling) {
157-
isScrolling = true;
158-
// Set pointer-events to none during scrolling
189+
// Check if hand tool is active
190+
const handToolActive = appState?.activeTool?.type === "hand";
191+
192+
if (!globalIsScrolling) {
193+
globalIsScrolling = true;
194+
// Set pointer-events to none during scrolling or when hand tool is active
159195
document.documentElement.style.setProperty('--embeddable-pointer-events', 'none');
160196
// Dispatch event with updated scrolling state
161197
scrollStateChangeEvent.detail.isScrolling = true;
162198
document.dispatchEvent(scrollStateChangeEvent);
163199
}
164200

165-
// Get the current debounced function and call it
166-
const debouncedScrollEnd = getDebouncedScrollEnd(debounceTime);
167-
debouncedScrollEnd();
201+
// If hand tool is not active, use debounce to unlock after scrolling stops
202+
// If hand tool is active, we don't want to unlock
203+
if (!handToolActive) {
204+
// Get the current debounced function and call it
205+
const debouncedScrollEnd = getDebouncedScrollEnd(debounceTime);
206+
debouncedScrollEnd();
207+
}
168208
};

0 commit comments

Comments
 (0)