feat: initial commit - Jhonny Editor
- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
This commit is contained in:
+124
@@ -0,0 +1,124 @@
|
||||
export type OnboardingEvent =
|
||||
| "marketing_viewed"
|
||||
| "primary_cta_clicked"
|
||||
| "onboarding_assistant_selected"
|
||||
| "onboarding_download_started"
|
||||
| "onboarding_safe_prompt_copied"
|
||||
| "onboarding_project_intake_prompt_copied"
|
||||
| "onboarding_project_intake_template_selected"
|
||||
| "onboarding_project_intake_template_copied"
|
||||
| "onboarding_workflow_guide_recommendation_viewed"
|
||||
| "onboarding_workflow_guide_prompt_copied"
|
||||
| "onboarding_advanced_opened"
|
||||
| "onboarding_recovery_opened"
|
||||
| "marketing_demo_played"
|
||||
|
||||
type OnboardingEventParameters = Record<string, string>
|
||||
|
||||
const firstTouchStorageKey = "premiere-pro-mcp:first-touch"
|
||||
|
||||
const campaignParameterNames = [
|
||||
"utm_source",
|
||||
"utm_medium",
|
||||
"utm_campaign",
|
||||
"utm_term",
|
||||
"utm_content",
|
||||
] as const
|
||||
|
||||
function campaignParameters(): OnboardingEventParameters {
|
||||
if (typeof window === "undefined") return {}
|
||||
const values: OnboardingEventParameters = {}
|
||||
const search = new URLSearchParams(window.location.search)
|
||||
for (const name of campaignParameterNames) {
|
||||
const value = search.get(name)
|
||||
if (value && value.length <= 80 && /^[a-z0-9._~-]+$/i.test(value)) values[name] = value
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
function sessionCampaignParameters(key: string): OnboardingEventParameters {
|
||||
if (typeof window === "undefined") return {}
|
||||
try {
|
||||
const stored = window.sessionStorage.getItem(key)
|
||||
if (!stored) return {}
|
||||
const parsed = JSON.parse(stored) as unknown
|
||||
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {}
|
||||
|
||||
return Object.fromEntries(
|
||||
campaignParameterNames.flatMap((name) => {
|
||||
const value = (parsed as Record<string, unknown>)[name]
|
||||
return typeof value === "string" && value.length <= 80 && /^[a-z0-9._~-]+$/i.test(value)
|
||||
? [[name, value]]
|
||||
: []
|
||||
}),
|
||||
)
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
function attributionParameters(): OnboardingEventParameters {
|
||||
const latestTouch = campaignParameters()
|
||||
let firstTouch = sessionCampaignParameters(firstTouchStorageKey)
|
||||
|
||||
if (!Object.keys(firstTouch).length && Object.keys(latestTouch).length) {
|
||||
firstTouch = latestTouch
|
||||
try {
|
||||
window.sessionStorage.setItem(firstTouchStorageKey, JSON.stringify(firstTouch))
|
||||
} catch {
|
||||
// Private browsing and restrictive browser settings can disable storage.
|
||||
// Analytics remains optional, so continue without durable attribution.
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...firstTouch,
|
||||
...Object.fromEntries(Object.entries(latestTouch).map(([name, value]) => [`latest_${name}`, value])),
|
||||
}
|
||||
}
|
||||
|
||||
function analyticsPermitted() {
|
||||
if (typeof window === "undefined") return false
|
||||
const nav = navigator as Navigator & { globalPrivacyControl?: boolean }
|
||||
return !["1", "yes"].includes(nav.doNotTrack ?? "") && !nav.globalPrivacyControl
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
dataLayer?: unknown[]
|
||||
gtag?: (...args: unknown[]) => void
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Records only route and action names. Prompts, project details, media names,
|
||||
* file paths, and other editor content must never be passed to this helper.
|
||||
*/
|
||||
export function trackOnboardingEvent(
|
||||
eventName: OnboardingEvent,
|
||||
parameters: OnboardingEventParameters = {},
|
||||
) {
|
||||
if (!analyticsPermitted()) return
|
||||
const safeParameters = {
|
||||
product: "premiere-pro-mcp",
|
||||
event: eventName,
|
||||
occurred_at: new Date().toISOString(),
|
||||
path: window.location.pathname,
|
||||
...attributionParameters(),
|
||||
...parameters,
|
||||
}
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("premiere-pro-mcp:onboarding", {
|
||||
detail: { eventName, parameters: safeParameters },
|
||||
}),
|
||||
)
|
||||
// The external analytics loader is intentionally deferred. Keep a tiny local
|
||||
// queue so a first CTA is retained without placing inline executable code in
|
||||
// the document or forcing a third-party script into the critical path.
|
||||
window.dataLayer = window.dataLayer ?? []
|
||||
window.gtag = window.gtag ?? ((...args: unknown[]) => {
|
||||
window.dataLayer?.push(args)
|
||||
})
|
||||
window.gtag("event", eventName, safeParameters)
|
||||
}
|
||||
Reference in New Issue
Block a user