From a11e10418b33973d8e42f64af254d338ab079f67 Mon Sep 17 00:00:00 2001 From: Sparkenstein Date: Mon, 11 Mar 2024 21:42:05 +0530 Subject: [PATCH] feat: basic anon analytics --- package.json | 1 + src-tauri/Cargo.lock | 114 ++++++++++++++++- src-tauri/Cargo.toml | 1 + src-tauri/src/main.rs | 1 + src/App.tsx | 30 ++++- src/Features/hash/FileHash.tsx | 4 + src/Features/random/Random.tsx | 6 +- src/Layout/Navbar/index.tsx | 225 +++++++++++++++++++-------------- src/utils/analytics.ts | 19 +++ yarn.lock | 9 +- 10 files changed, 309 insertions(+), 101 deletions(-) create mode 100644 src/utils/analytics.ts diff --git a/package.json b/package.json index e5487cc..2c0b56f 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "type-check": "tsc" }, "dependencies": { + "@aptabase/tauri": "^0.4.1", "@hello-pangea/dnd": "^16.5.0", "@loadable/component": "^5.16.3", "@mantine/charts": "^7.6.1", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index ff108a3..256e628 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -796,6 +796,7 @@ dependencies = [ "surge-ping", "tauri", "tauri-build", + "tauri-plugin-aptabase", "tauri-plugin-store", "tokio", "webp", @@ -1660,7 +1661,7 @@ dependencies = [ "httpdate", "itoa 1.0.1", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.5", "tokio", "tower-service", "tracing", @@ -2498,6 +2499,17 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_info" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +dependencies = [ + "log", + "serde", + "winapi", +] + [[package]] name = "outref" version = "0.1.0" @@ -4021,6 +4033,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sys-locale" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a11bd9c338fdba09f7881ab41551932ad42e405f61d01e8406baea71c07aee" +dependencies = [ + "js-sys", + "libc", + "wasm-bindgen", + "web-sys", + "windows-sys 0.45.0", +] + [[package]] name = "system-deps" version = "5.0.0" @@ -4155,6 +4180,7 @@ dependencies = [ "serde_repr", "serialize-to-javascript", "state", + "sys-locale", "tar", "tauri-macros", "tauri-runtime", @@ -4228,6 +4254,26 @@ dependencies = [ "tauri-utils", ] +[[package]] +name = "tauri-plugin-aptabase" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd13fa90b8596c69a3201d23fd8040142f13fd21c3d6d1636fbeb6ac53cdb17d" +dependencies = [ + "futures", + "log", + "os_info", + "rand 0.8.5", + "reqwest", + "serde", + "serde_json", + "tauri", + "thiserror", + "time", + "tokio", + "uuid", +] + [[package]] name = "tauri-plugin-store" version = "0.0.0" @@ -5106,6 +5152,15 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -5124,6 +5179,21 @@ dependencies = [ "windows-targets 0.52.0", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -5169,6 +5239,12 @@ dependencies = [ "windows-targets 0.52.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5193,6 +5269,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -5217,6 +5299,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -5241,6 +5329,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -5265,6 +5359,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -5277,6 +5377,12 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -5301,6 +5407,12 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 7aa6ab7..7464ddd 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -36,6 +36,7 @@ oxipng = { version = "9.0", features = [ ], default-features = false } webp = "0.2" base64 = "0.21.7" +tauri-plugin-aptabase = "0.4" [features] default = ["custom-protocol"] diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 2073c8b..195f00c 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -18,6 +18,7 @@ use commands::ping::ping::ping; fn main() { tauri::Builder::default() .plugin(tauri_plugin_store::Builder::default().build()) + .plugin(tauri_plugin_aptabase::Builder::new("A-EU-0242299228").build()) .invoke_handler(tauri::generate_handler![ hash, ping, diff --git a/src/App.tsx b/src/App.tsx index 2834c74..1b5bc2d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -24,6 +24,7 @@ import Nums from "./Features/number-tools/Nums"; import { data, Navbar } from "./Layout/Navbar"; import { Settings } from "./Layout/Settings"; import { useDisclosure, useWindowEvent } from "@mantine/hooks"; +import { trackOtherEvent, trackPageView } from "./utils/analytics"; // Lazy load components const Welcome = loadable(() => import("./Components/Welcome")); @@ -84,6 +85,14 @@ const shortCuts = [ key: "mod + b", action: "toggle sidebar collapse", }, + { + key: "(mod + k) + (mod + d)", + action: "editor dark theme, anywhere", + }, + { + key: "(mod + k) + (mod + l)", + action: "editor light theme, anywhere", + }, ]; function App() { @@ -109,14 +118,26 @@ function App() { } }, []); + useEffect(() => { + trackPageView(location.pathname); + }, [location]); + const listener = (e: KeyboardEvent) => { if (e.shiftKey && e.key === "?") { + trackOtherEvent("shortcut", { + key: "shift + ?", + action: "open-shortcut", + }); open(); } if (e.key === "Escape") { close(); } if (e.ctrlKey && e.key === "t") { + trackOtherEvent("shortcut", { + key: "mod + t", + action: "toggle-theme", + }); toggleColorScheme(); } }; @@ -195,7 +216,14 @@ function App() { actions={data.map((a) => ({ id: a.to, label: a.text, - onClick: () => nav(a.to), + onClick: () => { + trackOtherEvent("shortcut", { + key: "mod + k", + action: "spotlight-search", + to: a.to, + }); + nav(a.to); + }, icon: a.icon, }))} > diff --git a/src/Features/hash/FileHash.tsx b/src/Features/hash/FileHash.tsx index c66e294..0f7eb4c 100644 --- a/src/Features/hash/FileHash.tsx +++ b/src/Features/hash/FileHash.tsx @@ -1,6 +1,7 @@ import { Button, Group, LoadingOverlay, Stack, Table } from "@mantine/core"; import { dialog, invoke } from "@tauri-apps/api"; import { useState } from "react"; +import { trackOtherEvent } from "../../utils/analytics"; const FileHash = () => { const [fileHashes, setFileHashes] = useState< @@ -28,6 +29,9 @@ const FileHash = () => { ); console.timeEnd("t1"); setLoading(false); + trackOtherEvent("file_hash", { + files: filePaths.length, + }); }; return ( diff --git a/src/Features/random/Random.tsx b/src/Features/random/Random.tsx index 4848a56..dab2d67 100644 --- a/src/Features/random/Random.tsx +++ b/src/Features/random/Random.tsx @@ -163,11 +163,7 @@ const Random = () => { Entropy: {pass.entropy} - Note: entropy calculation might be broken. - - - And even if it's correct, entropy is not everything do not rely on - it + note: entropy is not everything do not rely on it ); diff --git a/src/Layout/Navbar/index.tsx b/src/Layout/Navbar/index.tsx index c3993b0..c0cb565 100644 --- a/src/Layout/Navbar/index.tsx +++ b/src/Layout/Navbar/index.tsx @@ -9,7 +9,7 @@ import { TextInput, Tooltip, } from "@mantine/core"; -import { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useContext, useEffect, useState } from "react"; import { BsFilePdf, BsSortNumericUpAlt } from "react-icons/bs"; import { FaCode, @@ -57,9 +57,22 @@ import { Droppable, OnDragEndResponder, } from "@hello-pangea/dnd"; -import { useWindowEvent } from "@mantine/hooks"; +import { + useDebouncedState, + useDebouncedValue, + useWindowEvent, +} from "@mantine/hooks"; +import { trackButtonClick, trackOtherEvent } from "../../utils/analytics"; + +type NavItem = { + id: string; + to: string; + icon: React.ReactNode; + text: string; + extra?: string; +}; -export const data = [ +export const data: NavItem[] = [ { id: "json-formatter", to: "/json-formatter", @@ -191,21 +204,11 @@ export const data = [ export const Navbar = ({ openSettings }: any) => { const location = useLocation(); const nav = useNavigate(); - const [navItems, setNavItems] = useState([]); + const [navItems, setNavItems] = useState([]); const { pinned, handleState } = useContext(AppContext); const [iconMode, setIconMode] = useState(false); - - const filterItems = (e: ChangeEvent) => { - if (e.target.value) { - setNavItems( - data.filter((i) => - i.text.toLowerCase().includes(e.target.value.toLowerCase()) - ) - ); - } else { - setNavItems([...data]); - } - }; + const [search, setSearch] = useState(""); + const [debouncedSearch] = useDebouncedValue(search, 300); useEffect(() => { async function pinnedItems() { @@ -216,6 +219,12 @@ export const Navbar = ({ openSettings }: any) => { pinnedItems(); }, []); + useEffect(() => { + if (debouncedSearch) { + trackOtherEvent("navbar-search", { search: debouncedSearch }); + } + }, [debouncedSearch]); + useEffect(() => { async function sidebar() { const savedSidebaritems = (await db.get("sidebar")) || []; @@ -270,6 +279,10 @@ export const Navbar = ({ openSettings }: any) => { const items = [...navItems]; const [reorderedItem] = items.splice(res.source.index, 1); items.splice(res.destination!.index, 0, reorderedItem); + trackOtherEvent("navbar-reorder", { + fromItem: res.source.index, + toItem: res.destination!.index, + }); setNavItems(items); db.set( "sidebar", @@ -280,6 +293,10 @@ export const Navbar = ({ openSettings }: any) => { const listener = (e: KeyboardEvent) => { if (e.ctrlKey && e.key === "b") { + trackOtherEvent("shortcut", { + key: "mod + b", + action: "toggle-sidebar-collapse", + }); setIconMode(!iconMode); } }; @@ -297,14 +314,22 @@ export const Navbar = ({ openSettings }: any) => { id="search" placeholder="Search..." size={"xs"} - onChange={filterItems} + value={search} + onChange={(e) => setSearch(e.currentTarget.value)} className={classes.textInput} + miw={180} /> )} setIconMode(!iconMode)} + onClick={() => { + trackButtonClick({ + name: "toggle-icon-mode", + value: !iconMode, + }); + setIconMode(!iconMode); + }} > {iconMode ? : } @@ -321,7 +346,13 @@ export const Navbar = ({ openSettings }: any) => { openSettings(true)} + onClick={() => { + trackButtonClick({ + name: "open-settings", + value: true, + }); + openSettings(true); + }} > @@ -336,40 +367,61 @@ export const Navbar = ({ openSettings }: any) => { {(provided) => (
- {navItems.map((e, index) => { - const pinExists = pinned?.includes(e.id); + {navItems + .filter((n) => + n.text + .toLowerCase() + .includes(debouncedSearch.toLowerCase()) + ) + .map((e, index) => { + const pinExists = pinned?.includes(e.id); - return ( - - {(provided) => ( -
- { - nav(e.to); + return ( + + {(provided) => ( +
- - - {e.icon} - - {e.extra ? ( - + { + nav(e.to); + }} + > + + + {e.icon} + + {e.extra ? ( + + + {e.text.toUpperCase()} + + + ) : ( { ? "500" : "400" } - c="red" - component={Link} - to={e.to} > {e.text.toUpperCase()} - - ) : ( - - {e.text.toUpperCase()} - - )} - - - { - e2.stopPropagation(); - onPinClicked(e); - }} - > - {pinExists ? ( - - ) : ( - )} - + + + { + e2.stopPropagation(); + onPinClicked(e); + }} + > + {pinExists ? ( + + ) : ( + + )} + + - -
- )} -
- ); - })} +
+ )} +
+ ); + })} {provided.placeholder}
)} diff --git a/src/utils/analytics.ts b/src/utils/analytics.ts new file mode 100644 index 0000000..d044d24 --- /dev/null +++ b/src/utils/analytics.ts @@ -0,0 +1,19 @@ +import { trackEvent } from "@aptabase/tauri"; + +function trackPageView(page: string) { + trackEvent("page_view", { page }); +} + +function trackButtonClick(data: Record) { + trackEvent("button_click", { ...data }); +} + +function trackError(error: string) { + trackEvent("error", { error }); +} + +function trackOtherEvent(event: string, data: any) { + trackEvent(event, data); +} + +export { trackPageView, trackButtonClick, trackError, trackOtherEvent }; diff --git a/yarn.lock b/yarn.lock index 861491f..afa25e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,13 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" +"@aptabase/tauri@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@aptabase/tauri/-/tauri-0.4.1.tgz#90c74bae004c9588a034ee3b7b2a8f23997091de" + integrity sha512-ZjCtPN1Tw0y90nxMLR64UqFjgikxfc9NZouxqXlqZFkfpF8D/tPf1xUn0Anu8nvERGND/hAkO3x7ZLyLGI1HRg== + dependencies: + "@tauri-apps/api" "^1.0.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" @@ -1678,7 +1685,7 @@ resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a" integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== -"@tauri-apps/api@1.5.3", "@tauri-apps/api@^1.5.3": +"@tauri-apps/api@1.5.3", "@tauri-apps/api@^1.0.0", "@tauri-apps/api@^1.5.3": version "1.5.3" resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.5.3.tgz#f7b362b1f30aadb0a8bbeb7ae111755c0ed33d73" integrity sha512-zxnDjHHKjOsrIzZm6nO5Xapb/BxqUq1tc7cGkFXsFkGTsSWgCPH1D8mm0XS9weJY2OaR73I3k3S+b7eSzJDfqA==