diff --git a/src/plus/focus/focusService.ts b/src/plus/focus/focusService.ts index 63f6c49..2ea8518 100644 --- a/src/plus/focus/focusService.ts +++ b/src/plus/focus/focusService.ts @@ -1,7 +1,9 @@ import type { Disposable } from 'vscode'; +import { window } from 'vscode'; import type { Container } from '../../container'; import type { GitRemote } from '../../git/models/remote'; import type { RichRemoteProvider } from '../../git/remotes/richRemoteProvider'; +import { isSubscriptionPaidPlan } from '../../subscription'; import { log } from '../../system/decorators/log'; import { Logger } from '../../system/logger'; import { getLogScope } from '../../system/logger.scope'; @@ -83,6 +85,8 @@ export class FocusService implements Disposable { const result = (await rsp.json()) as Result; return type == null ? result.data : result.data.filter(i => i.type === type); } catch (ex) { + if (ex instanceof Error && ex.message === 'Authentication required') return []; + Logger.error(ex, scope); debugger; throw ex; @@ -104,6 +108,10 @@ export class FocusService implements Disposable { const scope = getLogScope(); try { + if (!(await ensureAccount('Pinning requires an account', this.container))) { + throw new Error('Unable to pin item: account required'); + } + type Result = { data: EnrichedItemResponse }; const rq: EnrichedItemRequest = { @@ -143,6 +151,10 @@ export class FocusService implements Disposable { const scope = getLogScope(); try { + if (!(await ensurePaidPlan('Snoozing requires a trial or paid plan', this.container))) { + throw new Error('Unable to snooze item: subscription required'); + } + type Result = { data: EnrichedItemResponse }; const rq: EnrichedItemRequest = { @@ -177,3 +189,109 @@ export class FocusService implements Disposable { return this.delete(id, 'unsnooze'); } } + +async function ensurePaidPlan(title: string, container: Container): Promise { + while (true) { + const subscription = await container.subscription.getSubscription(); + if (subscription.account?.verified === false) { + const resend = { title: 'Resend Verification' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nYou must verify your email before you can continue.`, + { modal: true }, + resend, + cancel, + ); + + if (result === resend) { + if (await container.subscription.resendVerification()) { + continue; + } + } + + return false; + } + + const plan = subscription.plan.effective.id; + if (isSubscriptionPaidPlan(plan)) break; + + if (subscription.account == null) { + const signIn = { title: 'Start Free GitKraken Trial' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nTry our developer productivity and collaboration services free for 7 days.`, + { modal: true }, + signIn, + cancel, + ); + + if (result === signIn) { + if (await container.subscription.loginOrSignUp()) { + continue; + } + } + } else { + const upgrade = { title: 'Upgrade to Pro' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nContinue to use our developer productivity and collaboration services.`, + { modal: true }, + upgrade, + cancel, + ); + + if (result === upgrade) { + void container.subscription.purchase(); + } + } + + return false; + } + + return true; +} + +async function ensureAccount(title: string, container: Container): Promise { + while (true) { + const subscription = await container.subscription.getSubscription(); + if (subscription.account?.verified === false) { + const resend = { title: 'Resend Verification' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nYou must verify your email before you can continue.`, + { modal: true }, + resend, + cancel, + ); + + if (result === resend) { + if (await container.subscription.resendVerification()) { + continue; + } + } + + return false; + } + + if (subscription.account != null) break; + + const signIn = { title: 'Sign In / Sign Up' }; + const cancel = { title: 'Cancel', isCloseAffordance: true }; + const result = await window.showWarningMessage( + `${title}\n\nGain access to our developer productivity and collaboration services.`, + { modal: true }, + signIn, + cancel, + ); + + if (result === signIn) { + if (await container.subscription.loginOrSignUp()) { + continue; + } + } + + return false; + } + + return true; +}