Explorar el Código

adds banner support on the home view

main
Keith Daulton hace 2 años
padre
commit
3ebf9c3539
Se han modificado 8 ficheros con 176 adiciones y 4 borrados
  1. +3
    -0
      src/storage.ts
  2. +25
    -0
      src/webviews/apps/home/home.html
  3. +79
    -0
      src/webviews/apps/home/home.scss
  4. +43
    -0
      src/webviews/apps/home/home.ts
  5. BIN
      src/webviews/apps/media/cyber-week-banner-dark.png
  6. BIN
      src/webviews/apps/media/cyber-week-banner-light.png
  7. +20
    -4
      src/webviews/home/homeWebviewView.ts
  8. +6
    -0
      src/webviews/home/protocol.ts

+ 3
- 0
src/storage.ts Ver fichero

@ -142,6 +142,9 @@ export interface GlobalStorage {
status: { status: {
pinned?: boolean; pinned?: boolean;
}; };
banners: {
dismissed?: string[];
};
}; };
pendingWelcomeOnFocus?: boolean; pendingWelcomeOnFocus?: boolean;
pendingWhatsNewOnFocus?: boolean; pendingWhatsNewOnFocus?: boolean;

+ 25
- 0
src/webviews/apps/home/home.html Ver fichero

@ -83,7 +83,32 @@
.gl-plus-banner { .gl-plus-banner {
background-image: url(#{webroot}/media/gitlens-backdrop-opacity.webp); background-image: url(#{webroot}/media/gitlens-backdrop-opacity.webp);
} }
.vscode-high-contrast .ribbon-banner,
.vscode-dark .ribbon-banner {
background-image: url(#{webroot}/media/cyber-week-banner-dark.webp);
}
.vscode-high-contrast-light .ribbon-banner,
.vscode-light .ribbon-banner {
background-image: url(#{webroot}/media/cyber-week-banner-light.webp);
}
</style> </style>
<div class="ribbon-banner-container" data-banner="cyberweek2022" hidden>
<a href="#" class="ribbon-banner">
<h2>
<strong>50% off</strong>
<span class="ribbon-banner__subtext">GitLens Pro &amp; all GitKraken products!</span>
</h2>
<p>Expires Dec 5, 2022 11:59pm PT</p>
</a>
<a
href="#"
class="ribbon-banner-dismiss"
data-banner-dismiss="cyberweek2022"
title="Dismiss"
aria-label="Dismiss"
><code-icon icon="close"></code-icon
></a>
</div>
<div class="stepped-sections"> <div class="stepped-sections">
<stepped-section id="welcome"> <stepped-section id="welcome">
<span slot="heading">Welcome to GitLens 13</span> <span slot="heading">Welcome to GitLens 13</span>

+ 79
- 0
src/webviews/apps/home/home.scss Ver fichero

@ -34,6 +34,10 @@
visibility: hidden; visibility: hidden;
} }
[hidden] {
display: none !important;
}
html { html {
height: 100%; height: 100%;
font-size: 62.5%; font-size: 62.5%;
@ -605,6 +609,81 @@ vscode-button {
} }
} }
.ribbon-banner {
&-container {
position: relative;
}
&-dismiss {
position: absolute;
top: 0;
right: 0;
display: inline-flex;
justify-content: center;
align-items: center;
width: 2.2rem;
height: 2.2rem;
color: var(--color-foreground--75);
&:hover {
color: var(--color-foreground--75);
text-decoration: none;
}
}
.vscode-high-contrast &,
.vscode-dark & {
background-color: var(--color-background--lighten-10);
background-position: right -7rem center;
background-size: auto 140px;
}
.vscode-high-contrast-light &,
.vscode-light & {
background-color: var(--color-background--darken-10);
background-position: right 2.5rem center;
background-size: auto 28px;
}
background-repeat: no-repeat;
display: block;
text-align: left;
color: inherit;
padding: 1.2rem 9.3rem 1.2rem 1.4rem;
line-height: 1.1;
margin-top: -2rem;
margin-bottom: 1rem;
border-radius: 0.4rem;
mix-blend-mode: luminosity;
opacity: 0.8;
transition: opacity ease 250ms, mix-blend-mode ease 250ms;
&:focus,
&:hover {
color: inherit;
text-decoration: none;
mix-blend-mode: normal;
opacity: 1;
}
h2 {
font-size: 1.2rem;
font-weight: inherit;
margin: 0 0 0.8rem 0;
}
p {
font-size: 1rem;
margin: 0;
opacity: 0.8;
}
strong {
font-weight: 800;
opacity: 1;
}
&__subtext {
opacity: 0.8;
}
}
@media (max-width: 280px) { @media (max-width: 280px) {
.not-small { .not-small {
display: none; display: none;

+ 43
- 0
src/webviews/apps/home/home.ts Ver fichero

@ -10,6 +10,7 @@ import {
DidChangeExtensionEnabledType, DidChangeExtensionEnabledType,
DidChangeLayoutType, DidChangeLayoutType,
DidChangeSubscriptionNotificationType, DidChangeSubscriptionNotificationType,
DismissBannerCommandType,
DismissSectionCommandType, DismissSectionCommandType,
DismissStatusCommandType, DismissStatusCommandType,
} from '../../home/protocol'; } from '../../home/protocol';
@ -72,6 +73,9 @@ export class HomeApp extends App {
this.onStatusDismissed(e, target), this.onStatusDismissed(e, target),
), ),
); );
disposables.push(
DOM.on('[data-banner-dismiss]', 'click', (e, target: HTMLElement) => this.onBannerDismissed(e, target)),
);
return disposables; return disposables;
} }
@ -143,6 +147,17 @@ export class HomeApp extends App {
this.updateHeader(); this.updateHeader();
} }
private onBannerDismissed(_e: MouseEvent, target: HTMLElement) {
const key = target.getAttribute('data-banner-dismiss');
if (key == null || this.state.dismissedBanners?.includes(key)) {
return;
}
this.state.dismissedBanners = this.state.dismissedBanners ?? [];
this.state.dismissedBanners.push(key);
this.sendCommand(DismissBannerCommandType, { id: key });
this.updateBanners();
}
private onDataActionClicked(_e: MouseEvent, target: HTMLElement) { private onDataActionClicked(_e: MouseEvent, target: HTMLElement) {
const action = target.dataset.action; const action = target.dataset.action;
this.onActionClickedCore(action); this.onActionClickedCore(action);
@ -209,6 +224,28 @@ export class HomeApp extends App {
} }
} }
private updateBanners() {
const $banners = [...document.querySelectorAll('[data-banner]')];
if (!$banners.length) {
return;
}
const { subscription, dismissedBanners } = this.state;
const isPaid = subscription.state === SubscriptionState.Paid;
$banners.forEach($el => {
const key = $el.getAttribute('data-banner');
if (
isPaid ||
(key !== null && dismissedBanners?.includes(key)) ||
(key === 'cyberweek2022' && !showCyberWeek())
) {
$el.setAttribute('hidden', 'true');
} else {
$el.removeAttribute('hidden');
}
});
}
private updateNoRepo() { private updateNoRepo() {
const { extensionEnabled } = this.state; const { extensionEnabled } = this.state;
@ -305,6 +342,7 @@ export class HomeApp extends App {
this.updateSteps(forceShowPlus); this.updateSteps(forceShowPlus);
this.updateSections(); this.updateSections();
this.updateBanners();
} }
} }
@ -319,4 +357,9 @@ function toggleArrayItem(list: string[] = [], item: string, add = true) {
return list; return list;
} }
const cyberweekEnding = Date.parse('2022-12-06T00:00:00.000-08:00');
function showCyberWeek() {
return Date.now() < cyberweekEnding;
}
new HomeApp(); new HomeApp();

