Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/frontend/src/CustomEmbeddableRenderer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@
&.visible {
opacity: 1;
}

&__text {
margin-left: 4px;
font-size: 12px;
font-weight: 600;
font-family: 'Roboto', sans-serif;
color: #afafaf;
opacity: 0.7;
}
}

&__content {
Expand Down
72 changes: 57 additions & 15 deletions src/frontend/src/CustomEmbeddableRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const renderCustomEmbeddable = (
<div className="custom-embed">
<div className="custom-embed__title-bar">
<div className="custom-embed__title-bar__text">{title}</div>
<LockIndicator />
<LockIndicator appState={appState} />
</div>
<div className="custom-embed__content">
{content}
Expand All @@ -87,7 +87,7 @@ export const renderCustomEmbeddable = (
<div className="custom-embed">
<div className="custom-embed__title-bar">
<div className="custom-embed__title-bar__text">{title}</div>
<LockIndicator />
<LockIndicator appState={appState} />
</div>
<div className="custom-embed__content">
<iframe className="custom-embed__content--iframe" src={element.link} />
Expand All @@ -97,13 +97,15 @@ export const renderCustomEmbeddable = (
}
};

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

// Effect to handle scroll state changes
useEffect(() => {
const handleScrollStateChange = (event: CustomEvent<{ isScrolling: boolean }>) => {
setVisible(event.detail.isScrolling);
setIsScrolling(event.detail.isScrolling);
};

// Add event listener for scroll state changes
Expand All @@ -115,15 +117,48 @@ const LockIndicator = () => {
};
}, []);

// Separate effect to handle hand tool state changes
useEffect(() => {
// Check hand tool state
const handToolActive = appState?.activeTool?.type === "hand";
const wasHandToolActive = isHandToolActive;
setIsHandToolActive(handToolActive);

// If hand tool was active but is now deactivated
if (wasHandToolActive && !handToolActive) {
// Force reset of global scrolling state
globalIsScrolling = false;
document.documentElement.style.setProperty('--embeddable-pointer-events', 'all');

// Dispatch event to update all components
scrollStateChangeEvent.detail.isScrolling = false;
document.dispatchEvent(scrollStateChangeEvent);

// Update component state
setIsScrolling(false);
} else if (handToolActive) {
// Set pointer-events to none when hand tool is active
document.documentElement.style.setProperty('--embeddable-pointer-events', 'none');
}
}, [appState]);

// Determine if the lock should be visible
const visible = isScrolling || isHandToolActive;

return (
<div className={`custom-embed__lock-icon ${visible ? 'visible' : ''}`}>
<Lock size={16} />
{isHandToolActive && (
<span className="custom-embed__lock-icon__text visible">
(Hand tool)
</span>
)}
</div>
);
};

// Track scrolling state
let isScrolling = false;
// Track scrolling state globally
let globalIsScrolling = false;
// Create a custom event for scrolling state changes
const scrollStateChangeEvent = new CustomEvent('scrollStateChange', { detail: { isScrolling: false } });

Expand All @@ -137,7 +172,7 @@ const getDebouncedScrollEnd = (() => {
if (currentDebounceTime !== lastDebounceTime || !debouncedFn) {
lastDebounceTime = currentDebounceTime;
debouncedFn = debounce(() => {
isScrolling = false;
globalIsScrolling = false;
// Set pointer-events back to all when not scrolling
document.documentElement.style.setProperty('--embeddable-pointer-events', 'all');
// Dispatch event with updated scrolling state
Expand All @@ -153,16 +188,23 @@ export const lockEmbeddables = (appState?: AppState) => {
// Get the debounce time from settings, with fallback to default
const debounceTime = appState?.pad?.userSettings?.embedLockDebounceTime || 350;

if (!isScrolling) {
isScrolling = true;
// Set pointer-events to none during scrolling
// Check if hand tool is active
const handToolActive = appState?.activeTool?.type === "hand";

if (!globalIsScrolling) {
globalIsScrolling = true;
// Set pointer-events to none during scrolling or when hand tool is active
document.documentElement.style.setProperty('--embeddable-pointer-events', 'none');
// Dispatch event with updated scrolling state
scrollStateChangeEvent.detail.isScrolling = true;
document.dispatchEvent(scrollStateChangeEvent);
}

// Get the current debounced function and call it
const debouncedScrollEnd = getDebouncedScrollEnd(debounceTime);
debouncedScrollEnd();
// If hand tool is not active, use debounce to unlock after scrolling stops
// If hand tool is active, we don't want to unlock
if (!handToolActive) {
// Get the current debounced function and call it
const debouncedScrollEnd = getDebouncedScrollEnd(debounceTime);
debouncedScrollEnd();
}
};