Compare commits

...
Author SHA1 Message Date
Brandon Thomas cb8c1c7fb9 Google Analytics package and events 2025-07-22 19:11:25 -04:00
19 changed files with 227 additions and 53 deletions
@@ -1,6 +1,7 @@
import { authentication } from "./authentication";
import { UsersApi } from "~/Classes/ApiManager/UsersApi";
import { BillingApi } from "~/Classes/ApiManager/BillingApi";
import { gtagLogin, gtagLogout } from "@storyteller/google-analytics";
import {
updateActiveSubscriptions,
@@ -23,6 +24,7 @@ export const logout = async (
// if success, nothing
// regarldess of success/fail, clear the state and localstorage
setLogoutStates();
gtagLogout();
};
export const login = async ({
@@ -114,6 +116,11 @@ async function getUserInfoAndSubcriptions() {
updateAuthStatus(AUTH_STATUS.NO_ACCESS);
return;
}
const userToken = sessionResponse.data.user.user_token;
if (!!userToken) {
gtagLogin(userToken);
}
const billingApi = new BillingApi();
const subscriptionsResponse = await billingApi.ListActiveSubscriptions();
-33
View File
@@ -1,33 +0,0 @@
[build]
command = "./apps/editor3d/script/netlify_build.sh"
publish = "apps/editor3d/dist/"
[build.environment]
REACT_APP_PUBLIC_POSTHOG_KEY = "phc_jBFgac0mVALAFk3negnSfYCcHgvkT00yBLQDmCDYNBb"
REACT_APP_PUBLIC_POSTHOG_UI = "https://us.i.posthog.com"
#[dev]
#command = "npm run dev"
#framework = "vite"
# Set immutable caching for static files, because they have fingerprinted filenames
[[headers]]
for = "/build/*"
[headers.values]
"Cache-Control" = "public, max-age=31560000, immutable"
[[redirects]]
from = "/ingest/static/*"
to = "https://us-assets.i.posthog.com/static/:splat"
host = "us-assets.i.posthog.com"
status = 200
force = true
[[redirects]]
from = "/ingest/*"
to = "https://us.i.posthog.com/:splat"
host = "us.i.posthog.com"
status = 200
force = true
+3
View File
@@ -144,6 +144,9 @@
},
{
"path": "../../libs/api"
},
{
"path": "../../libs/analytics/google-analytics"
}
]
}
@@ -0,0 +1,50 @@
{
"extends": [
"../../../.eslintrc.json"
],
"ignorePatterns": [
"!**/*"
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx"
],
"rules": {}
},
{
"files": [
"*.ts",
"*.tsx"
],
"rules": {}
},
{
"files": [
"*.js",
"*.jsx"
],
"rules": {}
},
{
"files": [
"*.json"
],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/dependency-checks": [
"error",
{
"ignoredFiles": [
"{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}",
"{projectRoot}/vite.config.{js,ts,mjs,mts}"
]
}
]
}
}
]
}
@@ -0,0 +1,7 @@
# google-analytics
This library was generated with [Nx](https://nx.dev).
## Building
Run `nx build google-analytics` to build the library.
@@ -0,0 +1,19 @@
{
"name": "@storyteller/google-analytics",
"version": "0.0.1",
"private": true,
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"development": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
}
},
"dependencies": {}
}
@@ -0,0 +1,4 @@
export * from './lib/gtag-login.js';
export * from './lib/gtag-logout.js';
export * from './lib/gtag-event.js';
@@ -0,0 +1,10 @@
// Send an event with name and "args". Args is a string-to-string map.
export const gtagEvent = function(eventName: string, args?: { [key: string]: string }) {
console.debug("gtagEvent", eventName, args);
if (!args) {
(window as any).gtag('event', eventName);
} else {
(window as any).gtag('event', eventName, args);
}
}
@@ -0,0 +1,10 @@
import { TAG_ID } from './tag-id.js';
export const gtagLogin = function(userToken: string) {
console.debug("gtagLogin", TAG_ID, userToken);
(window as any).gtag(
'config', TAG_ID, {
'user_id': userToken
});
}
@@ -0,0 +1,10 @@
import { TAG_ID } from './tag-id.js';
export const gtagLogout = function() {
console.debug("gtagLogout", TAG_ID);
(window as any).gtag(
'config', TAG_ID, {
'user_id': null
});
}
@@ -0,0 +1 @@
export const TAG_ID = 'G-Y4Y8KMLPQ7';
@@ -0,0 +1,10 @@
{
"extends": "../../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}
@@ -0,0 +1,21 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": ".",
"rootDir": "src",
"outDir": "dist",
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
"emitDeclarationOnly": true,
"module": "nodenext",
"moduleResolution": "nodenext",
"forceConsistentCasingInFileNames": true,
"types": [
"node",
"vite/client"
]
},
"include": [
"src/**/*.ts"
],
"references": []
}
@@ -0,0 +1,37 @@
/// <reference types='vitest' />
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import * as path from 'path';
export default defineConfig(() => ({
root: __dirname,
cacheDir: '../../../node_modules/.vite/libs/analytics/google-analytics',
plugins: [dts({ entryRoot: 'src', tsconfigPath: path.join(__dirname, 'tsconfig.lib.json') })],
// Uncomment this if you are using workers.
// worker: {
// plugins: [ nxViteTsPaths() ],
// },
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
build: {
outDir: './dist',
emptyOutDir: true,
reportCompressedSize: true,
commonjsOptions: {
transformMixedEsModules: true,
},
lib: {
// Could also be a dictionary or array of multiple entry points.
entry: 'src/index.ts',
name: '@storyteller/google-analytics',
fileName: 'index',
// Change this to the formats you want to support.
// Don't forget to update your package.json as well.
formats: ['es' as const]
},
rollupOptions: {
// External packages that should not be bundled into your library.
external: []
},
},
}));
@@ -46,6 +46,7 @@ import {
// import { showActionReminder } from "@storyteller/ui-action-reminder-modal";
// import { invoke } from "@tauri-apps/api/core";
import { usePrompt2DStore, RefImage } from "./promptStore";
import { gtagEvent } from "@storyteller/google-analytics";
export type AspectRatio = "1:1" | "3:2" | "2:3";
@@ -397,6 +398,8 @@ export const PromptBox2D = ({
}
}
gtagEvent("enqueue_2d");
if (isEnqueueing) return;
setIsEnqueueing(true);
if (!prompt.trim()) return;
@@ -52,6 +52,7 @@ import {
} from "@storyteller/tauri-api";
// import { showActionReminder } from "@storyteller/ui-action-reminder-modal";
import { usePrompt3DStore, RefImage } from "./promptStore";
import { gtagEvent } from "@storyteller/google-analytics";
interface PromptBox3DProps {
cameras: Signal<Camera[]>;
@@ -316,6 +317,7 @@ export const PromptBox3D = ({
};
const handleEnqueue = async () => {
gtagEvent("enqueue_3d");
const isDesktop = IsDesktopApp();
console.log("Is Desktop?", isDesktop);
if (isDesktop) {
+9
View File
@@ -76,6 +76,7 @@
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"ajv": "^8.0.0",
"autoprefixer": "10.4.13",
"eslint": "~8.57.0",
"eslint-config-prettier": "^10.0.0",
@@ -1147,6 +1148,10 @@
"version": "0.0.1",
"extraneous": true
},
"libs/analytics/google-analytics": {
"name": "@storyteller/google-analytics",
"version": "0.0.1"
},
"libs/api": {
"name": "@storyteller/api",
"version": "0.0.1",
@@ -9413,6 +9418,10 @@
"resolved": "libs/common",
"link": true
},
"node_modules/@storyteller/google-analytics": {
"resolved": "libs/analytics/google-analytics",
"link": true
},
"node_modules/@storyteller/model-list": {
"resolved": "libs/model-list",
"link": true
+21 -20
View File
@@ -8,34 +8,34 @@
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
"@fortawesome/pro-regular-svg-icons": "^6.5.1",
"@fortawesome/pro-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^2.2.2",
"@preact/signals-react": "^3.0.1",
"@remix-run/serve": "^2.15.0",
"dayjs": "^1.11.10",
"detect-gpu": "^5.0.38",
"framer-motion": "^12.11.0",
"konva": "^9.3.20",
"lodash": "^4.17.21",
"lucide-react": "^0.512.0",
"pnpm": "^10.8.1",
"posthog-js": "^1.141.0",
"react": "18.3.1",
"react-copy-to-clipboard": "^5.1.0",
"react-device-detect": "^2.2.3",
"react-dom": "18.3.1",
"react-drag-drop-files": "^2.3.10",
"react-helmet": "^6.1.0",
"react-hot-toast": "^2.5.2",
"react-router-dom": "6.29.0",
"zustand": "^5.0.5",
"tailwind-merge": "^2.2.2",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@fortawesome/pro-solid-svg-icons": "^6.5.1",
"@fortawesome/pro-regular-svg-icons": "^6.5.1",
"react-drag-drop-files": "^2.3.10",
"uuid": "^9.0.1",
"dayjs": "^1.11.10",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
"posthog-js": "^1.141.0",
"lodash": "^4.17.21",
"detect-gpu": "^5.0.38",
"three": "^0.162.0",
"react-copy-to-clipboard": "^5.1.0",
"react-helmet": "^6.1.0",
"konva": "^9.3.20"
"uuid": "^9.0.1",
"zustand": "^5.0.5"
},
"devDependencies": {
"@babel/core": "^7.14.5",
@@ -58,17 +58,18 @@
"@testing-library/jest-dom": "6.4.2",
"@testing-library/react": "16.1.0",
"@testing-library/user-event": "^14.5.2",
"@types/lodash": "^4.14.202",
"@types/node": "^20.0.0",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^7.16.0",
"@typescript-eslint/parser": "^7.16.0",
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"ajv": "^8.0.0",
"autoprefixer": "10.4.13",
"postcss-import": "^16.0.1",
"postcss-nesting": "^12.1.0",
"eslint": "~8.57.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-import": "2.31.0",
@@ -81,6 +82,8 @@
"jsonc-eslint-parser": "^2.1.0",
"nx": "21.2.3",
"postcss": "8.4.38",
"postcss-import": "^16.0.1",
"postcss-nesting": "^12.1.0",
"tailwindcss": "3.4.3",
"tslib": "^2.3.0",
"typescript": "5.8.3",
@@ -89,9 +92,7 @@
"vite-plugin-dts": "~4.5.0",
"vite-plugin-static-copy": "^2.3.1",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.0",
"@types/uuid": "^9.0.8",
"@types/lodash": "^4.14.202"
"vitest": "^3.0.0"
},
"workspaces": [
"apps/**/*",
+3
View File
@@ -146,6 +146,9 @@
},
{
"path": "./libs/model-list"
},
{
"path": "./libs/analytics/google-analytics"
}
]
}