diff --git a/src/webviews/apps/home/components/card-section.ts b/src/webviews/apps/home/components/card-section.ts index e69b801..48ec390 100644 --- a/src/webviews/apps/home/components/card-section.ts +++ b/src/webviews/apps/home/components/card-section.ts @@ -1,4 +1,4 @@ -import { attr, css, customElement, FASTElement, html, volatile, when } from '@microsoft/fast-element'; +import { attr, css, customElement, FASTElement, html, when } from '@microsoft/fast-element'; import { numberConverter } from '../../shared/components/converters/number-converter'; import '../../shared/components/codicon'; @@ -38,11 +38,16 @@ const styles = css` :host { display: block; padding: 1.2rem; - background-color: #aaaaaa10; + background-color: var(--card-background); margin-bottom: 1rem; border-radius: 0.4rem; background-repeat: no-repeat; background-size: cover; + transition: aspect-ratio linear 100ms, background-color linear 100ms; + } + + :host(:hover) { + background-color: var(--card-hover-background); } header { @@ -104,7 +109,7 @@ export class CardSection extends FASTElement { @attr({ mode: 'boolean' }) expanded = true; - handleDismiss(e: Event) { + handleDismiss(_e: Event) { this.$emit('dismiss'); } } diff --git a/src/webviews/apps/home/components/header-card.ts b/src/webviews/apps/home/components/header-card.ts new file mode 100644 index 0000000..ee801da --- /dev/null +++ b/src/webviews/apps/home/components/header-card.ts @@ -0,0 +1,236 @@ +import { attr, css, customElement, FASTElement, html, volatile, when } from '@microsoft/fast-element'; +import { SubscriptionState } from '../../../../subscription'; +import { pluralize } from '../../../../system/string'; +import { numberConverter } from '../../shared/components/converters/number-converter'; +import '../../shared/components/codicon'; + +const template = html` +
GitLens Logo
+

+ ${when( + x => x.name === '', + html`GitLens 12 Git supercharged`, + )} + ${when(x => x.name !== '', html`${x => x.name}`)} +

+

+ ${x => x.planName} + + ${when( + x => x.state === SubscriptionState.Free, + html` + Sign In + `, + )} + ${when( + x => x.state === SubscriptionState.Paid, + html` +   + `, + )} + ${when( + x => [SubscriptionState.FreeInPreviewTrial, SubscriptionState.FreePlusInTrial].includes(x.state), + html`${x => x.daysRemaining}`, + )} + ${when( + x => x.state === SubscriptionState.FreePreviewTrialExpired, + html`Extend Trial`, + )} + ${when( + x => x.state === SubscriptionState.FreePlusTrialExpired, + html` + Upgrade to Pro  + `, + )} + ${when( + x => x.state === SubscriptionState.VerificationRequired, + html` + Verify  + `, + )} + +

