From 6c79c1ef3f940bc67c7527155641cd7ba06ff984 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 29 Sep 2025 15:40:15 -0700 Subject: [PATCH] Rework licensing flows to be more friendly --- src-tauri/capabilities/capabilities.json | 1 + src-tauri/static/greg.jpeg | Bin 0 -> 10775 bytes src-tauri/tauri.conf.json | 4 +- src-tauri/yaak-license/src/license.rs | 1 + src-tauri/yaak-models/bindings/gen_models.ts | 2 +- .../20250929132954_dismiss-license-badge.sql | 10 +++ src-tauri/yaak-models/src/models.rs | 4 + src-tauri/yaak-models/src/queries/settings.rs | 1 + src-web/components/LicenseBadge.tsx | 19 ++--- src-web/components/LocalImage.tsx | 33 ++++++++ src-web/components/Settings/Settings.tsx | 12 +-- .../components/Settings/SettingsInterface.tsx | 29 +++++++ .../components/Settings/SettingsLicense.tsx | 80 ++++++++---------- src-web/components/core/Icon.tsx | 1 + src-web/hooks/useLicenseConfirmation.ts | 15 ---- 15 files changed, 133 insertions(+), 79 deletions(-) create mode 100644 src-tauri/static/greg.jpeg create mode 100644 src-tauri/yaak-models/migrations/20250929132954_dismiss-license-badge.sql create mode 100644 src-web/components/LocalImage.tsx delete mode 100644 src-web/hooks/useLicenseConfirmation.ts diff --git a/src-tauri/capabilities/capabilities.json b/src-tauri/capabilities/capabilities.json index 3eca9861..b77c0d6f 100644 --- a/src-tauri/capabilities/capabilities.json +++ b/src-tauri/capabilities/capabilities.json @@ -11,6 +11,7 @@ "core:event:allow-emit", "core:event:allow-listen", "core:event:allow-unlisten", + "core:path:allow-resolve-directory", "os:allow-os-type", "clipboard-manager:allow-clear", "clipboard-manager:allow-write-text", diff --git a/src-tauri/static/greg.jpeg b/src-tauri/static/greg.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..eb7723cffad7970730d4adec8eefed39e07d4572 GIT binary patch literal 10775 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 ZQ-t9yhLu7x%&^#`P?0)ZG~3^m{{yF#CeZ)@ literal 0 HcmV?d00001 diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index c7a98979..3ea40eec 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -15,7 +15,8 @@ "enable": true, "scope": { "allow": [ - "$APPDATA/responses/*" + "$APPDATA/responses/*", + "$RESOURCE/static/*" ] } } @@ -56,6 +57,7 @@ ], "longDescription": "A cross-platform desktop app for interacting with REST, GraphQL, and gRPC", "resources": [ + "static", "vendored/protoc/include", "vendored/plugins", "vendored/plugin-runtime" diff --git a/src-tauri/yaak-license/src/license.rs b/src-tauri/yaak-license/src/license.rs index dce35ebb..f71d6282 100644 --- a/src-tauri/yaak-license/src/license.rs +++ b/src-tauri/yaak-license/src/license.rs @@ -155,6 +155,7 @@ pub async fn check_license(window: &WebviewWindow) -> Result DbContext<'a> { update_channel: "stable".to_string(), autoupdate: true, colored_methods: false, + hide_license_badge: false, }; self.upsert(&settings, &UpdateSource::Background).expect("Failed to upsert settings") } diff --git a/src-web/components/LicenseBadge.tsx b/src-web/components/LicenseBadge.tsx index 8671e986..af275312 100644 --- a/src-web/components/LicenseBadge.tsx +++ b/src-web/components/LicenseBadge.tsx @@ -1,8 +1,9 @@ import type { LicenseCheckStatus } from '@yaakapp-internal/license'; import { useLicense } from '@yaakapp-internal/license'; +import { settingsAtom } from '@yaakapp-internal/models'; +import { useAtomValue } from 'jotai'; import type { ReactNode } from 'react'; import { openSettings } from '../commands/openSettings'; -import { useLicenseConfirmation } from '../hooks/useLicenseConfirmation'; import { appInfo } from '../lib/appInfo'; import { BadgeButton } from './core/BadgeButton'; import type { ButtonProps } from './core/Button'; @@ -19,7 +20,7 @@ const details: Record< export function LicenseBadge() { const { check } = useLicense(); - const [licenseDetails, setLicenseDetails] = useLicenseConfirmation(); + const settings = useAtomValue(settingsAtom); if (appInfo.isDev) { return null; @@ -32,17 +33,17 @@ export function LicenseBadge() { } // Hasn't loaded yet - if (licenseDetails == null || check.data == null) { + if (check.data == null) { return null; } - // User has confirmed they are using Yaak for personal use only, so hide badge - if (licenseDetails.confirmedPersonalUse) { + // Dismissed license badge + if (settings.hideLicenseBadge) { return null; } // User is trialing but has already seen the message, so hide badge - if (check.data.type === 'trialing' && licenseDetails.hasDismissedTrial) { + if (check.data.type === 'trialing') { return null; } @@ -55,12 +56,6 @@ export function LicenseBadge() { { - if (check.data.type === 'trialing') { - await setLicenseDetails((v) => ({ - ...v, - hasDismissedTrial: true, - })); - } openSettings.mutate('license'); }} > diff --git a/src-web/components/LocalImage.tsx b/src-web/components/LocalImage.tsx new file mode 100644 index 00000000..59cf8a93 --- /dev/null +++ b/src-web/components/LocalImage.tsx @@ -0,0 +1,33 @@ +import { useQuery } from '@tanstack/react-query'; +import { convertFileSrc } from '@tauri-apps/api/core'; +import { resolveResource } from '@tauri-apps/api/path'; +import classNames from 'classnames'; +import React from 'react'; + +interface Props { + src: string; + className?: string; +} + +export function LocalImage({ src: srcPath, className }: Props) { + const src = useQuery({ + queryKey: ['local-image', srcPath], + queryFn: async () => { + const p = await resolveResource(srcPath); + console.log("LOADING SRC", srcPath, p) + return convertFileSrc(p); + }, + }); + + return ( + Response preview + ); +} diff --git a/src-web/components/Settings/Settings.tsx b/src-web/components/Settings/Settings.tsx index 6fbad5f4..3af1ead7 100644 --- a/src-web/components/Settings/Settings.tsx +++ b/src-web/components/Settings/Settings.tsx @@ -74,22 +74,22 @@ export default function Settings({ hide }: Props) { onChangeValue={setTab} tabs={tabs.map((value) => ({ value, label: capitalize(value) }))} > - + - + - + - + - + - + diff --git a/src-web/components/Settings/SettingsInterface.tsx b/src-web/components/Settings/SettingsInterface.tsx index feacb660..3fd3684a 100644 --- a/src-web/components/Settings/SettingsInterface.tsx +++ b/src-web/components/Settings/SettingsInterface.tsx @@ -1,13 +1,16 @@ import { type } from '@tauri-apps/plugin-os'; import { useFonts } from '@yaakapp-internal/fonts'; +import { useLicense } from '@yaakapp-internal/license'; import type { EditorKeymap } from '@yaakapp-internal/models'; import { patchModel, settingsAtom } from '@yaakapp-internal/models'; import { useAtomValue } from 'jotai'; import React from 'react'; import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace'; import { clamp } from '../../lib/clamp'; +import { showConfirm } from '../../lib/confirm'; import { Checkbox } from '../core/Checkbox'; import { Icon } from '../core/Icon'; +import { Link } from '../core/Link'; import { Select } from '../core/Select'; import { HStack, VStack } from '../core/Stacks'; @@ -28,6 +31,7 @@ export function SettingsInterface() { const workspace = useAtomValue(activeWorkspaceAtom); const settings = useAtomValue(settingsAtom); const fonts = useFonts(); + const license = useLicense(); if (settings == null || workspace == null) { return null; @@ -123,6 +127,31 @@ export function SettingsInterface() { title="Colorize Request Methods" onChange={(coloredMethods) => patchModel(settings, { coloredMethods })} /> + {license.check.data?.type === 'personal_use' && ( + { + if (hide) { + const confirmed = await showConfirm({ + id: 'hide-license-badge', + title: 'Hide License Badge', + confirmText: 'Hide Badge', + description: ( + <> + Only proceed if you’re using Yaak for personal projects only. If you’re using it + at work, please Purchase a License. + + ), + requireTyping: 'Personal Use', + color: 'notice', + }); + if (!confirmed) return; + } + await patchModel(settings, { licenseBadge: !hide }); + }} + /> + )} {type() !== 'macos' && ( (''); const [activateFormVisible, toggleActivateFormVisible] = useToggle(false); - const [licenseDetails, setLicenseDetails] = useLicenseConfirmation(); - const [checked, setChecked] = useState(false); if (check.isPending) { return null; } return ( -
+
{check.data?.type === 'commercial_use' ? ( - - License active! Enjoy using Yaak for commercial use. - + Your license is active 🥳 ) : check.data?.type == 'trialing' ? (

- You have{' '} {pluralizeCount('day', differenceInDays(check.data.end, new Date()))} remaining {' '} - on your commercial use trial. Once the trial ends you agree to only use Yaak for - personal use until a license is activated. + on trial

- ) : check.data?.type == 'personal_use' && !licenseDetails?.confirmedPersonalUse ? ( + ) : check.data?.type == 'personal_use' ? ( -

- Your 30-day trial has ended. Please activate a license or confirm how you're using - Yaak. -

-
{ - e.preventDefault(); - await setLicenseDetails((v) => ({ - ...v, - confirmedPersonalUse: true, - })); - }} - > - - - +

Your free trial has ended

) : null} -

- A commercial license is required if using Yaak within a for-profit organization.{' '} - - Learn More - -

+ {check.data?.type !== 'commercial_use' && ( +
+ +
+

Hey, I'm Greg 👋🏼

+

+ Yaak is free for personal projects and learning.{' '} + {check.data?.type === 'trialing' ? 'After your trial, a ' : 'A '} + license is required for work or commercial use. +

+

+ + Learn More + +

+
+
+ )} {check.error && {check.error}} {activate.error && {activate.error}} {check.data?.type === 'commercial_use' ? ( -