diff --git a/src/webviews/apps/media/cyberweek-2023-wide-dark.png b/src/webviews/apps/media/cyberweek-2023-wide-dark.png new file mode 100644 index 0000000..a11d6c0 Binary files /dev/null and b/src/webviews/apps/media/cyberweek-2023-wide-dark.png differ diff --git a/src/webviews/apps/media/cyberweek-2023-wide-light.png b/src/webviews/apps/media/cyberweek-2023-wide-light.png new file mode 100644 index 0000000..f8f7068 Binary files /dev/null and b/src/webviews/apps/media/cyberweek-2023-wide-light.png differ diff --git a/src/webviews/apps/welcome/welcome.html b/src/webviews/apps/welcome/welcome.html index dbbaeda..12f45af 100644 --- a/src/webviews/apps/welcome/welcome.html +++ b/src/webviews/apps/welcome/welcome.html @@ -55,6 +55,23 @@ understand, write, and review code. Focus, collaborate, accelerate.

+

Powerful Features

diff --git a/src/webviews/apps/welcome/welcome.scss b/src/webviews/apps/welcome/welcome.scss index 4551449..327c874 100644 --- a/src/webviews/apps/welcome/welcome.scss +++ b/src/webviews/apps/welcome/welcome.scss @@ -3,6 +3,16 @@ @use '../shared/styles/normalize'; @use '../shared/styles/theme'; +.vscode-high-contrast, +.vscode-dark { + --promo-banner-dark-display: inline-block; +} + +.vscode-high-contrast-light, +.vscode-light { + --promo-banner-light-display: inline-block; +} + // normalize type body { line-height: 1.4; @@ -183,6 +193,24 @@ gk-card p { margin: 0; } +.promo-banner { + text-align: center; + + &__media { + width: 100%; + max-width: 100%; + height: auto; + + &.is-light { + display: var(--promo-banner-light-display, none); + } + + &.is-dark { + display: var(--promo-banner-dark-display, none); + } + } +} + .welcome { padding: var(--gitlens-gutter-width); diff --git a/src/webviews/apps/welcome/welcome.ts b/src/webviews/apps/welcome/welcome.ts index 523bbc7..8f7f9b4 100644 --- a/src/webviews/apps/welcome/welcome.ts +++ b/src/webviews/apps/welcome/welcome.ts @@ -93,6 +93,12 @@ export class WelcomeApp extends App { this.updateFeatures(); this.updateRepoState(); this.updateAccountState(); + this.updatePromo(); + } + + private updatePromo() { + const { canShowPromo } = this.state; + document.getElementById('promo')!.hidden = !(canShowPromo ?? false); } private updateVersion() { diff --git a/src/webviews/welcome/protocol.ts b/src/webviews/welcome/protocol.ts index d21f742..a0bd30b 100644 --- a/src/webviews/welcome/protocol.ts +++ b/src/webviews/welcome/protocol.ts @@ -9,7 +9,8 @@ export interface State extends WebviewState { currentLine: Config['currentLine']['enabled']; }; repoFeaturesBlocked?: boolean; - isTrialOrPaid?: boolean; + isTrialOrPaid: boolean; + canShowPromo: boolean; } export interface UpdateConfigurationParams { diff --git a/src/webviews/welcome/welcomeWebview.ts b/src/webviews/welcome/welcomeWebview.ts index 0cfa25b..da003ef 100644 --- a/src/webviews/welcome/welcomeWebview.ts +++ b/src/webviews/welcome/welcomeWebview.ts @@ -2,7 +2,7 @@ import type { ConfigurationChangeEvent } from 'vscode'; import { Disposable, workspace } from 'vscode'; import type { Container } from '../../container'; import type { Subscription } from '../../plus/gk/account/subscription'; -import { SubscriptionState } from '../../plus/gk/account/subscription'; +import { isSubscriptionPaid, SubscriptionState } from '../../plus/gk/account/subscription'; import type { SubscriptionChangeEvent } from '../../plus/gk/account/subscriptionService'; import { configuration } from '../../system/configuration'; import type { IpcMessage } from '../protocol'; @@ -77,6 +77,7 @@ export class WelcomeWebviewProvider implements WebviewProvider { this.container.git.openRepositoryCount === 0 || this.container.git.hasUnsafeRepositories(), isTrialOrPaid: await this.getTrialOrPaidState(subscription), + canShowPromo: await this.getCanShowPromo(subscription), }; } @@ -90,6 +91,16 @@ export class WelcomeWebviewProvider implements WebviewProvider { return false; } + private async getCanShowPromo(subscription?: Subscription): Promise { + const expiresTime = new Date('2023-12-06T07:59:00.000Z').getTime(); // 2023-12-05 23:59:00 PST-0800 + if (Date.now() > expiresTime) { + return false; + } + + const sub = subscription ?? (await this.container.subscription.getSubscription(true)); + return !isSubscriptionPaid(sub); + } + private updateConfiguration(params: UpdateConfigurationParams) { void configuration.updateEffective(`${params.type}.enabled`, params.value); }