+
+
+
+`; + +const styles = css` + * { + box-sizing: border-box; + } + + :host { + position: relative; + display: grid; + padding: 1rem 1rem 1.2rem; + background-color: var(--card-background); + border-radius: 0.4rem; + gap: 0 0.8rem; + grid-template-columns: 3.4rem auto; + grid-auto-flow: column; + } + + a { + color: var(--vscode-textLink-foreground); + text-decoration: none; + } + a:focus { + outline-color: var(--focus-border); + } + a:hover { + text-decoration: underline; + } + + .header-card__media { + grid-column: 1; + grid-row: 1 / span 2; + } + + .header-card__image { + aspect-ratio: 1 / 1; + border-radius: 50%; + } + + .header-card__title { + font-size: var(--vscode-font-size); + color: var(--gitlens-brand-color-2); + margin: 0; + } + .header-card__title em { + font-weight: normal; + color: var(--color-view-foreground); + opacity: 0.4; + margin-left: 0.4rem; + } + .header-card__account { + margin: 0; + display: flex; + flex-direction: row; + justify-content: space-between; + flex-wrap: wrap; + } + + .progress { + width: 100%; + overflow: hidden; + } + + :host-context(.vscode-high-contrast) .progress, + :host-context(.vscode-dark) .progress { + background-color: var(--color-background--lighten-15); + } + + :host-context(.vscode-high-contrast-light) .progress, + :host-context(.vscode-light) .progress { + background-color: var(--color-background--darken-15); + } + + .progress__indicator { + height: 4px; + background-color: var(--vscode-progressBar-background); + } + + .header-card__progress { + position: absolute; + bottom: 0; + left: 0; + border-bottom-left-radius: 0.4rem; + border-bottom-right-radius: 0.4rem; + } + + .foreground { + color: var(--color-foreground); + } + .status { + color: var(--color-foreground--75); + } +`; + +@customElement({ name: 'header-card', template: template, styles: styles }) +export class HeaderCard extends FASTElement { + @attr + image = ''; + + @attr + name = ''; + + @attr({ converter: numberConverter }) + days = 0; + + @attr({ converter: numberConverter }) + steps = 4; + + @attr({ converter: numberConverter }) + completed = 0; + + @attr({ converter: numberConverter }) + state: SubscriptionState = SubscriptionState.Free; + + @attr + plan = ''; + + get daysRemaining() { + if (this.days < 1) { + return '<1 day'; + } + return pluralize('day', this.days); + } + + get progressNow() { + return this.completed + 1; + } + + get progressMax() { + return this.steps + 1; + } + + @volatile + get progress() { + return `${(this.progressNow / this.progressMax) * 100}%`; + } + + @volatile + get planName() { + switch (this.state) { + case SubscriptionState.Free: + return 'GitLens+ (Local & Public Repos)'; + case SubscriptionState.FreeInPreviewTrial: + case SubscriptionState.FreePlusInTrial: + return 'GitLens+ Pro Trial'; + case SubscriptionState.FreePreviewTrialExpired: + return 'GitLens+ (Local & Public Repos)'; + case SubscriptionState.FreePlusTrialExpired: + return 'GitLens+ (Local & Public Repos)'; + case SubscriptionState.VerificationRequired: + return 'GitLens+ (Unverified)'; + default: + return this.plan; + } + } +} diff --git a/src/webviews/apps/home/components/plus-content.ts b/src/webviews/apps/home/components/plus-content.ts new file mode 100644 index 0000000..e6ac3f2 --- /dev/null +++ b/src/webviews/apps/home/components/plus-content.ts @@ -0,0 +1,156 @@ +import { attr, css, customElement, FASTElement, html, when } from '@microsoft/fast-element'; +import { SubscriptionState } from '../../../../subscription'; +import { pluralize } from '../../../../system/string'; +import { numberConverter } from '../../shared/components/converters/number-converter'; +import '../../shared/components/codicon'; + +const template = html` + ${when( + x => x.state === SubscriptionState.Free, + html` +

Adds all-new, completely optional, features that enhance your GitLens experience.

+

These features are free for local and public repos with no account required.

+ +

+ Try GitLens+ for private repositories +

+

+ Hide GitLens+ features +

+ `, + )} + ${when( + x => x.state === SubscriptionState.Paid, + html` +

GitLens+ adds all-new, completely optional, features that enhance your current GitLens experience.

+

These features are free for local and public repos with no account required.

+ `, + )} + ${when( + x => [SubscriptionState.FreeInPreviewTrial, SubscriptionState.FreePlusInTrial].includes(x.state), + html` +

GitLens+ Trial

+

+ You have ${x => x.daysRemaining} left in your + GitLens+ trial. Once + your trial ends, you'll need a paid plan to continue to use GitLens+ features on this and other private + repos. +

+ `, + )} + ${when( + x => x.state === SubscriptionState.FreePreviewTrialExpired, + html` +

Extend Your GitLens+ Trial

+

+ Your free trial has ended, please sign in to extend your trial of GitLens+ features on private repos by + an additional 7-days. +

+

+ Extend Trial +

+ `, + )} + ${when( + x => x.state === SubscriptionState.FreePlusTrialExpired, + html` +

GitLens+ Trial Expired

+

+ Your free trial has ended, please upgrade your account to continue to use GitLens+ features, including + the Commit Graph, on this and other private repos. +

+

+ Upgrade Your Account +

+ `, + )} + ${when( + x => x.state === SubscriptionState.VerificationRequired, + html` +

Please verify your email

+

Please verify the email for the account you created.

+

+ Resend Verification Email +

+

+ Refresh Verification Status +

+ `, + )} + +

