Skip to content

Commit 59c260e

Browse files
d13eamodio
authored andcommitted
Adds cyber week banner to home
1 parent 79b3d96 commit 59c260e

File tree

7 files changed

+118
-4
lines changed

7 files changed

+118
-4
lines changed

src/webviews/apps/home/home.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,30 @@ <h1 class="alert__title">Untrusted workspace</h1>
122122
<p data-requires="norepo">
123123
<code-icon icon="question"></code-icon> Features which need a repository are currently unavailable
124124
</p>
125+
<div class="promo-banner" id="promo-cw2023" hidden>
126+
<a
127+
class="promo-banner__link"
128+
href="https://www.gitkraken.com/cw23?utm_source=cyber_week&utm_medium=gitlens_banner&utm_campaign=cyber_week_2023"
129+
aria-label="Cyber Week Sale: 50% off first seat of Pro — only $4/month! Includes entire GitKraken suite of dev tools."
130+
>
131+
<img
132+
class="promo-banner__media is-dark"
133+
src="#{webroot}/media/cyberweek-2023-small-dark.webp"
134+
alt=""
135+
/>
136+
<img
137+
class="promo-banner__media is-light"
138+
src="#{webroot}/media/cyberweek-2023-small-light.webp"
139+
alt=""
140+
/><br />
141+
50% off first seat of Pro — only $4/month!
142+
</a>
143+
</div>
144+
<div class="promo-banner" id="promo-pro50" hidden>
145+
<a class="promo-banner__link" href="command:gitlens.plus.purchase"
146+
>Special: 50% off first seat of Pro — only $4/month!</a
147+
>
148+
</div>
125149
<nav class="nav-list">
126150
<h2 class="nav-list__title t-eyebrow">Popular views</h2>
127151
<a

src/webviews/apps/home/home.scss

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
--card-background: var(--color-background--lighten-075);
2020
--card-hover-background: var(--color-background--lighten-10);
2121
--popover-bg: var(--color-background--lighten-15);
22+
--promo-banner-dark-display: inline-block;
2223
}
2324

2425
.vscode-high-contrast-light,
@@ -27,6 +28,7 @@
2728
--card-background: var(--color-background--darken-075);
2829
--card-hover-background: var(--color-background--darken-10);
2930
--popover-bg: var(--color-background--darken-15);
31+
--promo-banner-light-display: inline-block;
3032
}
3133

3234
* {
@@ -141,6 +143,39 @@ ul {
141143
padding-left: 1.2em;
142144
}
143145

146+
.promo-banner {
147+
text-align: center;
148+
margin-bottom: 1rem;
149+
150+
&__link {
151+
display: inline-block;
152+
font-size: 1.1rem;
153+
font-weight: bold;
154+
color: inherit;
155+
text-align: center;
156+
text-decoration: none;
157+
158+
&:hover {
159+
color: inherit;
160+
text-decoration: underline;
161+
}
162+
}
163+
164+
&__media {
165+
// width: 100%;
166+
max-width: 100%;
167+
height: auto;
168+
169+
&.is-light {
170+
display: var(--promo-banner-light-display, none);
171+
}
172+
173+
&.is-dark {
174+
display: var(--promo-banner-dark-display, none);
175+
}
176+
}
177+
}
178+
144179
.home {
145180
padding: 0;
146181
height: 100%;

src/webviews/apps/home/home.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import './home.scss';
33
import type { Disposable } from 'vscode';
44
import type { State } from '../../home/protocol';
5-
import { DidChangeRepositoriesType } from '../../home/protocol';
5+
import { DidChangeRepositoriesType, DidChangeSubscriptionType } from '../../home/protocol';
66
import type { IpcMessage } from '../../protocol';
77
import { ExecuteCommandType, onIpc } from '../../protocol';
88
import { App } from '../shared/appBase';
@@ -48,6 +48,13 @@ export class HomeApp extends App<State> {
4848
this.updateNoRepo();
4949
});
5050
break;
51+
case DidChangeSubscriptionType.method:
52+
onIpc(DidChangeSubscriptionType, msg, params => {
53+
this.state.promoStates = params.promoStates;
54+
this.setState(this.state);
55+
this.updatePromos();
56+
});
57+
break;
5158
default:
5259
super.onMessageReceived?.(msg);
5360
break;
@@ -98,8 +105,18 @@ export class HomeApp extends App<State> {
98105
header.hidden = !noRepos && !hasUnsafe;
99106
}
100107

108+
private updatePromos() {
109+
const {
110+
promoStates: { cw2023, pro50 },
111+
} = this.state;
112+
113+
setElementVisibility('promo-cw2023', cw2023);
114+
setElementVisibility('promo-pro50', pro50);
115+
}
116+
101117
private updateState() {
102118
this.updateNoRepo();
119+
this.updatePromos();
103120
}
104121
}
105122

