@@ -19,6 +19,7 @@ import type {
1919import { GlyphChars } from '../../../constants' ;
2020import { Commands } from '../../../constants.commands' ;
2121import type { StoredGraphFilters , StoredGraphRefType } from '../../../constants.storage' ;
22+ import { proPreviewLengthInDays , proTrialLengthInDays } from '../../../constants.subscription' ;
2223import type { GraphShownTelemetryContext , GraphTelemetryContext , TelemetryEvents } from '../../../constants.telemetry' ;
2324import type { Container } from '../../../container' ;
2425import { CancellationError } from '../../../errors' ;
@@ -96,6 +97,7 @@ import { getSearchQueryComparisonKey, parseSearchQuery } from '../../../git/sear
9697import { splitGitCommitMessage } from '../../../git/utils/commit-utils' ;
9798import { ReferencesQuickPickIncludes , showReferencePicker } from '../../../quickpicks/referencePicker' ;
9899import { showRepositoryPicker } from '../../../quickpicks/repositoryPicker' ;
100+ import { createFromDateDelta } from '../../../system/date' ;
99101import { gate } from '../../../system/decorators/gate' ;
100102import { debug , log } from '../../../system/decorators/log' ;
101103import type { Deferrable } from '../../../system/function' ;
@@ -135,6 +137,7 @@ import type {
135137 DidGetCountParams ,
136138 DidGetRowHoverParams ,
137139 DidSearchParams ,
140+ DidSetFeaturePreviewTrialParams ,
138141 DoubleClickedParams ,
139142 GetMissingAvatarsParams ,
140143 GetMissingRefsMetadataParams ,
@@ -205,6 +208,7 @@ import {
205208 DidChangeWorkingTreeNotification ,
206209 DidFetchNotification ,
207210 DidSearchNotification ,
211+ DidSetFeaturePreviewTrialNotification ,
208212 DoubleClickedCommandType ,
209213 EnsureRowRequest ,
210214 GetCountsRequest ,
@@ -293,6 +297,7 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
293297 [ DidChangeSubscriptionNotification , this . notifyDidChangeSubscription ] ,
294298 [ DidChangeWorkingTreeNotification , this . notifyDidChangeWorkingTree ] ,
295299 [ DidFetchNotification , this . notifyDidFetch ] ,
300+ [ DidSetFeaturePreviewTrialNotification , this . notifyDidSetFeaturePreviewTrial ] ,
296301 ] ) ;
297302 private _refsMetadata : Map < string , GraphRefMetadata | null > | null | undefined ;
298303 private _search : GitSearch | undefined ;
@@ -679,11 +684,58 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
679684 'gitlens.graph.copyWorkingChangesToWorktree' ,
680685 this . copyWorkingChangesToWorktree ,
681686 ) ,
687+ this . host . registerWebviewCommand ( 'gitlens.graph.startFeaturePreviewTrial' , this . startFeaturePreviewTrial ) ,
682688 ) ;
683689
684690 return commands ;
685691 }
686692
693+ async startFeaturePreviewTrial ( ) {
694+ const timestamp = new Date ( ) ;
695+ const consumedDays : { startedOn : string ; expiresOn : string } [ ] = this . container . storage . get (
696+ `plus:featurePreviewTrial:graph:consumedDays` ,
697+ [ ] ,
698+ ) ;
699+
700+ // If it's still in the 24h trial, end here
701+ if ( consumedDays . length > 0 && new Date ( consumedDays [ consumedDays . length - 1 ] . expiresOn ) > timestamp ) {
702+ return ;
703+ }
704+
705+ if ( consumedDays . length >= proPreviewLengthInDays ) {
706+ void window . showInformationMessage (
707+ `You have already used your ${ proPreviewLengthInDays } days of previewing local Pro features.` ,
708+ ) ;
709+ return ;
710+ }
711+
712+ await this . container . storage . store ( `plus:featurePreviewTrial:graph:consumedDays` , [
713+ ...( consumedDays ?? [ ] ) ,
714+ {
715+ startedOn : timestamp . toISOString ( ) ,
716+ expiresOn : createFromDateDelta ( timestamp , { days : 1 } ) . toISOString ( ) ,
717+ } ,
718+ ] ) ;
719+
720+ if ( this . container . telemetry . enabled ) {
721+ this . container . telemetry . sendEvent (
722+ 'subscription/action' ,
723+ { action : `start-graph-preview-trial` } ,
724+ { source : 'graph' } ,
725+ ) ;
726+ }
727+
728+ void window . showInformationMessage (
729+ `You can now preview local Pro features for 1 day${
730+ consumedDays . length + 1 < proPreviewLengthInDays
731+ ? `, up to ${ proPreviewLengthInDays - ( consumedDays . length + 1 ) } more days`
732+ : ''
733+ } , or [start your free ${ proTrialLengthInDays } -day Pro trial](command:gitlens.plus.signUp "Start Pro Trial") for full access to Pro features.`,
734+ ) ;
735+
736+ void this . notifyDidSetFeaturePreviewTrial ( ) ;
737+ }
738+
687739 onWindowFocusChanged ( focused : boolean ) : void {
688740 this . isWindowFocused = focused ;
689741 }
@@ -1872,6 +1924,16 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
18721924 } ) ;
18731925 }
18741926
1927+ @debug ( )
1928+ private async notifyDidSetFeaturePreviewTrial ( ) {
1929+ if ( ! this . host . ready || ! this . host . visible ) {
1930+ this . host . addPendingIpcNotification ( DidSetFeaturePreviewTrialNotification , this . _ipcNotificationMap , this ) ;
1931+ return false ;
1932+ }
1933+
1934+ return this . host . notify ( DidSetFeaturePreviewTrialNotification , this . getStoredGraphPreviewTrial ( ) ) ;
1935+ }
1936+
18751937 @debug ( )
18761938 private async notifyDidChangeWorkingTree ( ) {
18771939 if ( ! this . host . ready || ! this . host . visible ) {
@@ -2514,6 +2576,8 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
25142576
25152577 const defaultSearchMode = this . container . storage . get ( 'graph:searchMode' ) ?? 'normal' ;
25162578
2579+ const graphPreviewTrial = this . getStoredGraphPreviewTrial ( ) ;
2580+
25172581 return {
25182582 ...this . host . baseWebviewState ,
25192583 windowFocused : this . isWindowFocused ,
@@ -2561,6 +2625,7 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
25612625 nonce : this . host . cspNonce ,
25622626 workingTreeStats : getSettledValue ( workingStatsResult ) ?? { added : 0 , deleted : 0 , modified : 0 } ,
25632627 defaultSearchMode : defaultSearchMode ,
2628+ graphPreviewTrial : graphPreviewTrial ,
25642629 } ;
25652630 }
25662631
@@ -2835,6 +2900,18 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
28352900 return refs ;
28362901 }
28372902
2903+ private getStoredGraphPreviewTrial ( ) : DidSetFeaturePreviewTrialParams {
2904+ const storedValue = this . container . storage . get ( `plus:featurePreviewTrial:graph:consumedDays` , [ ] ) ;
2905+ return {
2906+ feature : 'graph' ,
2907+ consumedDays : storedValue ,
2908+ isActive :
2909+ storedValue . length > 0 &&
2910+ storedValue . length <= proPreviewLengthInDays &&
2911+ new Date ( storedValue [ storedValue . length - 1 ] . expiresOn ) > new Date ( ) ,
2912+ } ;
2913+ }
2914+
28382915 private updateIncludeOnlyRefs (
28392916 repoPath : string | undefined ,
28402917 { branchesVisibility, refs } : UpdateIncludedRefsParams ,
0 commit comments