All other GitLens features are always accessible

+`; + +const styles = css` + * { + box-sizing: border-box; + } + + :host { + display: block; + text-align: center; + } + + a { + color: var(--vscode-textLink-foreground); + text-decoration: none; + } + a:focus { + outline-color: var(--focus-border); + } + a:hover { + text-decoration: underline; + } + + p { + margin-top: 0; + } + + .mb-1 { + margin-bottom: 0.4rem; + } + .mb-0 { + margin-bottom: 0; + } + + .minimal { + color: var(--color-foreground--50); + } +`; + +@customElement({ name: 'plus-content', template: template, styles: styles }) +export class PlusContent extends FASTElement { + @attr({ converter: numberConverter }) + days = 0; + + @attr({ converter: numberConverter }) + state: SubscriptionState = SubscriptionState.Free; + + @attr + visibility: 'local' | 'public' | 'mixed' | 'private' = 'public'; + + get daysRemaining() { + if (this.days < 1) { + return 'less than one day'; + } + return pluralize('day', this.days); + } + + get isFree() { + return ['local', 'public'].includes(this.visibility); + } + + fireAction(command: string) { + this.$emit('action', command); + } +} diff --git a/src/webviews/apps/home/components/stepped-section.ts b/src/webviews/apps/home/components/stepped-section.ts index 93da395..2fb416d 100644 --- a/src/webviews/apps/home/components/stepped-section.ts +++ b/src/webviews/apps/home/components/stepped-section.ts @@ -1,4 +1,4 @@ -import { attr, css, customElement, FASTElement, html, volatile, when } from '@microsoft/fast-element'; +import { attr, css, customElement, FASTElement, html } from '@microsoft/fast-element'; import { numberConverter } from '../../shared/components/converters/number-converter'; import '../../shared/components/codicon'; @@ -63,6 +63,15 @@ const styles = css` color: var(--vscode-textLink-foreground); } + /* + .checkbox code-icon { + border-radius: 50%; + } + .heading:hover ~ .checkbox code-icon { + background-color: var(--vscode-textLink-foreground); + } + */ + :host(:not(:last-of-type)) .checkbox:after { content: ''; position: absolute; @@ -86,8 +95,7 @@ const styles = css` .description { margin-left: 0.2rem; text-transform: none; - /* color needs to come from some sort property */ - color: #b68cd8; + color: var(--gitlens-brand-color-2); opacity: 0.6; font-style: italic; } @@ -101,7 +109,7 @@ export class SteppedSection extends FASTElement { @attr({ mode: 'boolean' }) completed = false; - handleClick(e: Event) { + handleClick(_e: Event) { this.completed = !this.completed; this.$emit('complete', this.completed); } diff --git a/src/webviews/apps/home/home.html b/src/webviews/apps/home/home.html index f02275e..3ad7c47 100644 --- a/src/webviews/apps/home/home.html +++ b/src/webviews/apps/home/home.html @@ -5,20 +5,67 @@ - skip to content - skip to footer links -
-
- -

GitLens 12 Git supercharged

- -
-
+ skip to links + skip to main content + +
+ + + + +
+ +
+
+