BIN
src/webviews/apps/media/cyber-week-banner-dark.png Ver fichero

Antes Después
Anchura: 892  |  Altura: 260  |  Tamaño: 129 KiB

BIN
src/webviews/apps/media/cyber-week-banner-light.png Ver fichero

Antes Después
Anchura: 106  |  Altura: 56  |  Tamaño: 2.9 KiB

+ 20
- 4
src/webviews/home/homeWebviewView.ts Ver fichero

@ -17,7 +17,7 @@ import { debounce } from '../../system/function';
import type { IpcMessage } from '../protocol'; import type { IpcMessage } from '../protocol';
import { onIpc } from '../protocol'; import { onIpc } from '../protocol';
import { WebviewViewBase } from '../webviewViewBase'; import { WebviewViewBase } from '../webviewViewBase';
import type { CompleteStepParams, DismissSectionParams, State } from './protocol';
import type { CompleteStepParams, DismissBannerParams, DismissSectionParams, State } from './protocol';
import { import {
CompletedActions, CompletedActions,
CompleteStepCommandType, CompleteStepCommandType,
@ -25,6 +25,7 @@ import {
DidChangeExtensionEnabledType, DidChangeExtensionEnabledType,
DidChangeLayoutType, DidChangeLayoutType,
DidChangeSubscriptionNotificationType, DidChangeSubscriptionNotificationType,
DismissBannerCommandType,
DismissSectionCommandType, DismissSectionCommandType,
DismissStatusCommandType, DismissStatusCommandType,
} from './protocol'; } from './protocol';
@ -136,6 +137,9 @@ export class HomeWebviewView extends WebviewViewBase {
case DismissStatusCommandType.method: case DismissStatusCommandType.method:
onIpc(DismissStatusCommandType, e, _params => this.dismissPinStatus()); onIpc(DismissStatusCommandType, e, _params => this.dismissPinStatus());
break; break;
case DismissBannerCommandType.method:
onIpc(DismissBannerCommandType, e, params => this.dismissBanner(params));
break;
} }
} }
@ -153,14 +157,24 @@ export class HomeWebviewView extends WebviewViewBase {
private dismissSection(params: DismissSectionParams) { private dismissSection(params: DismissSectionParams) {
const sections = this.container.storage.get('home:sections:dismissed', []); const sections = this.container.storage.get('home:sections:dismissed', []);
if (!sections.includes(params.id)) {
sections.push(params.id);
if (sections.includes(params.id)) {
return;
} }
sections.push(params.id);
void this.container.storage.store('home:sections:dismissed', sections); void this.container.storage.store('home:sections:dismissed', sections);
} }
private dismissBanner(params: DismissBannerParams) {
const banners = this.container.storage.get('home:banners:dismissed', []);
if (!banners.includes(params.id)) {
banners.push(params.id);
}
void this.container.storage.store('home:banners:dismissed', banners);
}
private dismissPinStatus() { private dismissPinStatus() {
void this.container.storage.store('home:status:pinned', false); void this.container.storage.store('home:status:pinned', false);
} }
@ -209,6 +223,7 @@ export class HomeWebviewView extends WebviewViewBase {
const subscriptionState = await this.getSubscription(subscription); const subscriptionState = await this.getSubscription(subscription);
const steps = this.container.storage.get('home:steps:completed', []); const steps = this.container.storage.get('home:steps:completed', []);
const sections = this.container.storage.get('home:sections:dismissed', []); const sections = this.container.storage.get('home:sections:dismissed', []);
const dismissedBanners = this.container.storage.get('home:banners:dismissed', []);
return { return {
extensionEnabled: this.getExtensionEnabled(), extensionEnabled: this.getExtensionEnabled(),
@ -222,6 +237,7 @@ export class HomeWebviewView extends WebviewViewBase {
avatar: subscriptionState.avatar, avatar: subscriptionState.avatar,
layout: this.getLayout(), layout: this.getLayout(),
pinStatus: this.getPinStatus(), pinStatus: this.getPinStatus(),
dismissedBanners: dismissedBanners,
}; };
} }

+ 6
- 0
src/webviews/home/protocol.ts Ver fichero

@ -14,6 +14,7 @@ export interface State {
subscription: Subscription; subscription: Subscription;
completedActions: CompletedActions[]; completedActions: CompletedActions[];
completedSteps?: string[]; completedSteps?: string[];
dismissedBanners?: string[];
dismissedSections?: string[]; dismissedSections?: string[];
plusEnabled: boolean; plusEnabled: boolean;
visibility: RepositoriesVisibility; visibility: RepositoriesVisibility;
@ -35,6 +36,11 @@ export const DismissSectionCommandType = new IpcCommandType
export const DismissStatusCommandType = new IpcCommandType<undefined>('home/status/dismiss'); export const DismissStatusCommandType = new IpcCommandType<undefined>('home/status/dismiss');
export interface DismissBannerParams {
id: string;
}
export const DismissBannerCommandType = new IpcCommandType<DismissBannerParams>('home/banner/dismiss');
export interface DidChangeSubscriptionParams { export interface DidChangeSubscriptionParams {
subscription: Subscription; subscription: Subscription;
completedActions: CompletedActions[]; completedActions: CompletedActions[];

Cargando…
Cancelar
Guardar