mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-09-18 01:19:24 +00:00
Scarf Fire
This commit is contained in:
parent
e59e73ceb0
commit
cd6652a48d
@ -7,7 +7,6 @@ import { ToolWorkflowProvider } from "./contexts/ToolWorkflowContext";
|
||||
import { SidebarProvider } from "./contexts/SidebarContext";
|
||||
import ErrorBoundary from "./components/shared/ErrorBoundary";
|
||||
import HomePage from "./pages/HomePage";
|
||||
import { ScarfPixel } from "./components/ScarfPixel";
|
||||
|
||||
// Import global styles
|
||||
import "./styles/tailwind.css";
|
||||
@ -37,7 +36,6 @@ export default function App() {
|
||||
<ErrorBoundary>
|
||||
<FileContextProvider enableUrlSync={true} enablePersistence={true}>
|
||||
<NavigationProvider>
|
||||
<ScarfPixel />
|
||||
<FilesModalProvider>
|
||||
<ToolWorkflowProvider>
|
||||
<SidebarProvider>
|
||||
|
@ -1,30 +0,0 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useNavigationState } from "../contexts/NavigationContext";
|
||||
|
||||
export function ScarfPixel() {
|
||||
const { workbench, selectedTool } = useNavigationState();
|
||||
const lastUrlSent = useRef<string | null>(null); // helps with React 18 StrictMode in dev
|
||||
|
||||
useEffect(() => {
|
||||
// Get current pathname from browser location
|
||||
const pathname = window.location.pathname;
|
||||
|
||||
const url = 'https://static.scarf.sh/a.png?x-pxid=3c1d68de-8945-4e9f-873f-65320b6fabf7'
|
||||
+ '&path=' + encodeURIComponent(pathname)
|
||||
+ '&t=' + Date.now(); // cache-buster
|
||||
|
||||
console.log("ScarfPixel: Navigation change", { workbench, selectedTool, pathname });
|
||||
|
||||
if (lastUrlSent.current !== url) {
|
||||
lastUrlSent.current = url;
|
||||
const img = new Image();
|
||||
img.referrerPolicy = "no-referrer-when-downgrade"; // optional
|
||||
img.src = url;
|
||||
|
||||
console.log("ScarfPixel: Fire to... " + pathname, url);
|
||||
}
|
||||
}, [workbench, selectedTool]); // Fire when navigation state changes
|
||||
|
||||
return null; // Nothing visible in UI
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) {
|
||||
const handleToolSelect = useCallback((toolId: string) => {
|
||||
// Set the selected tool and determine the appropriate workbench
|
||||
actions.setSelectedTool(toolId);
|
||||
|
||||
|
||||
// Get the tool from registry to determine workbench
|
||||
const tool = getSelectedTool(toolId);
|
||||
if (tool && tool.workbench) {
|
||||
@ -225,10 +225,7 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) {
|
||||
|
||||
// URL sync for proper tool navigation
|
||||
useNavigationUrlSync(
|
||||
navigationState.workbench,
|
||||
navigationState.selectedTool,
|
||||
actions.setWorkbench,
|
||||
actions.setSelectedTool,
|
||||
handleToolSelect,
|
||||
() => actions.setSelectedTool(null),
|
||||
toolRegistry,
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import { useEffect, useCallback } from 'react';
|
||||
import { WorkbenchType, ToolId, ToolRoute } from '../types/navigation';
|
||||
import { WorkbenchType, ToolId } from '../types/navigation';
|
||||
import { parseToolRoute, updateToolRoute, clearToolRoute } from '../utils/urlRouting';
|
||||
import { ToolRegistry } from '../data/toolsTaxonomy';
|
||||
|
||||
@ -11,10 +11,7 @@ import { ToolRegistry } from '../data/toolsTaxonomy';
|
||||
* Hook to sync workbench and tool with URL using registry
|
||||
*/
|
||||
export function useNavigationUrlSync(
|
||||
workbench: WorkbenchType,
|
||||
selectedTool: ToolId | null,
|
||||
setWorkbench: (workbench: WorkbenchType) => void,
|
||||
setSelectedTool: (toolId: ToolId | null) => void,
|
||||
handleToolSelect: (toolId: string) => void,
|
||||
clearToolSelection: () => void,
|
||||
registry: ToolRegistry,
|
||||
@ -28,7 +25,9 @@ export function useNavigationUrlSync(
|
||||
if (route.toolId !== selectedTool) {
|
||||
if (route.toolId) {
|
||||
handleToolSelect(route.toolId);
|
||||
} else {
|
||||
} else if (selectedTool !== null) {
|
||||
// Only clear selection if we actually had a tool selected
|
||||
// Don't clear on initial load when selectedTool starts as null
|
||||
clearToolSelection();
|
||||
}
|
||||
}
|
||||
@ -41,8 +40,10 @@ export function useNavigationUrlSync(
|
||||
if (selectedTool) {
|
||||
updateToolRoute(selectedTool, registry);
|
||||
} else {
|
||||
// Clear URL when no tool is selected
|
||||
clearToolRoute();
|
||||
// Only clear URL if we're not on the home page already
|
||||
if (window.location.pathname !== '/') {
|
||||
clearToolRoute();
|
||||
}
|
||||
}
|
||||
}, [selectedTool, registry, enableSync]);
|
||||
|
||||
@ -103,4 +104,4 @@ export function useCurrentRoute(registry: ToolRegistry) {
|
||||
}, [registry]);
|
||||
|
||||
return getCurrentRoute;
|
||||
}
|
||||
}
|
||||
|
28
frontend/src/utils/scarfTracking.ts
Normal file
28
frontend/src/utils/scarfTracking.ts
Normal file
@ -0,0 +1,28 @@
|
||||
let lastFiredPathname: string | null = null;
|
||||
let lastFiredTime = 0;
|
||||
|
||||
/**
|
||||
* Fire scarf pixel for analytics tracking
|
||||
* Only fires if pathname is different from last call or enough time has passed
|
||||
*/
|
||||
export function firePixel(pathname: string): void {
|
||||
const now = Date.now();
|
||||
|
||||
// Only fire if pathname changed or it's been at least 1 second since last fire
|
||||
if (pathname === lastFiredPathname && now - lastFiredTime < 250) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastFiredPathname = pathname;
|
||||
lastFiredTime = now;
|
||||
|
||||
const url = 'https://static.scarf.sh/a.png?x-pxid=3c1d68de-8945-4e9f-873f-65320b6fabf7'
|
||||
+ '&path=' + encodeURIComponent(pathname)
|
||||
|
||||
const img = new Image();
|
||||
img.referrerPolicy = "no-referrer-when-downgrade";
|
||||
img.src = url;
|
||||
|
||||
console.log("ScarfPixel: Fire to... " + pathname);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
getDefaultWorkbench
|
||||
} from '../types/navigation';
|
||||
import { ToolRegistry, getToolWorkbench, getToolUrlPath, isValidToolId } from '../data/toolsTaxonomy';
|
||||
import { firePixel } from './scarfTracking';
|
||||
|
||||
/**
|
||||
* Parse the current URL to extract tool routing information
|
||||
@ -44,33 +45,38 @@ export function parseToolRoute(registry: ToolRegistry): ToolRoute {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update URL and fire analytics pixel
|
||||
*/
|
||||
function updateUrl(newPath: string, searchParams: URLSearchParams): void {
|
||||
const currentPath = window.location.pathname;
|
||||
const queryString = searchParams.toString();
|
||||
const fullUrl = newPath + (queryString ? `?${queryString}` : '');
|
||||
|
||||
// Only update URL and fire pixel if something actually changed
|
||||
if (currentPath !== newPath || window.location.search !== (queryString ? `?${queryString}` : '')) {
|
||||
window.history.replaceState(null, '', fullUrl);
|
||||
firePixel(newPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the URL to reflect the current tool selection
|
||||
*/
|
||||
export function updateToolRoute(toolId: ToolId, registry: ToolRegistry): void {
|
||||
const currentPath = window.location.pathname;
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
|
||||
const tool = registry[toolId];
|
||||
if (!tool) {
|
||||
console.warn(`Tool ${toolId} not found in registry`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const newPath = getToolUrlPath(toolId, tool);
|
||||
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
|
||||
// Remove tool query parameter since we're using path-based routing
|
||||
searchParams.delete('tool');
|
||||
|
||||
// Construct final URL
|
||||
const queryString = searchParams.toString();
|
||||
const fullUrl = newPath + (queryString ? `?${queryString}` : '');
|
||||
|
||||
// Update URL without triggering page reload
|
||||
if (currentPath !== newPath || window.location.search !== (queryString ? `?${queryString}` : '')) {
|
||||
window.history.replaceState(null, '', fullUrl);
|
||||
}
|
||||
updateUrl(newPath, searchParams);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,10 +86,7 @@ export function clearToolRoute(): void {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
searchParams.delete('tool');
|
||||
|
||||
const queryString = searchParams.toString();
|
||||
const url = '/' + (queryString ? `?${queryString}` : '');
|
||||
|
||||
window.history.replaceState(null, '', url);
|
||||
updateUrl('/', searchParams);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user