diff --git a/apps/yaak-client/components/CommercialUseBanner.tsx b/apps/yaak-client/components/CommercialUseBanner.tsx index ea96168f..0290b058 100644 --- a/apps/yaak-client/components/CommercialUseBanner.tsx +++ b/apps/yaak-client/components/CommercialUseBanner.tsx @@ -2,9 +2,13 @@ import { invoke } from "@tauri-apps/api/core"; import { openUrl } from "@tauri-apps/plugin-opener"; import type { LicenseCheckStatus } from "@yaakapp-internal/license"; import { useEffect, useState } from "react"; +import { useKeyValue } from "../hooks/useKeyValue"; import { appInfo } from "../lib/appInfo"; +import { pricingUrl } from "../lib/pricingUrl"; import { DismissibleBanner } from "./core/DismissibleBanner"; +const COMMERCIAL_USE_SNOOZE_DAYS = 7; + export function CommercialUseBanner({ children, source, @@ -15,6 +19,15 @@ export function CommercialUseBanner({ title: string; }) { const [visible, setVisible] = useState(false); + const { + isLoading: isSnoozeLoading, + set: setSnoozedAt, + value: snoozedAt, + } = useKeyValue({ + namespace: "global", + key: "commercial-use-banner-snoozed-at", + fallback: null, + }); useEffect(() => { let canceled = false; @@ -30,19 +43,25 @@ export function CommercialUseBanner({ }; }, [source]); - if (!visible) return null; + if ( + !visible || + isSnoozeLoading || + isWithinDays(snoozedAt, COMMERCIAL_USE_SNOOZE_DAYS) + ) { + return null; + } return (
setSnoozedAt(new Date().toISOString())} actions={[ { label: "View plans", - color: "primary", + color: "info", variant: "solid", onClick: () => { openCommercialUsePricing(source).catch(console.error); @@ -75,5 +94,14 @@ async function shouldShowCommercialUsePrompt(): Promise { } async function openCommercialUsePricing(source: string): Promise { - await openUrl(`https://yaak.app/pricing?s=${source}&ref=app.yaak.desktop`).catch(console.error); + await openUrl(pricingUrl(`app.commercial-use.${source}`)).catch(console.error); +} + +function isWithinDays(date: string | null, days: number): boolean { + if (date == null) return false; + + const time = new Date(date).getTime(); + if (Number.isNaN(time)) return false; + + return Date.now() - time < days * 24 * 60 * 60 * 1000; } diff --git a/apps/yaak-client/components/Settings/SettingsInterface.tsx b/apps/yaak-client/components/Settings/SettingsInterface.tsx index 1bfc92d2..764ab1e4 100644 --- a/apps/yaak-client/components/Settings/SettingsInterface.tsx +++ b/apps/yaak-client/components/Settings/SettingsInterface.tsx @@ -8,6 +8,7 @@ import { useAtomValue } from "jotai"; import { useState } from "react"; import { activeWorkspaceAtom } from "../../hooks/useActiveWorkspace"; import { showConfirm } from "../../lib/confirm"; +import { pricingUrl } from "../../lib/pricingUrl"; import { invokeCmd } from "../../lib/tauri"; import { CargoFeature } from "../CargoFeature"; import { Button } from "../core/Button"; @@ -252,7 +253,9 @@ function LicenseSettings({ settings }: { settings: Settings }) {

Licenses help keep Yaak independent and sustainable.{" "} - Purchase a License → + + Purchase a License → +

), diff --git a/apps/yaak-client/components/Settings/SettingsLicense.tsx b/apps/yaak-client/components/Settings/SettingsLicense.tsx index fc246efc..baa4bd6d 100644 --- a/apps/yaak-client/components/Settings/SettingsLicense.tsx +++ b/apps/yaak-client/components/Settings/SettingsLicense.tsx @@ -6,6 +6,7 @@ import { formatDate } from "date-fns/format"; import { useState } from "react"; import { useToggle } from "../../hooks/useToggle"; import { pluralizeCount } from "../../lib/pluralize"; +import { pricingUrl } from "../../lib/pricingUrl"; import { CargoFeature } from "../CargoFeature"; import { Button } from "../core/Button"; import { Link } from "../core/Link"; @@ -48,7 +49,7 @@ function SettingsLicenseCmp() { Personal use is always free, forever.
- + Learn More
@@ -68,7 +69,7 @@ function SettingsLicenseCmp() {
- + Learn More
@@ -134,7 +135,7 @@ function SettingsLicenseCmp() {