diff --git a/apps/desktop/layer/renderer/src/modules/app/EnvironmentIndicator.tsx b/apps/desktop/layer/renderer/src/modules/app/EnvironmentIndicator.tsx index 262f30a93..ec4e8f394 100644 --- a/apps/desktop/layer/renderer/src/modules/app/EnvironmentIndicator.tsx +++ b/apps/desktop/layer/renderer/src/modules/app/EnvironmentIndicator.tsx @@ -19,7 +19,7 @@ import { featureConfigMap } from "~/lib/features" import { DebugRegistry } from "../debug/registry" -const EnvironmentDebugModalContent = () => { +export const EnvironmentDebugModalContent = () => { const actionMap = DebugRegistry.getAll() const debugValues = useDebugFeatureValue() as Record const setDebugValues = useSetDebugFeatureValue() diff --git a/apps/desktop/layer/renderer/src/modules/settings/tabs/about.tsx b/apps/desktop/layer/renderer/src/modules/settings/tabs/about.tsx index 3ec43c5cd..0e5dd3abd 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/tabs/about.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/tabs/about.tsx @@ -7,16 +7,19 @@ import { getCurrentEnvironment } from "@follow/utils/environment" import { cn } from "@follow/utils/utils" import PKG, { repository } from "@pkg" import { useQuery } from "@tanstack/react-query" -import { useState } from "react" +import { useEffect, useRef, useState } from "react" import { Trans, useTranslation } from "react-i18next" import { toast } from "sonner" +import { useModalStack } from "~/components/ui/modal/stacked/hooks" import { ipcServices } from "~/lib/client" import { getNewIssueUrl } from "~/lib/issues" +import { EnvironmentDebugModalContent } from "~/modules/app/EnvironmentIndicator" export const SettingAbout = () => { const { t } = useTranslation("settings") const [isCheckingUpdate, setIsCheckingUpdate] = useState(false) + const { present } = useModalStack() const currentEnvironment = getCurrentEnvironment().join("\n") const { data: appVersion } = useQuery({ queryKey: ["appVersion"], @@ -24,6 +27,17 @@ export const SettingAbout = () => { }) const rendererVersion = PKG.version + const rendererClickCountRef = useRef(0) + const rendererClickResetTimerRef = useRef(null) + const lastRendererClickTimestampRef = useRef(0) + + useEffect(() => { + return () => { + if (rendererClickResetTimerRef.current) { + window.clearTimeout(rendererClickResetTimerRef.current) + } + } + }, []) const handleCheckForUpdates = async () => { if (isCheckingUpdate) return @@ -48,6 +62,40 @@ export const SettingAbout = () => { } } + const handleRendererVersionClick = () => { + if (!rendererVersion) return + + const now = Date.now() + if (now - lastRendererClickTimestampRef.current > 800) { + rendererClickCountRef.current = 0 + } + + rendererClickCountRef.current += 1 + lastRendererClickTimestampRef.current = now + + if (rendererClickResetTimerRef.current) { + window.clearTimeout(rendererClickResetTimerRef.current) + } + + rendererClickResetTimerRef.current = window.setTimeout(() => { + rendererClickCountRef.current = 0 + rendererClickResetTimerRef.current = null + }, 800) + + if (rendererClickCountRef.current >= 10) { + rendererClickCountRef.current = 0 + if (rendererClickResetTimerRef.current) { + window.clearTimeout(rendererClickResetTimerRef.current) + rendererClickResetTimerRef.current = null + } + + present({ + title: "Debug Actions", + content: EnvironmentDebugModalContent, + }) + } + } + const handleOpenLegal = (type: "privacy" | "tos") => { const path = type === "privacy" ? "privacy-policy" : "terms-of-service" window.open(`https://folo.is/${path}`, "_blank") @@ -80,10 +128,14 @@ export const SettingAbout = () => { )} {rendererVersion && ( - + )}