5.57 KB
Loading
16.5 KB
Loading

src/webviews/home/homeWebview.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { Disposable, workspace } from 'vscode';
22
import type { Container } from '../../container';
3+
import type { Subscription } from '../../plus/gk/account/subscription';
4+
import { isSubscriptionExpired, isSubscriptionPaid, isSubscriptionTrial } from '../../plus/gk/account/subscription';
5+
import type { SubscriptionChangeEvent } from '../../plus/gk/account/subscriptionService';
36
import { registerCommand } from '../../system/command';
47
import type { WebviewController, WebviewProvider } from '../webviewController';
58
import type { DidChangeRepositoriesParams, State } from './protocol';
6-
import { DidChangeRepositoriesType } from './protocol';
9+
import { DidChangeRepositoriesType, DidChangeSubscriptionType } from './protocol';
710

811
const emptyDisposable = Object.freeze({
912
dispose: () => {
@@ -23,6 +26,7 @@ export class HomeWebviewProvider implements WebviewProvider<State> {
2326
!workspace.isTrusted
2427
? workspace.onDidGrantWorkspaceTrust(this.notifyDidChangeRepositories, this)
2528
: emptyDisposable,
29+
this.container.subscription.onDidChange(this.onSubscriptionChanged, this),
2630
);
2731
}
2832

@@ -38,19 +42,24 @@ export class HomeWebviewProvider implements WebviewProvider<State> {
3842
return [registerCommand(`${this.host.id}.refresh`, () => this.host.refresh(true), this)];
3943
}
4044

41-
includeBootstrap(): State {
45+
includeBootstrap(): Promise<State> {
4246
return this.getState();
4347
}
4448

4549
onReloaded() {
4650
this.notifyDidChangeRepositories();
4751
}
4852

49-
private getState(): State {
53+
private onSubscriptionChanged(e: SubscriptionChangeEvent) {
54+
void this.notifyDidChangeSubscription(e.current);
55+
}
56+
57+
private async getState(subscription?: Subscription): Promise<State> {
5058
return {
5159
...this.host.baseWebviewState,
5260
repositories: this.getRepositoriesState(),
5361
webroot: this.host.getWebRoot(),
62+
promoStates: await this.getCanShowPromos(subscription),
5463
};
5564
}
5665

@@ -63,7 +72,30 @@ export class HomeWebviewProvider implements WebviewProvider<State> {
6372
};
6473
}
6574

75+
private async getCanShowPromos(subscription?: Subscription): Promise<Record<string, boolean>> {
76+
const promos = {
77+
cw2023: false,
78+
pro50: false,
79+
};
80+
81+
const sub = subscription ?? (await this.container.subscription.getSubscription(true));
82+
const expiresTime = new Date('2023-12-06T07:59:00.000Z').getTime(); // 2023-12-05 23:59:00 PST-0800
83+
if (Date.now() < expiresTime && !isSubscriptionPaid(sub)) {
84+
promos.cw2023 = true;
85+
} else if (subscription != null && (isSubscriptionTrial(subscription) || isSubscriptionExpired(subscription))) {
86+
promos.pro50 = true;
87+
}
88+
89+
return promos;
90+
}
91+
6692
private notifyDidChangeRepositories() {
6793
void this.host.notify(DidChangeRepositoriesType, this.getRepositoriesState());
6894
}
95+
96+
private async notifyDidChangeSubscription(subscription?: Subscription) {
97+
void this.host.notify(DidChangeSubscriptionType, {
98+
promoStates: await this.getCanShowPromos(subscription),
99+
});
100+
}
69101
}

src/webviews/home/protocol.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { IpcNotificationType } from '../protocol';
44
export interface State extends WebviewState {
55
repositories: DidChangeRepositoriesParams;
66
webroot?: string;
7+
promoStates: Record<string, boolean>;
78
}
89

910
export interface DidChangeRepositoriesParams {
@@ -13,3 +14,8 @@ export interface DidChangeRepositoriesParams {
1314
trusted: boolean;
1415
}
1516
export const DidChangeRepositoriesType = new IpcNotificationType<DidChangeRepositoriesParams>('repositories/didChange');
17+
18+
export interface DidChangeSubscriptionParams {
19+
promoStates: Record<string, boolean>;
20+
}
21+
export const DidChangeSubscriptionType = new IpcNotificationType<DidChangeSubscriptionParams>('subscription/didChange');

0 commit comments

Comments
 (0)