From 66df4f531ad19a68856cdd8425ebb88b38dcd6b4 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Wed, 24 Nov 2021 20:51:54 -0600
Subject: [PATCH 01/24] Add the yaml keyword back in
---
package.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 0da17ef4..895288dd 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,8 @@
"cicd",
"CI/CD",
"CircleCI",
- "continuous integration"
+ "continuous integration",
+ "YAML"
],
"activationEvents": [
"localCiJobs.selectRepo",
From c2e3c98b143c958b998657971431c77e4587febc Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 25 Nov 2021 12:07:36 -0600
Subject: [PATCH 02/24] Update the links to preview and paid to point to
/pricing
---
README.md | 4 ++--
package.json | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 8e01f6b4..765a492c 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-[](https://getlocalci.com)
-[](https://getlocalci.com)
+[](https://getlocalci.com/pricing)
+[](https://getlocalci.com/pricing)
[](https://en.wikipedia.org/wiki/MacOS)
[](https://circleci.com)
diff --git a/package.json b/package.json
index 895288dd..514e93f9 100644
--- a/package.json
+++ b/package.json
@@ -223,7 +223,7 @@
"badges": [
{
"url": "https://img.shields.io/badge/trial-2%20day-orange",
- "href": "https://getlocalci.com",
+ "href": "https://getlocalci.com/pricing",
"description": "2 day free preview"
},
{
From a15dd9d93cd8aebcd0c16b2720ac70b5c6b5518e Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 25 Nov 2021 12:17:03 -0600
Subject: [PATCH 03/24] Add a link to get started with CircleCI
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 765a492c..70d85440 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ But first you'll get a free 2-day preview, no sign-up or credit card needed.
[CircleCI®](https://circleci.com/), [macOS](https://en.wikipedia.org/wiki/MacOS), [Docker](https://www.docker.com/)
-If you don't have a CircleCI® account, please [sign up here](https://circleci.com/docs/2.0/first-steps/).
+If you don’t have a CircleCI® account, you can [get started](https://circleci.com/docs/2.0/first-steps/) with CircleCI® for free.
A `.circleci/config.yml` file should be somewhere in the VS Code workspace, using the [2.x configuration](https://circleci.com/docs/2.0/configuration-reference/).
From 900311ed4582956711e0e72aac2c18ad4588b37e Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 25 Nov 2021 12:18:12 -0600
Subject: [PATCH 04/24] Change the backtick to an apostrophe
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 70d85440..db8e5397 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ But first you'll get a free 2-day preview, no sign-up or credit card needed.
[CircleCI®](https://circleci.com/), [macOS](https://en.wikipedia.org/wiki/MacOS), [Docker](https://www.docker.com/)
-If you don’t have a CircleCI® account, you can [get started](https://circleci.com/docs/2.0/first-steps/) with CircleCI® for free.
+If you don't have a CircleCI® account, you can [get started](https://circleci.com/docs/2.0/first-steps/) with CircleCI® for free.
A `.circleci/config.yml` file should be somewhere in the VS Code workspace, using the [2.x configuration](https://circleci.com/docs/2.0/configuration-reference/).
From dc69b534db5fdab9f16a5afa4ae5a22b3ded3bcf Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Mon, 29 Nov 2021 23:34:16 -0600
Subject: [PATCH 05/24] Change the remaining time in the preview to account for
days
Setting the stage to
add time to the trial for filling out the survey.
---
src/classes/LicenseProvider.ts | 7 ++-
src/constants/index.ts | 1 +
.../getDaysAndHoursRemainingInTrial.test.ts | 55 +++++++++++++++++++
...> getMillisecondsRemainingInTrial.test.ts} | 16 +++---
src/utils/getDaysAndHoursRemainingInTrial.ts | 49 +++++++++++++++++
src/utils/getLicenseInformation.ts | 30 ++++------
....ts => getMillisecondsRemainingInTrial.ts} | 7 +--
src/utils/isTrialExpired.ts | 7 ++-
webview/index.js | 24 ++++----
9 files changed, 152 insertions(+), 44 deletions(-)
create mode 100644 src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts
rename src/test/suite/utils/{getHoursRemainingInTrial.test.ts => getMillisecondsRemainingInTrial.test.ts} (51%)
create mode 100644 src/utils/getDaysAndHoursRemainingInTrial.ts
rename src/utils/{getHoursRemainingInTrial.ts => getMillisecondsRemainingInTrial.ts} (58%)
diff --git a/src/classes/LicenseProvider.ts b/src/classes/LicenseProvider.ts
index cd6bbd78..fea88751 100644
--- a/src/classes/LicenseProvider.ts
+++ b/src/classes/LicenseProvider.ts
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
-import { LICENSE_ERROR } from '../constants';
+import { LICENSE_ERROR, SURVEY_URL } from '../constants';
import getLicenseErrorMessage from '../utils/getLicenseErrorMessage';
import getLicenseInformation from '../utils/getLicenseInformation';
import isLicenseValid from '../utils/isLicenseValid';
@@ -66,6 +66,11 @@ export default class LicenseProvider implements vscode.WebviewViewProvider {
});
}
}
+
+ if (data.type === 'takeSurvey') {
+ // @todo: Set globalState to extend the preview length.
+ vscode.env.openExternal(vscode.Uri.parse(SURVEY_URL));
+ }
});
}
diff --git a/src/constants/index.ts b/src/constants/index.ts
index 80195499..4d182d80 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -50,3 +50,4 @@ export const LOCAL_VOLUME_DIRECTORY = `${HOST_TMP_DIRECTORY}/volume`;
export const RUN_JOB_COMMAND = 'local-ci.job.run';
export const SUPPRESS_UNCOMMITTED_FILE_WARNING =
'local-ci.suppress-warning.uncommitted';
+export const SURVEY_URL = 'https://example.com';
diff --git a/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts b/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts
new file mode 100644
index 00000000..c61bee9d
--- /dev/null
+++ b/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts
@@ -0,0 +1,55 @@
+import * as assert from 'assert';
+import getDaysAndHoursRemainingInTrial from '../../../utils/getDaysAndHoursRemainingInTrial';
+
+const hourInMilliseconds = 3600000;
+suite('getDaysAndHoursRemainingInTrial', () => {
+ test('no trial started timestamp', () => {
+ const time = new Date().getTime();
+ assert.strictEqual(getDaysAndHoursRemainingInTrial(time, null), 'No time');
+ });
+
+ test('entire trial remaining', () => {
+ const time = new Date().getTime();
+ assert.strictEqual(getDaysAndHoursRemainingInTrial(time, time), '2 days');
+ });
+
+ test('entire trial remaining', () => {
+ const time = new Date().getTime();
+ assert.strictEqual(
+ getDaysAndHoursRemainingInTrial(time, time - 10 * hourInMilliseconds),
+ '1 day, 14 hours'
+ );
+ });
+
+ test('one day remaining', () => {
+ const time = new Date().getTime();
+ assert.strictEqual(
+ getDaysAndHoursRemainingInTrial(time, time - 24 * hourInMilliseconds),
+ '1 day'
+ );
+ });
+
+ test('five hours remaining', () => {
+ const time = new Date().getTime();
+ assert.strictEqual(
+ getDaysAndHoursRemainingInTrial(time, time - 43 * hourInMilliseconds),
+ '5 hours'
+ );
+ });
+
+ test('one hour remaining', () => {
+ const time = new Date().getTime();
+ assert.strictEqual(
+ getDaysAndHoursRemainingInTrial(time, time - 47 * hourInMilliseconds),
+ '1 hour'
+ );
+ });
+
+ test('no time remaining', () => {
+ const time = new Date().getTime();
+ assert.strictEqual(
+ getDaysAndHoursRemainingInTrial(time, time - 48 * hourInMilliseconds),
+ 'No time'
+ );
+ });
+});
diff --git a/src/test/suite/utils/getHoursRemainingInTrial.test.ts b/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
similarity index 51%
rename from src/test/suite/utils/getHoursRemainingInTrial.test.ts
rename to src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
index 0c95132d..6524e21c 100644
--- a/src/test/suite/utils/getHoursRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
@@ -1,33 +1,33 @@
import * as assert from 'assert';
-import getHoursRemainingInTrial from '../../../utils/getHoursRemainingInTrial';
+import getMillisecondsRemainingInTrial from '../../../utils/getMillisecondsRemainingInTrial';
const hourInMilliseconds = 3600000;
-suite('getHoursRemainingInTrial', () => {
+suite('getMillisecondsRemainingInTrial', () => {
test('entire trial remaining', () => {
const time = new Date().getTime();
- assert.strictEqual(getHoursRemainingInTrial(time, time), 48);
+ assert.strictEqual(getMillisecondsRemainingInTrial(time, time), 172800000);
});
test('one day remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getHoursRemainingInTrial(time, time - 24 * hourInMilliseconds),
- 24
+ getMillisecondsRemainingInTrial(time, time - 24 * hourInMilliseconds),
+ 86400000
);
});
test('one hour remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getHoursRemainingInTrial(time, time - 47 * hourInMilliseconds),
- 1
+ getMillisecondsRemainingInTrial(time, time - 47 * hourInMilliseconds),
+ 3600000
);
});
test('no time remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getHoursRemainingInTrial(time, time - 48 * hourInMilliseconds),
+ getMillisecondsRemainingInTrial(time, time - 48 * hourInMilliseconds),
0
);
});
diff --git a/src/utils/getDaysAndHoursRemainingInTrial.ts b/src/utils/getDaysAndHoursRemainingInTrial.ts
new file mode 100644
index 00000000..01daa439
--- /dev/null
+++ b/src/utils/getDaysAndHoursRemainingInTrial.ts
@@ -0,0 +1,49 @@
+import getMillisecondsRemainingInTrial from './getMillisecondsRemainingInTrial';
+const hourInMilliseconds = 3600000;
+const dayInMilliseconds = 86400000;
+
+function getTextForNumber(singular: string, plural: string, count: number) {
+ if (!count) {
+ return '';
+ }
+
+ return count === 1 ? singular : plural;
+}
+
+export default function getDaysAndHoursRemainingInTrial(
+ currentTimeStamp: number,
+ trialStartedTimeStamp: number | unknown
+): string {
+ const defaultTime = 'No time';
+ if (!trialStartedTimeStamp) {
+ return defaultTime;
+ }
+
+ const millisecondsRemainingInTrial = getMillisecondsRemainingInTrial(
+ currentTimeStamp,
+ trialStartedTimeStamp
+ );
+ const daysRemaining = Math.floor(
+ millisecondsRemainingInTrial / dayInMilliseconds
+ );
+ const hoursRemaining = Math.ceil(
+ (millisecondsRemainingInTrial % dayInMilliseconds) / hourInMilliseconds
+ );
+
+ return millisecondsRemainingInTrial > 0
+ ? [
+ getTextForNumber(
+ `${daysRemaining} day`,
+ `${daysRemaining} days`,
+ daysRemaining
+ ),
+ getTextForNumber(
+ `${hoursRemaining} hour`,
+ `${hoursRemaining} hours`,
+ hoursRemaining
+ ),
+ ]
+ .filter((text) => text)
+ .join(', ')
+ : defaultTime;
+}
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 7da6679b..30dd1aee 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
-import getHoursRemainingInTrial from './getHoursRemainingInTrial';
+import getDaysAndHoursRemainingInTrial from './getDaysAndHoursRemainingInTrial';
import getLicenseErrorMessage from './getLicenseErrorMessage';
import isLicenseValid from './isLicenseValid';
import isTrialExpired from './isTrialExpired';
@@ -11,10 +11,6 @@ import {
TRIAL_STARTED_TIMESTAMP,
} from '../constants';
-function getTextForNumber(singular: string, plural: string, count: number) {
- return count === 1 ? singular : plural;
-}
-
export default async function getLicenseInformation(
context: vscode.ExtensionContext
): Promise {
@@ -27,9 +23,10 @@ export default async function getLicenseInformation(
const enterLicenseButton = `Enter license key `;
const changeLicenseButton = `Change license key `;
const retryValidationButton = `Retry license validation `;
+ const takeSurveyButton = `Get 7 more free days by taking a 2-minute survey `;
const isValid = await isLicenseValid(context);
- const previewExpired = isTrialExpired(previewStartedTimeStamp);
+ const isPreviewExpired = isTrialExpired(previewStartedTimeStamp);
if (isValid) {
return `Your Local CI license key is valid!
@@ -40,11 +37,12 @@ export default async function getLicenseInformation(
context.globalState.update(TRIAL_STARTED_TIMESTAMP, new Date().getTime());
return `Thanks for previewing Local CI!
This free trial will last for 2 days, then it will require a purchased license key.
+ ${takeSurveyButton}
${getLicenseLink}
${enterLicenseButton}
`;
}
- if (previewExpired && !!licenseKey && !isValid) {
+ if (isPreviewExpired && !!licenseKey && !isValid) {
return `There was an error validating the license key.
${getLicenseErrorMessage(
String(await context.secrets.get(LICENSE_ERROR))
@@ -54,24 +52,20 @@ export default async function getLicenseInformation(
${retryValidationButton}
`;
}
- if (previewExpired) {
+ if (isPreviewExpired) {
return `Thanks for previewing Local CI! The free preview is over.
Please enter a Local CI license key to keep using this.
+ ${takeSurveyButton}
${getLicenseLink}
${enterLicenseButton}
`;
}
- const timeRemaining = getHoursRemainingInTrial(
- new Date().getTime(),
- previewStartedTimeStamp
- );
-
return `Thanks for previewing Local CI!
- ${getTextForNumber(
- `Your free preview has ${timeRemaining} hour left.`,
- `Your free preview has ${timeRemaining} hours left.`,
- timeRemaining
- )}
+ ${getDaysAndHoursRemainingInTrial(
+ new Date().getTime(),
+ previewStartedTimeStamp
+ )} left in the preview
+ ${takeSurveyButton}
${getLicenseLink}
${enterLicenseButton}
`;
}
diff --git a/src/utils/getHoursRemainingInTrial.ts b/src/utils/getMillisecondsRemainingInTrial.ts
similarity index 58%
rename from src/utils/getHoursRemainingInTrial.ts
rename to src/utils/getMillisecondsRemainingInTrial.ts
index 499352b2..125e73f4 100644
--- a/src/utils/getHoursRemainingInTrial.ts
+++ b/src/utils/getMillisecondsRemainingInTrial.ts
@@ -1,15 +1,12 @@
import { TRIAL_LENGTH_IN_MILLISECONDS } from '../constants';
-const hourInMilliseconds = 3600000;
-export default function getHoursRemainingInTrial(
+export default function getMillisecondsRemainingInTrial(
currentTimeStamp: number,
trialStartedTimeStamp: number | unknown
): number {
const previewTimeElapsed = currentTimeStamp - Number(trialStartedTimeStamp);
return trialStartedTimeStamp
- ? Math.ceil(
- (TRIAL_LENGTH_IN_MILLISECONDS - previewTimeElapsed) / hourInMilliseconds
- )
+ ? TRIAL_LENGTH_IN_MILLISECONDS - previewTimeElapsed
: 0;
}
diff --git a/src/utils/isTrialExpired.ts b/src/utils/isTrialExpired.ts
index cef2319f..21d071cd 100644
--- a/src/utils/isTrialExpired.ts
+++ b/src/utils/isTrialExpired.ts
@@ -1,11 +1,14 @@
import { TRIAL_LENGTH_IN_MILLISECONDS } from '../constants';
+import getMillisecondsRemainingInTrial from './getMillisecondsRemainingInTrial';
export default function isTrialExpired(
trialStartedTimeStamp: number | unknown
): boolean {
return (
!trialStartedTimeStamp ||
- new Date().getTime() - Number(trialStartedTimeStamp) >
- TRIAL_LENGTH_IN_MILLISECONDS
+ getMillisecondsRemainingInTrial(
+ new Date().getTime(),
+ trialStartedTimeStamp
+ ) < TRIAL_LENGTH_IN_MILLISECONDS
);
}
diff --git a/webview/index.js b/webview/index.js
index a7cd1a8a..5945e58e 100644
--- a/webview/index.js
+++ b/webview/index.js
@@ -3,17 +3,21 @@
(function () {
function addLicenseHandlers() {
const vscode = acquireVsCodeApi();
- document
- .getElementById('enter-license')
- .addEventListener('click', () =>
- vscode.postMessage({ type: 'enterLicense' })
- );
+ const elementListeners = {
+ 'enter-license': 'enterLicense',
+ 'retry-license-validation': 'retryLicenseValidation',
+ 'take-survey': 'takeSurvey',
+ };
- document
- .getElementById('retry-license-validation')
- .addEventListener('click', () =>
- vscode.postMessage({ type: 'retryLicenseValidation' })
- );
+ Object.keys(elementListeners).forEach(
+ (elementId) => {
+ document
+ .getElementById(elementId)
+ .addEventListener('click', () =>
+ vscode.postMessage({ type: elementListeners[elementId] })
+ );
+ }
+ );
}
// Mainly copied from @wordpress/dom-ready https://github.com/WordPress/gutenberg/blob/3da717b8d0ac7d7821fc6d0475695ccf3ae2829f/packages/dom-ready/src/index.js#L31
From e853d3851a7471df69ed57fe9fec7d15faa74dc0 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Wed, 1 Dec 2021 21:55:05 -0600
Subject: [PATCH 06/24] Extend the trial by 15 days on filling out the survey
---
.nvmrc | 2 +-
package-lock.json | 2 +-
package.json | 2 +-
src/classes/JobProvider.ts | 6 +-
src/classes/LicenseProvider.ts | 27 ++++++++-
src/constants/index.ts | 2 +
src/extension.ts | 3 -
.../getDaysAndHoursRemainingInTrial.test.ts | 55 +++++++++++++++---
.../getMillisecondsRemainingInTrial.test.ts | 24 ++++++--
src/test/suite/utils/isTrialExpired.test.ts | 56 ++++++++++++++++++-
src/utils/getDaysAndHoursRemainingInTrial.ts | 51 +++--------------
src/utils/getLicenseInformation.ts | 33 +++++++----
src/utils/getMillisecondsRemainingInTrial.ts | 7 +--
src/utils/getPrettyPrintedTimeRemaining.ts | 52 +++++++++++++++++
src/utils/getTrialLength.ts | 14 +++++
src/utils/isTrialExpired.ts | 9 +--
webview/index.js | 31 +++++-----
webview/vscode.css | 24 +++++---
18 files changed, 291 insertions(+), 109 deletions(-)
create mode 100644 src/utils/getPrettyPrintedTimeRemaining.ts
create mode 100644 src/utils/getTrialLength.ts
diff --git a/.nvmrc b/.nvmrc
index 64f5a0a6..b6a7d89c 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-node
+16
diff --git a/package-lock.json b/package-lock.json
index 370ef098..b0245aeb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -48,7 +48,7 @@
"webpack-cli": "^4.7.0"
},
"engines": {
- "node": ">=16",
+ "node": "=16",
"vscode": "^1.59.0"
}
},
diff --git a/package.json b/package.json
index 514e93f9..0e956823 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,7 @@
"qna": "https://github.com/getlocalci/local-ci/discussions",
"engines": {
"vscode": "^1.59.0",
- "node": ">=16"
+ "node": "16"
},
"os": [
"!win32"
diff --git a/src/classes/JobProvider.ts b/src/classes/JobProvider.ts
index 9230c867..6105c101 100644
--- a/src/classes/JobProvider.ts
+++ b/src/classes/JobProvider.ts
@@ -15,6 +15,7 @@ import getAllConfigFilePaths from '../utils/getAllConfigFilePaths';
import getConfigFilePath from '../utils/getConfigFilePath';
import getDockerError from '../utils/getDockerError';
import getProcessFilePath from '../utils/getProcessFilePath';
+import getTrialLength from '../utils/getTrialLength';
import isDockerRunning from '../utils/isDockerRunning';
import isLicenseValid from '../utils/isLicenseValid';
import isTrialExpired from '../utils/isTrialExpired';
@@ -73,7 +74,10 @@ export default class JobProvider
const shouldEnableExtension =
(await isLicenseValid(this.context)) ||
- !isTrialExpired(this.context.globalState.get(TRIAL_STARTED_TIMESTAMP));
+ !isTrialExpired(
+ this.context.globalState.get(TRIAL_STARTED_TIMESTAMP),
+ getTrialLength(this.context)
+ );
const dockerRunning = isDockerRunning();
if (shouldEnableExtension && dockerRunning) {
diff --git a/src/classes/LicenseProvider.ts b/src/classes/LicenseProvider.ts
index fea88751..2a143fe5 100644
--- a/src/classes/LicenseProvider.ts
+++ b/src/classes/LicenseProvider.ts
@@ -1,8 +1,15 @@
import * as vscode from 'vscode';
-import { LICENSE_ERROR, SURVEY_URL } from '../constants';
+import {
+ HAS_EXTENDED_TRIAL,
+ LICENSE_ERROR,
+ SURVEY_URL,
+ TRIAL_STARTED_TIMESTAMP,
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
+} from '../constants';
import getLicenseErrorMessage from '../utils/getLicenseErrorMessage';
import getLicenseInformation from '../utils/getLicenseInformation';
import isLicenseValid from '../utils/isLicenseValid';
+import getPrettyPrintedTimeRemaining from '../utils/getPrettyPrintedTimeRemaining';
import showLicenseInput from '../utils/showLicenseInput';
function getNonce() {
@@ -37,7 +44,7 @@ export default class LicenseProvider implements vscode.WebviewViewProvider {
localResourceRoots: [this.extensionUri],
};
- await this.load();
+ this.load();
webviewView.webview.onDidReceiveMessage(async (data) => {
if (data.type === 'enterLicense') {
@@ -68,8 +75,22 @@ export default class LicenseProvider implements vscode.WebviewViewProvider {
}
if (data.type === 'takeSurvey') {
- // @todo: Set globalState to extend the preview length.
+ if (this.context.globalState.get(HAS_EXTENDED_TRIAL)) {
+ return;
+ }
+
+ this.load();
+ this.context.globalState.update(HAS_EXTENDED_TRIAL, true);
+ this.context.globalState.update(
+ TRIAL_STARTED_TIMESTAMP,
+ new Date().getTime()
+ );
vscode.env.openExternal(vscode.Uri.parse(SURVEY_URL));
+ vscode.window.showInformationMessage(
+ `Thanks, your free preview is now ${getPrettyPrintedTimeRemaining(
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS
+ )} longer`
+ );
}
});
}
diff --git a/src/constants/index.ts b/src/constants/index.ts
index 4d182d80..4bb40880 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -41,6 +41,8 @@ export const LICENSE_VALIDITY = 'local-ci.license.validity';
export const LICENSE_VALIDITY_CACHE_EXPIRATION =
'local-ci.license.cache.expiration';
export const TRIAL_LENGTH_IN_MILLISECONDS = 172800000; // 2 days.
+export const EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS = 1296000000; // 15 days.
+export const HAS_EXTENDED_TRIAL = 'local-ci.license.trial-extended.survey';
export const TRIAL_STARTED_TIMESTAMP =
'local-ci.license.trial-started.timestamp';
export const CONTAINER_STORAGE_DIRECTORY = '/tmp/local-ci';
diff --git a/src/extension.ts b/src/extension.ts
index ff0e1501..72be54da 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -22,7 +22,6 @@ import getConfig from './utils/getConfig';
import getConfigFilePath from './utils/getConfigFilePath';
import getDebuggingTerminalName from './utils/getDebuggingTerminalName';
import getFinalTerminalName from './utils/getFinalTerminalName';
-import getLicenseInformation from './utils/getLicenseInformation';
import getProcessedConfig from './utils/getProcessedConfig';
import getProcessFilePath from './utils/getProcessFilePath';
import getRepoBasename from './utils/getRepoBasename';
@@ -255,6 +254,4 @@ export function activate(context: vscode.ExtensionContext): void {
}
},
});
-
- getLicenseInformation(context);
}
diff --git a/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts b/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts
index c61bee9d..e38c835b 100644
--- a/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts
@@ -1,22 +1,35 @@
import * as assert from 'assert';
+import { TRIAL_LENGTH_IN_MILLISECONDS } from '../../../constants';
import getDaysAndHoursRemainingInTrial from '../../../utils/getDaysAndHoursRemainingInTrial';
+const minuteInMilliseconds = 60000;
const hourInMilliseconds = 3600000;
+
suite('getDaysAndHoursRemainingInTrial', () => {
test('no trial started timestamp', () => {
const time = new Date().getTime();
- assert.strictEqual(getDaysAndHoursRemainingInTrial(time, null), 'No time');
+ assert.strictEqual(
+ getDaysAndHoursRemainingInTrial(time, null, TRIAL_LENGTH_IN_MILLISECONDS),
+ 'No time'
+ );
});
test('entire trial remaining', () => {
const time = new Date().getTime();
- assert.strictEqual(getDaysAndHoursRemainingInTrial(time, time), '2 days');
+ assert.strictEqual(
+ getDaysAndHoursRemainingInTrial(time, time, TRIAL_LENGTH_IN_MILLISECONDS),
+ '2 days'
+ );
});
test('entire trial remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(time, time - 10 * hourInMilliseconds),
+ getDaysAndHoursRemainingInTrial(
+ time,
+ time - 10 * hourInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
'1 day, 14 hours'
);
});
@@ -24,7 +37,11 @@ suite('getDaysAndHoursRemainingInTrial', () => {
test('one day remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(time, time - 24 * hourInMilliseconds),
+ getDaysAndHoursRemainingInTrial(
+ time,
+ time - 24 * hourInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
'1 day'
);
});
@@ -32,7 +49,11 @@ suite('getDaysAndHoursRemainingInTrial', () => {
test('five hours remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(time, time - 43 * hourInMilliseconds),
+ getDaysAndHoursRemainingInTrial(
+ time,
+ time - 43 * hourInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
'5 hours'
);
});
@@ -40,15 +61,35 @@ suite('getDaysAndHoursRemainingInTrial', () => {
test('one hour remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(time, time - 47 * hourInMilliseconds),
+ getDaysAndHoursRemainingInTrial(
+ time,
+ time - 47 * hourInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
'1 hour'
);
});
+ test('one minute remaining', () => {
+ const time = new Date().getTime();
+ assert.strictEqual(
+ getDaysAndHoursRemainingInTrial(
+ time,
+ time - 47 * hourInMilliseconds - 59 * minuteInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
+ '1 minute'
+ );
+ });
+
test('no time remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(time, time - 48 * hourInMilliseconds),
+ getDaysAndHoursRemainingInTrial(
+ time,
+ time - 48 * hourInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
'No time'
);
});
diff --git a/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts b/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
index 6524e21c..86d8df21 100644
--- a/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
@@ -1,17 +1,25 @@
import * as assert from 'assert';
+import { TRIAL_LENGTH_IN_MILLISECONDS } from '../../../constants';
import getMillisecondsRemainingInTrial from '../../../utils/getMillisecondsRemainingInTrial';
const hourInMilliseconds = 3600000;
suite('getMillisecondsRemainingInTrial', () => {
test('entire trial remaining', () => {
const time = new Date().getTime();
- assert.strictEqual(getMillisecondsRemainingInTrial(time, time), 172800000);
+ assert.strictEqual(
+ getMillisecondsRemainingInTrial(time, time, TRIAL_LENGTH_IN_MILLISECONDS),
+ 172800000
+ );
});
test('one day remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getMillisecondsRemainingInTrial(time, time - 24 * hourInMilliseconds),
+ getMillisecondsRemainingInTrial(
+ time,
+ time - 24 * hourInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
86400000
);
});
@@ -19,7 +27,11 @@ suite('getMillisecondsRemainingInTrial', () => {
test('one hour remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getMillisecondsRemainingInTrial(time, time - 47 * hourInMilliseconds),
+ getMillisecondsRemainingInTrial(
+ time,
+ time - 47 * hourInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
3600000
);
});
@@ -27,7 +39,11 @@ suite('getMillisecondsRemainingInTrial', () => {
test('no time remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getMillisecondsRemainingInTrial(time, time - 48 * hourInMilliseconds),
+ getMillisecondsRemainingInTrial(
+ time,
+ time - 48 * hourInMilliseconds,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
0
);
});
diff --git a/src/test/suite/utils/isTrialExpired.test.ts b/src/test/suite/utils/isTrialExpired.test.ts
index a23ab8a4..0cc8d79c 100644
--- a/src/test/suite/utils/isTrialExpired.test.ts
+++ b/src/test/suite/utils/isTrialExpired.test.ts
@@ -1,22 +1,72 @@
import * as assert from 'assert';
import * as mocha from 'mocha';
import * as sinon from 'sinon';
+import {
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
+ TRIAL_LENGTH_IN_MILLISECONDS,
+} from '../../../constants';
import isTrialExpired from '../../../utils/isTrialExpired';
mocha.afterEach(() => {
sinon.restore();
});
+const extendedTrial =
+ TRIAL_LENGTH_IN_MILLISECONDS + EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS;
+
suite('isTrialExpired', () => {
test('preview just began', () => {
- assert.strictEqual(isTrialExpired(new Date().getTime()), false);
+ assert.strictEqual(
+ isTrialExpired(new Date().getTime(), TRIAL_LENGTH_IN_MILLISECONDS),
+ false
+ );
});
test('preview began 2 days and 1 millisecond ago', () => {
- assert.strictEqual(isTrialExpired(new Date().getTime() - 172800001), true);
+ assert.strictEqual(
+ isTrialExpired(
+ new Date().getTime() - 172800001,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
+ true
+ );
});
test('preview began a week ago', () => {
- assert.strictEqual(isTrialExpired(new Date().getTime() - 604800000), true);
+ assert.strictEqual(
+ isTrialExpired(
+ new Date().getTime() - 604800000,
+ TRIAL_LENGTH_IN_MILLISECONDS
+ ),
+ true
+ );
+ });
+
+ test('preview just began and was extended', () => {
+ assert.strictEqual(
+ isTrialExpired(new Date().getTime(), TRIAL_LENGTH_IN_MILLISECONDS),
+ false
+ );
+ });
+
+ test('preview began 2 days and 10 milliseconds ago and was extended', () => {
+ assert.strictEqual(
+ isTrialExpired(new Date().getTime() - 172800010, extendedTrial),
+ false
+ );
+ });
+
+ test('preview began a week ago and was extended', () => {
+ assert.strictEqual(
+ isTrialExpired(new Date().getTime() - 604800000, extendedTrial),
+ false
+ );
+ });
+
+ test('preview began a 17 days and 1 millisecond ago and was extended', () => {
+ assert.strictEqual(
+ isTrialExpired(new Date().getTime() - 1468800001, extendedTrial),
+ true
+ );
});
});
diff --git a/src/utils/getDaysAndHoursRemainingInTrial.ts b/src/utils/getDaysAndHoursRemainingInTrial.ts
index 01daa439..81b5be15 100644
--- a/src/utils/getDaysAndHoursRemainingInTrial.ts
+++ b/src/utils/getDaysAndHoursRemainingInTrial.ts
@@ -1,49 +1,16 @@
import getMillisecondsRemainingInTrial from './getMillisecondsRemainingInTrial';
-const hourInMilliseconds = 3600000;
-const dayInMilliseconds = 86400000;
-
-function getTextForNumber(singular: string, plural: string, count: number) {
- if (!count) {
- return '';
- }
-
- return count === 1 ? singular : plural;
-}
+import getPrettyPrintedTimeRemaining from './getPrettyPrintedTimeRemaining';
export default function getDaysAndHoursRemainingInTrial(
currentTimeStamp: number,
- trialStartedTimeStamp: number | unknown
+ trialStartedTimeStamp: number | unknown,
+ trialLengthInMilliseconds: number
): string {
- const defaultTime = 'No time';
- if (!trialStartedTimeStamp) {
- return defaultTime;
- }
-
- const millisecondsRemainingInTrial = getMillisecondsRemainingInTrial(
- currentTimeStamp,
- trialStartedTimeStamp
+ return getPrettyPrintedTimeRemaining(
+ getMillisecondsRemainingInTrial(
+ currentTimeStamp,
+ trialStartedTimeStamp,
+ trialLengthInMilliseconds
+ )
);
- const daysRemaining = Math.floor(
- millisecondsRemainingInTrial / dayInMilliseconds
- );
- const hoursRemaining = Math.ceil(
- (millisecondsRemainingInTrial % dayInMilliseconds) / hourInMilliseconds
- );
-
- return millisecondsRemainingInTrial > 0
- ? [
- getTextForNumber(
- `${daysRemaining} day`,
- `${daysRemaining} days`,
- daysRemaining
- ),
- getTextForNumber(
- `${hoursRemaining} hour`,
- `${hoursRemaining} hours`,
- hoursRemaining
- ),
- ]
- .filter((text) => text)
- .join(', ')
- : defaultTime;
}
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 30dd1aee..3f6678ea 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -1,6 +1,7 @@
import * as vscode from 'vscode';
-import getDaysAndHoursRemainingInTrial from './getDaysAndHoursRemainingInTrial';
import getLicenseErrorMessage from './getLicenseErrorMessage';
+import getPrettyPrintedTimeRemaining from './getPrettyPrintedTimeRemaining';
+import getTrialLength from './getTrialLength';
import isLicenseValid from './isLicenseValid';
import isTrialExpired from './isTrialExpired';
import {
@@ -9,6 +10,7 @@ import {
LICENSE_KEY,
LICENSE_VALIDITY,
TRIAL_STARTED_TIMESTAMP,
+ HAS_EXTENDED_TRIAL,
} from '../constants';
export default async function getLicenseInformation(
@@ -19,25 +21,34 @@ export default async function getLicenseInformation(
TRIAL_STARTED_TIMESTAMP
);
const licenseKey = await context.secrets.get(LICENSE_KEY);
- const getLicenseLink = `Buy license `;
+ const getLicenseLink = `Buy license `;
const enterLicenseButton = `Enter license key `;
const changeLicenseButton = `Change license key `;
const retryValidationButton = `Retry license validation `;
- const takeSurveyButton = `Get 7 more free days by taking a 2-minute survey `;
+ const takeSurveyButton = `Get 15 more free days by taking a 2-minute anonymous survey `;
const isValid = await isLicenseValid(context);
- const isPreviewExpired = isTrialExpired(previewStartedTimeStamp);
+ const hasExtendedTrial = !!context.globalState.get(HAS_EXTENDED_TRIAL);
+ const trialLengthInMilliseconds = getTrialLength(context);
+ const isPreviewExpired = isTrialExpired(
+ previewStartedTimeStamp,
+ trialLengthInMilliseconds
+ );
if (isValid) {
return `Your Local CI license key is valid!
${changeLicenseButton}`;
}
+ const daysAndHoursRemainingInTrial = getPrettyPrintedTimeRemaining(
+ trialLengthInMilliseconds
+ );
+
if (!previewStartedTimeStamp && !licenseKey) {
context.globalState.update(TRIAL_STARTED_TIMESTAMP, new Date().getTime());
return `Thanks for previewing Local CI!
- This free trial will last for 2 days, then it will require a purchased license key.
- ${takeSurveyButton}
+ This free trial will last for ${daysAndHoursRemainingInTrial}.
+ ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${getLicenseLink}
${enterLicenseButton}
`;
}
@@ -49,23 +60,21 @@ export default async function getLicenseInformation(
)}
${getLicenseLink}
${enterLicenseButton}
+ ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${retryValidationButton}
`;
}
if (isPreviewExpired) {
return `Thanks for previewing Local CI! The free preview is over.
Please enter a Local CI license key to keep using this.
- ${takeSurveyButton}
+ ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${getLicenseLink}
${enterLicenseButton}
`;
}
return `Thanks for previewing Local CI!
- ${getDaysAndHoursRemainingInTrial(
- new Date().getTime(),
- previewStartedTimeStamp
- )} left in the preview
- ${takeSurveyButton}
+ ${daysAndHoursRemainingInTrial} left in the free preview.
+ ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${getLicenseLink}
${enterLicenseButton}
`;
}
diff --git a/src/utils/getMillisecondsRemainingInTrial.ts b/src/utils/getMillisecondsRemainingInTrial.ts
index 125e73f4..4fbaf2ca 100644
--- a/src/utils/getMillisecondsRemainingInTrial.ts
+++ b/src/utils/getMillisecondsRemainingInTrial.ts
@@ -1,12 +1,11 @@
-import { TRIAL_LENGTH_IN_MILLISECONDS } from '../constants';
-
export default function getMillisecondsRemainingInTrial(
currentTimeStamp: number,
- trialStartedTimeStamp: number | unknown
+ trialStartedTimeStamp: number | unknown,
+ trialLengthInMilliseconds: number
): number {
const previewTimeElapsed = currentTimeStamp - Number(trialStartedTimeStamp);
return trialStartedTimeStamp
- ? TRIAL_LENGTH_IN_MILLISECONDS - previewTimeElapsed
+ ? trialLengthInMilliseconds - previewTimeElapsed
: 0;
}
diff --git a/src/utils/getPrettyPrintedTimeRemaining.ts b/src/utils/getPrettyPrintedTimeRemaining.ts
new file mode 100644
index 00000000..65c8df51
--- /dev/null
+++ b/src/utils/getPrettyPrintedTimeRemaining.ts
@@ -0,0 +1,52 @@
+const minuteInMilliseconds = 60000;
+const hourInMilliseconds = 3600000;
+const dayInMilliseconds = 86400000;
+
+function getTextForNumber(singular: string, plural: string, count: number) {
+ if (!count) {
+ return '';
+ }
+
+ return count === 1 ? singular : plural;
+}
+
+export default function getPrettyPrintedTimeRemaining(
+ millisecondsRemaining: number
+): string {
+ const defaultTime = 'No time';
+ if (millisecondsRemaining <= 0) {
+ return defaultTime;
+ }
+
+ if (millisecondsRemaining < hourInMilliseconds) {
+ const minutesRemaining = Math.floor(
+ millisecondsRemaining / minuteInMilliseconds
+ );
+
+ return getTextForNumber(
+ `${minutesRemaining} minute`,
+ `${minutesRemaining} minutes`,
+ minutesRemaining
+ );
+ }
+
+ const daysRemaining = Math.floor(millisecondsRemaining / dayInMilliseconds);
+ const hoursRemaining = Math.floor(
+ (millisecondsRemaining % dayInMilliseconds) / hourInMilliseconds
+ );
+
+ return [
+ getTextForNumber(
+ `${daysRemaining} day`,
+ `${daysRemaining} days`,
+ daysRemaining
+ ),
+ getTextForNumber(
+ `${hoursRemaining} hour`,
+ `${hoursRemaining} hours`,
+ hoursRemaining
+ ),
+ ]
+ .filter((text) => text)
+ .join(', ');
+}
diff --git a/src/utils/getTrialLength.ts b/src/utils/getTrialLength.ts
new file mode 100644
index 00000000..2e0d2337
--- /dev/null
+++ b/src/utils/getTrialLength.ts
@@ -0,0 +1,14 @@
+import * as vscode from 'vscode';
+import {
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
+ HAS_EXTENDED_TRIAL,
+ TRIAL_LENGTH_IN_MILLISECONDS,
+} from '../constants';
+
+export default function getTrialLength(
+ context: vscode.ExtensionContext
+): number {
+ return context.globalState.get(HAS_EXTENDED_TRIAL)
+ ? EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS + TRIAL_LENGTH_IN_MILLISECONDS
+ : TRIAL_LENGTH_IN_MILLISECONDS;
+}
diff --git a/src/utils/isTrialExpired.ts b/src/utils/isTrialExpired.ts
index 21d071cd..eb804000 100644
--- a/src/utils/isTrialExpired.ts
+++ b/src/utils/isTrialExpired.ts
@@ -1,14 +1,15 @@
-import { TRIAL_LENGTH_IN_MILLISECONDS } from '../constants';
import getMillisecondsRemainingInTrial from './getMillisecondsRemainingInTrial';
export default function isTrialExpired(
- trialStartedTimeStamp: number | unknown
+ trialStartedTimeStamp: number | unknown,
+ trialLengthInMilliseconds: number
): boolean {
return (
!trialStartedTimeStamp ||
getMillisecondsRemainingInTrial(
new Date().getTime(),
- trialStartedTimeStamp
- ) < TRIAL_LENGTH_IN_MILLISECONDS
+ trialStartedTimeStamp,
+ trialLengthInMilliseconds
+ ) <= 0
);
}
diff --git a/webview/index.js b/webview/index.js
index 5945e58e..70db278c 100644
--- a/webview/index.js
+++ b/webview/index.js
@@ -3,21 +3,24 @@
(function () {
function addLicenseHandlers() {
const vscode = acquireVsCodeApi();
- const elementListeners = {
- 'enter-license': 'enterLicense',
- 'retry-license-validation': 'retryLicenseValidation',
- 'take-survey': 'takeSurvey',
- };
- Object.keys(elementListeners).forEach(
- (elementId) => {
- document
- .getElementById(elementId)
- .addEventListener('click', () =>
- vscode.postMessage({ type: elementListeners[elementId] })
- );
- }
- );
+ document
+ .getElementById('take-survey')
+ .addEventListener('click', () =>
+ vscode.postMessage({ type: 'takeSurvey' })
+ );
+
+ document
+ .getElementById('enter-license')
+ .addEventListener('click', () =>
+ vscode.postMessage({ type: 'enterLicense' })
+ );
+
+ document
+ .getElementById('retry-license-validation')
+ .addEventListener('click', () =>
+ vscode.postMessage({ type: 'retryLicenseValidation' })
+ );
}
// Mainly copied from @wordpress/dom-ready https://github.com/WordPress/gutenberg/blob/3da717b8d0ac7d7821fc6d0475695ccf3ae2829f/packages/dom-ready/src/index.js#L31
diff --git a/webview/vscode.css b/webview/vscode.css
index 82d8e4e8..316ebcfb 100644
--- a/webview/vscode.css
+++ b/webview/vscode.css
@@ -34,10 +34,25 @@ a.button {
text-align: center;
outline: 1px solid transparent;
outline-offset: 2px !important;
+}
+
+button.primary,
+a.primary {
color: var(--vscode-button-foreground);
background: var(--vscode-button-background);
}
+button.secondary,
+a.secondary {
+ color: var(--vscode-button-secondaryForeground);
+ background: var(--vscode-button-secondaryBackground);
+}
+
+button.secondary:hover
+a.button.secondary:hover {
+ background: var(--vscode-button-secondaryHoverBackground);
+}
+
button:hover,
a.button:hover {
cursor: pointer;
@@ -48,12 +63,3 @@ button:focus,
a.button:focus {
outline-color: var(--vscode-focusBorder);
}
-
-button.secondary {
- color: var(--vscode-button-secondaryForeground);
- background: var(--vscode-button-secondaryBackground);
-}
-
-button.secondary:hover {
- background: var(--vscode-button-secondaryHoverBackground);
-}
From 9aefcd22146ebe8a201c8d091fc105cadb7264c1 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Wed, 1 Dec 2021 21:59:16 -0600
Subject: [PATCH 07/24] Remove = before Node version
Also, remove await before
showLicenseInput().
---
package-lock.json | 2 +-
src/classes/LicenseProvider.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index b0245aeb..bd417712 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -48,7 +48,7 @@
"webpack-cli": "^4.7.0"
},
"engines": {
- "node": "=16",
+ "node": "16",
"vscode": "^1.59.0"
}
},
diff --git a/src/classes/LicenseProvider.ts b/src/classes/LicenseProvider.ts
index 2a143fe5..c15f538b 100644
--- a/src/classes/LicenseProvider.ts
+++ b/src/classes/LicenseProvider.ts
@@ -48,7 +48,7 @@ export default class LicenseProvider implements vscode.WebviewViewProvider {
webviewView.webview.onDidReceiveMessage(async (data) => {
if (data.type === 'enterLicense') {
- await showLicenseInput(
+ showLicenseInput(
this.context,
() => this.load(),
() => this.licenseSuccessCallback()
From a2abc588c1c909ebf62d771465c54a5cf26a62a6 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Wed, 1 Dec 2021 22:33:08 -0600
Subject: [PATCH 08/24] Bump vscode-test to the latest
---
package-lock.json | 14 ++++----
package.json | 2 +-
...est.ts => getTimeRemainingInTrial.test.ts} | 26 +++++++-------
src/utils/getLicenseInformation.ts | 15 ++++----
src/utils/getPrettyPrintedTimeRemaining.ts | 34 ++++++++-----------
...gInTrial.ts => getTimeRemainingInTrial.ts} | 2 +-
6 files changed, 46 insertions(+), 47 deletions(-)
rename src/test/suite/utils/{getDaysAndHoursRemainingInTrial.test.ts => getTimeRemainingInTrial.test.ts} (73%)
rename src/utils/{getDaysAndHoursRemainingInTrial.ts => getTimeRemainingInTrial.ts} (88%)
diff --git a/package-lock.json b/package-lock.json
index bd417712..aa313e98 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -43,7 +43,7 @@
"typescript": "^4.3.2",
"util": "^0.12.4",
"vsce": "^2.5.0",
- "vscode-test": "^1.5.2",
+ "vscode-test": "^1.6.1",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0"
},
@@ -4884,9 +4884,9 @@
}
},
"node_modules/vscode-test": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.5.2.tgz",
- "integrity": "sha512-x9PVfKxF6EInH9iSFGQi0V8H5zIW1fC7RAer6yNQR6sy3WyOwlWkuT3I+wf75xW/cO53hxMi1aj/EvqQfDFOAg==",
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.6.1.tgz",
+ "integrity": "sha512-086q88T2ca1k95mUzffvbzb7esqQNvJgiwY4h29ukPhFo8u+vXOOmelUoU5EQUHs3Of8+JuQ3oGdbVCqaxuTXA==",
"dev": true,
"dependencies": {
"http-proxy-agent": "^4.0.1",
@@ -9168,9 +9168,9 @@
}
},
"vscode-test": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.5.2.tgz",
- "integrity": "sha512-x9PVfKxF6EInH9iSFGQi0V8H5zIW1fC7RAer6yNQR6sy3WyOwlWkuT3I+wf75xW/cO53hxMi1aj/EvqQfDFOAg==",
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.6.1.tgz",
+ "integrity": "sha512-086q88T2ca1k95mUzffvbzb7esqQNvJgiwY4h29ukPhFo8u+vXOOmelUoU5EQUHs3Of8+JuQ3oGdbVCqaxuTXA==",
"dev": true,
"requires": {
"http-proxy-agent": "^4.0.1",
diff --git a/package.json b/package.json
index 0e956823..46fc0d29 100644
--- a/package.json
+++ b/package.json
@@ -287,7 +287,7 @@
"typescript": "^4.3.2",
"util": "^0.12.4",
"vsce": "^2.5.0",
- "vscode-test": "^1.5.2",
+ "vscode-test": "^1.6.1",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0"
},
diff --git a/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
similarity index 73%
rename from src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts
rename to src/test/suite/utils/getTimeRemainingInTrial.test.ts
index e38c835b..cae2c292 100644
--- a/src/test/suite/utils/getDaysAndHoursRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
@@ -1,15 +1,15 @@
import * as assert from 'assert';
import { TRIAL_LENGTH_IN_MILLISECONDS } from '../../../constants';
-import getDaysAndHoursRemainingInTrial from '../../../utils/getDaysAndHoursRemainingInTrial';
+import getTimeRemainingInTrial from '../../../utils/getTimeRemainingInTrial';
const minuteInMilliseconds = 60000;
const hourInMilliseconds = 3600000;
-suite('getDaysAndHoursRemainingInTrial', () => {
+suite('getTimeRemainingInTrial', () => {
test('no trial started timestamp', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(time, null, TRIAL_LENGTH_IN_MILLISECONDS),
+ getTimeRemainingInTrial(time, null, TRIAL_LENGTH_IN_MILLISECONDS),
'No time'
);
});
@@ -17,27 +17,27 @@ suite('getDaysAndHoursRemainingInTrial', () => {
test('entire trial remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(time, time, TRIAL_LENGTH_IN_MILLISECONDS),
+ getTimeRemainingInTrial(time, time, TRIAL_LENGTH_IN_MILLISECONDS),
'2 days'
);
});
- test('entire trial remaining', () => {
+ test('1 day, 14 hours remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(
+ getTimeRemainingInTrial(
time,
time - 10 * hourInMilliseconds,
TRIAL_LENGTH_IN_MILLISECONDS
),
- '1 day, 14 hours'
+ '1 day'
);
});
- test('one day remaining', () => {
+ test('exactly one day remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(
+ getTimeRemainingInTrial(
time,
time - 24 * hourInMilliseconds,
TRIAL_LENGTH_IN_MILLISECONDS
@@ -49,7 +49,7 @@ suite('getDaysAndHoursRemainingInTrial', () => {
test('five hours remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(
+ getTimeRemainingInTrial(
time,
time - 43 * hourInMilliseconds,
TRIAL_LENGTH_IN_MILLISECONDS
@@ -61,7 +61,7 @@ suite('getDaysAndHoursRemainingInTrial', () => {
test('one hour remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(
+ getTimeRemainingInTrial(
time,
time - 47 * hourInMilliseconds,
TRIAL_LENGTH_IN_MILLISECONDS
@@ -73,7 +73,7 @@ suite('getDaysAndHoursRemainingInTrial', () => {
test('one minute remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(
+ getTimeRemainingInTrial(
time,
time - 47 * hourInMilliseconds - 59 * minuteInMilliseconds,
TRIAL_LENGTH_IN_MILLISECONDS
@@ -85,7 +85,7 @@ suite('getDaysAndHoursRemainingInTrial', () => {
test('no time remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
- getDaysAndHoursRemainingInTrial(
+ getTimeRemainingInTrial(
time,
time - 48 * hourInMilliseconds,
TRIAL_LENGTH_IN_MILLISECONDS
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 3f6678ea..64eecbfd 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -12,6 +12,7 @@ import {
TRIAL_STARTED_TIMESTAMP,
HAS_EXTENDED_TRIAL,
} from '../constants';
+import getTimeRemainingInTrial from './getTimeRemainingInTrial';
export default async function getLicenseInformation(
context: vscode.ExtensionContext
@@ -40,14 +41,12 @@ export default async function getLicenseInformation(
${changeLicenseButton}`;
}
- const daysAndHoursRemainingInTrial = getPrettyPrintedTimeRemaining(
- trialLengthInMilliseconds
- );
-
if (!previewStartedTimeStamp && !licenseKey) {
context.globalState.update(TRIAL_STARTED_TIMESTAMP, new Date().getTime());
return `Thanks for previewing Local CI!
- This free trial will last for ${daysAndHoursRemainingInTrial}.
+ This free trial will last for ${getPrettyPrintedTimeRemaining(
+ trialLengthInMilliseconds
+ )}.
${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${getLicenseLink}
${enterLicenseButton}
`;
@@ -73,7 +72,11 @@ export default async function getLicenseInformation(
}
return `Thanks for previewing Local CI!
- ${daysAndHoursRemainingInTrial} left in the free preview.
+ ${getTimeRemainingInTrial(
+ new Date().getTime(),
+ context.globalState.get(TRIAL_STARTED_TIMESTAMP),
+ trialLengthInMilliseconds
+ )} left in the free preview.
${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${getLicenseLink}
${enterLicenseButton}
`;
diff --git a/src/utils/getPrettyPrintedTimeRemaining.ts b/src/utils/getPrettyPrintedTimeRemaining.ts
index 65c8df51..802d0199 100644
--- a/src/utils/getPrettyPrintedTimeRemaining.ts
+++ b/src/utils/getPrettyPrintedTimeRemaining.ts
@@ -3,10 +3,6 @@ const hourInMilliseconds = 3600000;
const dayInMilliseconds = 86400000;
function getTextForNumber(singular: string, plural: string, count: number) {
- if (!count) {
- return '';
- }
-
return count === 1 ? singular : plural;
}
@@ -30,23 +26,23 @@ export default function getPrettyPrintedTimeRemaining(
);
}
- const daysRemaining = Math.floor(millisecondsRemaining / dayInMilliseconds);
- const hoursRemaining = Math.floor(
- (millisecondsRemaining % dayInMilliseconds) / hourInMilliseconds
- );
+ if (millisecondsRemaining < dayInMilliseconds) {
+ const hoursRemaining = Math.floor(
+ millisecondsRemaining / hourInMilliseconds
+ );
- return [
- getTextForNumber(
- `${daysRemaining} day`,
- `${daysRemaining} days`,
- daysRemaining
- ),
- getTextForNumber(
+ return getTextForNumber(
`${hoursRemaining} hour`,
`${hoursRemaining} hours`,
hoursRemaining
- ),
- ]
- .filter((text) => text)
- .join(', ');
+ );
+ }
+
+ const daysRemaining = Math.floor(millisecondsRemaining / dayInMilliseconds);
+
+ return getTextForNumber(
+ `${daysRemaining} day`,
+ `${daysRemaining} days`,
+ daysRemaining
+ );
}
diff --git a/src/utils/getDaysAndHoursRemainingInTrial.ts b/src/utils/getTimeRemainingInTrial.ts
similarity index 88%
rename from src/utils/getDaysAndHoursRemainingInTrial.ts
rename to src/utils/getTimeRemainingInTrial.ts
index 81b5be15..4c7f7bc7 100644
--- a/src/utils/getDaysAndHoursRemainingInTrial.ts
+++ b/src/utils/getTimeRemainingInTrial.ts
@@ -1,7 +1,7 @@
import getMillisecondsRemainingInTrial from './getMillisecondsRemainingInTrial';
import getPrettyPrintedTimeRemaining from './getPrettyPrintedTimeRemaining';
-export default function getDaysAndHoursRemainingInTrial(
+export default function getTimeRemainingInTrial(
currentTimeStamp: number,
trialStartedTimeStamp: number | unknown,
trialLengthInMilliseconds: number
From 731fd366b815ea0e38f595a6b03bd00db0b34dc1 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Wed, 1 Dec 2021 23:53:18 -0600
Subject: [PATCH 09/24] Have an hour count at less than 2 days
---
src/classes/LicenseProvider.ts | 4 +-
.../utils/getTimeRemainingInTrial.test.ts | 59 +++++++++++++------
src/utils/getPrettyPrintedTimeRemaining.ts | 28 ++++++---
3 files changed, 64 insertions(+), 27 deletions(-)
diff --git a/src/classes/LicenseProvider.ts b/src/classes/LicenseProvider.ts
index c15f538b..2acc6fd6 100644
--- a/src/classes/LicenseProvider.ts
+++ b/src/classes/LicenseProvider.ts
@@ -1,15 +1,15 @@
import * as vscode from 'vscode';
import {
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
HAS_EXTENDED_TRIAL,
LICENSE_ERROR,
SURVEY_URL,
TRIAL_STARTED_TIMESTAMP,
- EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
} from '../constants';
import getLicenseErrorMessage from '../utils/getLicenseErrorMessage';
import getLicenseInformation from '../utils/getLicenseInformation';
-import isLicenseValid from '../utils/isLicenseValid';
import getPrettyPrintedTimeRemaining from '../utils/getPrettyPrintedTimeRemaining';
+import isLicenseValid from '../utils/isLicenseValid';
import showLicenseInput from '../utils/showLicenseInput';
function getNonce() {
diff --git a/src/test/suite/utils/getTimeRemainingInTrial.test.ts b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
index cae2c292..bc506802 100644
--- a/src/test/suite/utils/getTimeRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
@@ -4,91 +4,114 @@ import getTimeRemainingInTrial from '../../../utils/getTimeRemainingInTrial';
const minuteInMilliseconds = 60000;
const hourInMilliseconds = 3600000;
+const dayInMilliseconds = 86400000;
suite('getTimeRemainingInTrial', () => {
+ const time = new Date().getTime();
test('no trial started timestamp', () => {
- const time = new Date().getTime();
assert.strictEqual(
getTimeRemainingInTrial(time, null, TRIAL_LENGTH_IN_MILLISECONDS),
'No time'
);
});
- test('entire trial remaining', () => {
- const time = new Date().getTime();
+ test('14 days and 1 hour remaining', () => {
assert.strictEqual(
- getTimeRemainingInTrial(time, time, TRIAL_LENGTH_IN_MILLISECONDS),
+ getTimeRemainingInTrial(
+ time,
+ time,
+ 14 * dayInMilliseconds + hourInMilliseconds
+ ),
+ '14 days'
+ );
+ });
+
+ test('14 days remaining', () => {
+ assert.strictEqual(
+ getTimeRemainingInTrial(time, time, 14 * dayInMilliseconds),
+ '14 days'
+ );
+ });
+
+ test('2 hours remaining', () => {
+ assert.strictEqual(
+ getTimeRemainingInTrial(time, time, dayInMilliseconds * 2),
'2 days'
);
});
test('1 day, 14 hours remaining', () => {
- const time = new Date().getTime();
assert.strictEqual(
getTimeRemainingInTrial(
time,
time - 10 * hourInMilliseconds,
- TRIAL_LENGTH_IN_MILLISECONDS
+ dayInMilliseconds * 2
),
- '1 day'
+ '1 day, 14 hours'
);
});
test('exactly one day remaining', () => {
- const time = new Date().getTime();
assert.strictEqual(
getTimeRemainingInTrial(
time,
time - 24 * hourInMilliseconds,
- TRIAL_LENGTH_IN_MILLISECONDS
+ dayInMilliseconds * 2
),
'1 day'
);
});
test('five hours remaining', () => {
- const time = new Date().getTime();
assert.strictEqual(
getTimeRemainingInTrial(
time,
time - 43 * hourInMilliseconds,
- TRIAL_LENGTH_IN_MILLISECONDS
+ dayInMilliseconds * 2
),
'5 hours'
);
});
test('one hour remaining', () => {
- const time = new Date().getTime();
assert.strictEqual(
getTimeRemainingInTrial(
time,
time - 47 * hourInMilliseconds,
- TRIAL_LENGTH_IN_MILLISECONDS
+ dayInMilliseconds * 2
),
'1 hour'
);
});
- test('one minute remaining', () => {
- const time = new Date().getTime();
+ test('23 minutes remaining', () => {
+ assert.strictEqual(
+ getTimeRemainingInTrial(
+ time,
+ time - 47 * hourInMilliseconds - 37 * minuteInMilliseconds,
+ dayInMilliseconds * 2
+ ),
+ '23 minutes'
+ );
+ });
+
+ test('1 minute remaining', () => {
assert.strictEqual(
getTimeRemainingInTrial(
time,
time - 47 * hourInMilliseconds - 59 * minuteInMilliseconds,
- TRIAL_LENGTH_IN_MILLISECONDS
+ dayInMilliseconds * 2
),
'1 minute'
);
});
test('no time remaining', () => {
- const time = new Date().getTime();
assert.strictEqual(
getTimeRemainingInTrial(
time,
time - 48 * hourInMilliseconds,
- TRIAL_LENGTH_IN_MILLISECONDS
+ dayInMilliseconds * 2
),
'No time'
);
diff --git a/src/utils/getPrettyPrintedTimeRemaining.ts b/src/utils/getPrettyPrintedTimeRemaining.ts
index 802d0199..740cd3c6 100644
--- a/src/utils/getPrettyPrintedTimeRemaining.ts
+++ b/src/utils/getPrettyPrintedTimeRemaining.ts
@@ -3,6 +3,10 @@ const hourInMilliseconds = 3600000;
const dayInMilliseconds = 86400000;
function getTextForNumber(singular: string, plural: string, count: number) {
+ if (!count) {
+ return '';
+ }
+
return count === 1 ? singular : plural;
}
@@ -26,16 +30,26 @@ export default function getPrettyPrintedTimeRemaining(
);
}
- if (millisecondsRemaining < dayInMilliseconds) {
+ if (millisecondsRemaining < 2 * dayInMilliseconds) {
+ const daysRemaining = Math.floor(millisecondsRemaining / dayInMilliseconds);
const hoursRemaining = Math.floor(
- millisecondsRemaining / hourInMilliseconds
+ (millisecondsRemaining % dayInMilliseconds) / hourInMilliseconds
);
- return getTextForNumber(
- `${hoursRemaining} hour`,
- `${hoursRemaining} hours`,
- hoursRemaining
- );
+ return [
+ getTextForNumber(
+ `${daysRemaining} day`,
+ `${daysRemaining} days`,
+ daysRemaining
+ ),
+ getTextForNumber(
+ `${hoursRemaining} hour`,
+ `${hoursRemaining} hours`,
+ hoursRemaining
+ ),
+ ]
+ .filter((timeRemaining) => timeRemaining)
+ .join(', ');
}
const daysRemaining = Math.floor(millisecondsRemaining / dayInMilliseconds);
From 8bcf36bbb9a20c0bb71fef0b77a0cd545e2a26a4 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 2 Dec 2021 00:09:16 -0600
Subject: [PATCH 10/24] If there's less than a minute remaining, show 'No time'
---
.../utils/getMillisecondsRemainingInTrial.test.ts | 4 ++--
.../suite/utils/getTimeRemainingInTrial.test.ts | 13 ++++++++++++-
src/test/suite/utils/isTrialExpired.test.ts | 2 +-
src/utils/getPrettyPrintedTimeRemaining.ts | 2 +-
4 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts b/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
index 86d8df21..973bf3eb 100644
--- a/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
@@ -12,7 +12,7 @@ suite('getMillisecondsRemainingInTrial', () => {
);
});
- test('one day remaining', () => {
+ test('1 day remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
getMillisecondsRemainingInTrial(
@@ -24,7 +24,7 @@ suite('getMillisecondsRemainingInTrial', () => {
);
});
- test('one hour remaining', () => {
+ test('1 hour remaining', () => {
const time = new Date().getTime();
assert.strictEqual(
getMillisecondsRemainingInTrial(
diff --git a/src/test/suite/utils/getTimeRemainingInTrial.test.ts b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
index bc506802..aac12a93 100644
--- a/src/test/suite/utils/getTimeRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
@@ -51,7 +51,7 @@ suite('getTimeRemainingInTrial', () => {
);
});
- test('exactly one day remaining', () => {
+ test('exactly 1 day remaining', () => {
assert.strictEqual(
getTimeRemainingInTrial(
time,
@@ -106,6 +106,17 @@ suite('getTimeRemainingInTrial', () => {
);
});
+ test('30 seconds remaining', () => {
+ assert.strictEqual(
+ getTimeRemainingInTrial(
+ time,
+ time - 47 * hourInMilliseconds - 59 * minuteInMilliseconds - 30000,
+ dayInMilliseconds * 2
+ ),
+ 'No time'
+ );
+ });
+
test('no time remaining', () => {
assert.strictEqual(
getTimeRemainingInTrial(
diff --git a/src/test/suite/utils/isTrialExpired.test.ts b/src/test/suite/utils/isTrialExpired.test.ts
index 0cc8d79c..0a7fa627 100644
--- a/src/test/suite/utils/isTrialExpired.test.ts
+++ b/src/test/suite/utils/isTrialExpired.test.ts
@@ -63,7 +63,7 @@ suite('isTrialExpired', () => {
);
});
- test('preview began a 17 days and 1 millisecond ago and was extended', () => {
+ test('preview began 17 days and 1 millisecond ago and was extended', () => {
assert.strictEqual(
isTrialExpired(new Date().getTime() - 1468800001, extendedTrial),
true
diff --git a/src/utils/getPrettyPrintedTimeRemaining.ts b/src/utils/getPrettyPrintedTimeRemaining.ts
index 740cd3c6..48a65821 100644
--- a/src/utils/getPrettyPrintedTimeRemaining.ts
+++ b/src/utils/getPrettyPrintedTimeRemaining.ts
@@ -14,7 +14,7 @@ export default function getPrettyPrintedTimeRemaining(
millisecondsRemaining: number
): string {
const defaultTime = 'No time';
- if (millisecondsRemaining <= 0) {
+ if (millisecondsRemaining < minuteInMilliseconds) {
return defaultTime;
}
From a6053dbfd8734637d565a47c491d9c62e32c8815 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 2 Dec 2021 00:16:38 -0600
Subject: [PATCH 11/24] Prevent a JS error in addLicenseHandlers()
Before, there was an error
when the button wasn't in the DOM.
---
webview/index.js | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/webview/index.js b/webview/index.js
index 70db278c..7dffb96b 100644
--- a/webview/index.js
+++ b/webview/index.js
@@ -3,24 +3,20 @@
(function () {
function addLicenseHandlers() {
const vscode = acquireVsCodeApi();
+ const listenerElements = {
+ 'take-survey': 'takeSurvey',
+ 'enter-license': 'enterLicense',
+ 'retry-license-validation': 'retryLicenseValidation',
+ };
- document
- .getElementById('take-survey')
- .addEventListener('click', () =>
- vscode.postMessage({ type: 'takeSurvey' })
- );
-
- document
- .getElementById('enter-license')
- .addEventListener('click', () =>
- vscode.postMessage({ type: 'enterLicense' })
- );
-
- document
- .getElementById('retry-license-validation')
- .addEventListener('click', () =>
- vscode.postMessage({ type: 'retryLicenseValidation' })
- );
+ Object.keys(listenerElements).forEach((elementId) => {
+ const element = document.getElementById(elementId)
+ if (element) {
+ element.addEventListener('click', () =>
+ vscode.postMessage({ type: listenerElements[elementId] })
+ );
+ }
+ });
}
// Mainly copied from @wordpress/dom-ready https://github.com/WordPress/gutenberg/blob/3da717b8d0ac7d7821fc6d0475695ccf3ae2829f/packages/dom-ready/src/index.js#L31
From fdddfc394194ad5bfe1f0202cbfba90d4d1fd96c Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 2 Dec 2021 00:22:06 -0600
Subject: [PATCH 12/24] Always show the hours if there are any after days
Otherwise, 17 days immediately
goes down to 16 days,
as it's Math.floor().
---
.../utils/getTimeRemainingInTrial.test.ts | 2 +-
src/utils/getPrettyPrintedTimeRemaining.ts | 44 +++++++------------
2 files changed, 18 insertions(+), 28 deletions(-)
diff --git a/src/test/suite/utils/getTimeRemainingInTrial.test.ts b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
index aac12a93..6d6914d0 100644
--- a/src/test/suite/utils/getTimeRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
@@ -22,7 +22,7 @@ suite('getTimeRemainingInTrial', () => {
time,
14 * dayInMilliseconds + hourInMilliseconds
),
- '14 days'
+ '14 days, 1 hour'
);
});
diff --git a/src/utils/getPrettyPrintedTimeRemaining.ts b/src/utils/getPrettyPrintedTimeRemaining.ts
index 48a65821..4af2479e 100644
--- a/src/utils/getPrettyPrintedTimeRemaining.ts
+++ b/src/utils/getPrettyPrintedTimeRemaining.ts
@@ -30,33 +30,23 @@ export default function getPrettyPrintedTimeRemaining(
);
}
- if (millisecondsRemaining < 2 * dayInMilliseconds) {
- const daysRemaining = Math.floor(millisecondsRemaining / dayInMilliseconds);
- const hoursRemaining = Math.floor(
- (millisecondsRemaining % dayInMilliseconds) / hourInMilliseconds
- );
-
- return [
- getTextForNumber(
- `${daysRemaining} day`,
- `${daysRemaining} days`,
- daysRemaining
- ),
- getTextForNumber(
- `${hoursRemaining} hour`,
- `${hoursRemaining} hours`,
- hoursRemaining
- ),
- ]
- .filter((timeRemaining) => timeRemaining)
- .join(', ');
- }
-
const daysRemaining = Math.floor(millisecondsRemaining / dayInMilliseconds);
-
- return getTextForNumber(
- `${daysRemaining} day`,
- `${daysRemaining} days`,
- daysRemaining
+ const hoursRemaining = Math.floor(
+ (millisecondsRemaining % dayInMilliseconds) / hourInMilliseconds
);
+
+ return [
+ getTextForNumber(
+ `${daysRemaining} day`,
+ `${daysRemaining} days`,
+ daysRemaining
+ ),
+ getTextForNumber(
+ `${hoursRemaining} hour`,
+ `${hoursRemaining} hours`,
+ hoursRemaining
+ ),
+ ]
+ .filter((timeRemaining) => timeRemaining)
+ .join(', ');
}
From 53ce8ade6acc278625887e37af084def79535ebf Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 2 Dec 2021 00:40:33 -0600
Subject: [PATCH 13/24] Close the tag, add a dynamic number of days
---
src/utils/getLicenseInformation.ts | 16 ++++++++++------
webview/vscode.css | 1 +
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 64eecbfd..9022c5bc 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -11,6 +11,7 @@ import {
LICENSE_VALIDITY,
TRIAL_STARTED_TIMESTAMP,
HAS_EXTENDED_TRIAL,
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
} from '../constants';
import getTimeRemainingInTrial from './getTimeRemainingInTrial';
@@ -21,12 +22,15 @@ export default async function getLicenseInformation(
const previewStartedTimeStamp = context.globalState.get(
TRIAL_STARTED_TIMESTAMP
);
+ const daysInMilliseconds = 86400000;
const licenseKey = await context.secrets.get(LICENSE_KEY);
const getLicenseLink = `Buy license `;
const enterLicenseButton = `Enter license key `;
const changeLicenseButton = `Change license key `;
const retryValidationButton = `Retry license validation `;
- const takeSurveyButton = `Get 15 more free days by taking a 2-minute anonymous survey `;
+ const takeSurveyButton = `Get ${
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS / daysInMilliseconds
+ } more free days by taking a 2-minute anonymous survey `;
const isValid = await isLicenseValid(context);
const hasExtendedTrial = !!context.globalState.get(HAS_EXTENDED_TRIAL);
@@ -47,7 +51,7 @@ export default async function getLicenseInformation(
This free trial will last for ${getPrettyPrintedTimeRemaining(
trialLengthInMilliseconds
)}.
- ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
+ ${hasExtendedTrial ? '' : `
${takeSurveyButton}
`}
${getLicenseLink}
${enterLicenseButton}
`;
}
@@ -59,14 +63,14 @@ export default async function getLicenseInformation(
)}
${getLicenseLink}
${enterLicenseButton}
- ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
+ ${hasExtendedTrial ? '' : `
${takeSurveyButton}
`}
${retryValidationButton}
`;
}
if (isPreviewExpired) {
return `Thanks for previewing Local CI! The free preview is over.
Please enter a Local CI license key to keep using this.
- ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
+ ${hasExtendedTrial ? '' : `
${takeSurveyButton}
`}
${getLicenseLink}
${enterLicenseButton}
`;
}
@@ -76,8 +80,8 @@ export default async function getLicenseInformation(
new Date().getTime(),
context.globalState.get(TRIAL_STARTED_TIMESTAMP),
trialLengthInMilliseconds
- )} left in the free preview.
- ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
+ )} left in this free preview.
+ ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${getLicenseLink}
${enterLicenseButton}
`;
}
diff --git a/webview/vscode.css b/webview/vscode.css
index 316ebcfb..71a43791 100644
--- a/webview/vscode.css
+++ b/webview/vscode.css
@@ -34,6 +34,7 @@ a.button {
text-align: center;
outline: 1px solid transparent;
outline-offset: 2px !important;
+ text-decoration: none;
}
button.primary,
From 3f49b250dc3a1028af01e5cfb5e18337bc21094d Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 2 Dec 2021 00:55:35 -0600
Subject: [PATCH 14/24] Change the to a
---
src/utils/getLicenseInformation.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 9022c5bc..113492bd 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -1,6 +1,7 @@
import * as vscode from 'vscode';
import getLicenseErrorMessage from './getLicenseErrorMessage';
import getPrettyPrintedTimeRemaining from './getPrettyPrintedTimeRemaining';
+import getTimeRemainingInTrial from './getTimeRemainingInTrial';
import getTrialLength from './getTrialLength';
import isLicenseValid from './isLicenseValid';
import isTrialExpired from './isTrialExpired';
@@ -13,7 +14,6 @@ import {
HAS_EXTENDED_TRIAL,
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
} from '../constants';
-import getTimeRemainingInTrial from './getTimeRemainingInTrial';
export default async function getLicenseInformation(
context: vscode.ExtensionContext
@@ -28,9 +28,9 @@ export default async function getLicenseInformation(
const enterLicenseButton = `Enter license key `;
const changeLicenseButton = `Change license key `;
const retryValidationButton = `Retry license validation `;
- const takeSurveyButton = `Get ${
+ const takeSurveyButton = `Get ${
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS / daysInMilliseconds
- } more free days by taking a 2-minute anonymous survey `;
+ } more free days by taking a 2-minute anonymous survey `;
const isValid = await isLicenseValid(context);
const hasExtendedTrial = !!context.globalState.get(HAS_EXTENDED_TRIAL);
From 9b4023c8981bbdca78829f179aad539576f31be4 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 2 Dec 2021 01:28:20 -0600
Subject: [PATCH 15/24] Round the hours up, so it doesn't show 1 day, 23 hours
right away
It's confusing when it says
there's a 2-day trial,
but it shows 1 day, 23 hours.
---
src/extension.ts | 4 ++++
.../utils/getTimeRemainingInTrial.test.ts | 19 +++++++++++++++----
src/utils/getLicenseInformation.ts | 12 ------------
src/utils/getPrettyPrintedTimeRemaining.ts | 8 +++++---
4 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/src/extension.ts b/src/extension.ts
index 72be54da..b9575a35 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -13,6 +13,7 @@ import {
JOB_TREE_VIEW_ID,
RUN_JOB_COMMAND,
SELECTED_CONFIG_PATH,
+ TRIAL_STARTED_TIMESTAMP,
} from './constants';
import cleanUpCommittedImages from './utils/cleanUpCommittedImages';
import disposeTerminalsForJob from './utils/disposeTerminalsForJob';
@@ -30,6 +31,9 @@ import showLicenseInput from './utils/showLicenseInput';
import writeProcessFile from './utils/writeProcessFile';
export function activate(context: vscode.ExtensionContext): void {
+ if (!context.globalState.get(TRIAL_STARTED_TIMESTAMP)) {
+ context.globalState.update(TRIAL_STARTED_TIMESTAMP, new Date().getTime());
+ }
const jobProvider = new JobProvider(context);
vscode.window.registerTreeDataProvider(JOB_TREE_VIEW_ID, jobProvider);
diff --git a/src/test/suite/utils/getTimeRemainingInTrial.test.ts b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
index 6d6914d0..207b48f1 100644
--- a/src/test/suite/utils/getTimeRemainingInTrial.test.ts
+++ b/src/test/suite/utils/getTimeRemainingInTrial.test.ts
@@ -15,14 +15,25 @@ suite('getTimeRemainingInTrial', () => {
);
});
- test('14 days and 1 hour remaining', () => {
+ test('14 days and 13 hours remaining', () => {
assert.strictEqual(
getTimeRemainingInTrial(
time,
time,
- 14 * dayInMilliseconds + hourInMilliseconds
+ 14 * dayInMilliseconds + 13 * hourInMilliseconds
),
- '14 days, 1 hour'
+ '15 days'
+ );
+ });
+
+ test('14 days and 11 hours remaining', () => {
+ assert.strictEqual(
+ getTimeRemainingInTrial(
+ time,
+ time,
+ 14 * dayInMilliseconds + 11 * hourInMilliseconds
+ ),
+ '14 days, 11 hours'
);
});
@@ -47,7 +58,7 @@ suite('getTimeRemainingInTrial', () => {
time - 10 * hourInMilliseconds,
dayInMilliseconds * 2
),
- '1 day, 14 hours'
+ '2 days'
);
});
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 113492bd..94494ace 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -1,6 +1,5 @@
import * as vscode from 'vscode';
import getLicenseErrorMessage from './getLicenseErrorMessage';
-import getPrettyPrintedTimeRemaining from './getPrettyPrintedTimeRemaining';
import getTimeRemainingInTrial from './getTimeRemainingInTrial';
import getTrialLength from './getTrialLength';
import isLicenseValid from './isLicenseValid';
@@ -45,17 +44,6 @@ export default async function getLicenseInformation(
${changeLicenseButton}`;
}
- if (!previewStartedTimeStamp && !licenseKey) {
- context.globalState.update(TRIAL_STARTED_TIMESTAMP, new Date().getTime());
- return `Thanks for previewing Local CI!
- This free trial will last for ${getPrettyPrintedTimeRemaining(
- trialLengthInMilliseconds
- )}.
- ${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
- ${getLicenseLink}
- ${enterLicenseButton}
`;
- }
-
if (isPreviewExpired && !!licenseKey && !isValid) {
return `There was an error validating the license key.
${getLicenseErrorMessage(
diff --git a/src/utils/getPrettyPrintedTimeRemaining.ts b/src/utils/getPrettyPrintedTimeRemaining.ts
index 4af2479e..f9fbb667 100644
--- a/src/utils/getPrettyPrintedTimeRemaining.ts
+++ b/src/utils/getPrettyPrintedTimeRemaining.ts
@@ -30,9 +30,11 @@ export default function getPrettyPrintedTimeRemaining(
);
}
- const daysRemaining = Math.floor(millisecondsRemaining / dayInMilliseconds);
- const hoursRemaining = Math.floor(
- (millisecondsRemaining % dayInMilliseconds) / hourInMilliseconds
+ const daysRemaining = Math.round(millisecondsRemaining / dayInMilliseconds);
+ const hoursRemaining = Math.max(
+ (millisecondsRemaining - daysRemaining * dayInMilliseconds) /
+ hourInMilliseconds,
+ 0
);
return [
From d622b72dc805595de45b24c0dd93bc1c6b69c7f2 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Thu, 2 Dec 2021 01:30:43 -0600
Subject: [PATCH 16/24] Rename daysInMilliseconds to be singular
---
src/utils/getLicenseInformation.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 94494ace..fbe6dfd5 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -21,14 +21,14 @@ export default async function getLicenseInformation(
const previewStartedTimeStamp = context.globalState.get(
TRIAL_STARTED_TIMESTAMP
);
- const daysInMilliseconds = 86400000;
+ const dayInMilliseconds = 86400000;
const licenseKey = await context.secrets.get(LICENSE_KEY);
const getLicenseLink = `Buy license `;
const enterLicenseButton = `Enter license key `;
const changeLicenseButton = `Change license key `;
const retryValidationButton = `Retry license validation `;
const takeSurveyButton = `Get ${
- EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS / daysInMilliseconds
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS / dayInMilliseconds
} more free days by taking a 2-minute anonymous survey `;
const isValid = await isLicenseValid(context);
From dd9d47abcf17d6b206fe9f0dc44fb9f45966a974 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Fri, 3 Dec 2021 23:28:31 -0600
Subject: [PATCH 17/24] Prevent a decimal hours count
This shouldn't be a decimal like
1.4232 hours.
---
.vscode/extensions.json | 2 --
src/utils/getPrettyPrintedTimeRemaining.ts | 10 ++++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index c53bbbfd..ab1fbf45 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,6 +1,4 @@
{
- // See http://go.microsoft.com/fwlink/?LinkId=827846
- // for the documentation about the extensions.json format
"recommendations": [
"dbaeumer.vscode-eslint",
"amodio.tsl-problem-matcher"
diff --git a/src/utils/getPrettyPrintedTimeRemaining.ts b/src/utils/getPrettyPrintedTimeRemaining.ts
index f9fbb667..bf934331 100644
--- a/src/utils/getPrettyPrintedTimeRemaining.ts
+++ b/src/utils/getPrettyPrintedTimeRemaining.ts
@@ -31,10 +31,12 @@ export default function getPrettyPrintedTimeRemaining(
}
const daysRemaining = Math.round(millisecondsRemaining / dayInMilliseconds);
- const hoursRemaining = Math.max(
- (millisecondsRemaining - daysRemaining * dayInMilliseconds) /
- hourInMilliseconds,
- 0
+ const hoursRemaining = Math.floor(
+ Math.max(
+ (millisecondsRemaining - daysRemaining * dayInMilliseconds) /
+ hourInMilliseconds,
+ 0
+ )
);
return [
From cecbf8ca57f016ee4ace934074a777f33dc74284 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Sat, 4 Dec 2021 00:02:43 -0600
Subject: [PATCH 18/24] Add a link for a research interview
---
src/constants/index.ts | 1 +
src/utils/getLicenseInformation.ts | 19 ++++++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/constants/index.ts b/src/constants/index.ts
index 4bb40880..b7693ed5 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -50,6 +50,7 @@ export const HOST_TMP_DIRECTORY = '/tmp/local-ci'; // Also hard-coded in node/un
export const PROCESS_FILE_DIRECTORY = `${HOST_TMP_DIRECTORY}/process`;
export const LOCAL_VOLUME_DIRECTORY = `${HOST_TMP_DIRECTORY}/volume`;
export const RUN_JOB_COMMAND = 'local-ci.job.run';
+export const SCHEDULE_INTERVIEW_URL = 'https://example.com';
export const SUPPRESS_UNCOMMITTED_FILE_WARNING =
'local-ci.suppress-warning.uncommitted';
export const SURVEY_URL = 'https://example.com';
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index fbe6dfd5..fda0a251 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -5,13 +5,14 @@ import getTrialLength from './getTrialLength';
import isLicenseValid from './isLicenseValid';
import isTrialExpired from './isTrialExpired';
import {
+ EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
GET_LICENSE_KEY_URL,
+ HAS_EXTENDED_TRIAL,
LICENSE_ERROR,
LICENSE_KEY,
LICENSE_VALIDITY,
TRIAL_STARTED_TIMESTAMP,
- HAS_EXTENDED_TRIAL,
- EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
+ SCHEDULE_INTERVIEW_URL,
} from '../constants';
export default async function getLicenseInformation(
@@ -23,13 +24,14 @@ export default async function getLicenseInformation(
);
const dayInMilliseconds = 86400000;
const licenseKey = await context.secrets.get(LICENSE_KEY);
- const getLicenseLink = `Buy license `;
+ const getLicenseLink = `Buy license `;
const enterLicenseButton = `Enter license key `;
const changeLicenseButton = `Change license key `;
const retryValidationButton = `Retry license validation `;
const takeSurveyButton = `Get ${
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS / dayInMilliseconds
} more free days by taking a 2-minute anonymous survey `;
+ const scheduleInterviewLink = `Get a free lifetime license by doing a 30-minute Zoom interview about why you didn't buy`;
const isValid = await isLicenseValid(context);
const hasExtendedTrial = !!context.globalState.get(HAS_EXTENDED_TRIAL);
@@ -39,6 +41,11 @@ export default async function getLicenseInformation(
trialLengthInMilliseconds
);
+ const isPreviewExpiredByOneDay = isTrialExpired(
+ previewStartedTimeStamp,
+ trialLengthInMilliseconds + dayInMilliseconds
+ );
+
if (isValid) {
return `Your Local CI license key is valid!
${changeLicenseButton}`;
@@ -55,6 +62,12 @@ export default async function getLicenseInformation(
${retryValidationButton}
`;
}
+ if (isPreviewExpiredByOneDay) {
+ return `${scheduleInterviewLink}
+ No sales pitch, I have nothing to sell you after giving you the free lifetime license.
+ ${enterLicenseButton}
`;
+ }
+
if (isPreviewExpired) {
return `Thanks for previewing Local CI! The free preview is over.
Please enter a Local CI license key to keep using this.
From efa66d5df9803e2f7b5fa50121fc36569d04be7a Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Sat, 4 Dec 2021 00:22:56 -0600
Subject: [PATCH 19/24] Add a 'Complain' link, thanks to Jason Cohen's idea
Following:
https://blog.asmartbear.com/more-sales-customer-feedback.html
---
src/utils/getLicenseInformation.ts | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index fda0a251..1712e01a 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -32,6 +32,8 @@ export default async function getLicenseInformation(
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS / dayInMilliseconds
} more free days by taking a 2-minute anonymous survey`;
const scheduleInterviewLink = `Get a free lifetime license by doing a 30-minute Zoom interview about why you didn't buy`;
+ const complainUrl = 'mailto:ryan@getlocalci.com';
+ const complainLink = ` Complain to me `;
const isValid = await isLicenseValid(context);
const hasExtendedTrial = !!context.globalState.get(HAS_EXTENDED_TRIAL);
@@ -48,7 +50,8 @@ export default async function getLicenseInformation(
if (isValid) {
return `Your Local CI license key is valid!
- ${changeLicenseButton}`;
+ ${changeLicenseButton}
+ ${complainLink}
`;
}
if (isPreviewExpired && !!licenseKey && !isValid) {
@@ -59,7 +62,8 @@ export default async function getLicenseInformation(
${getLicenseLink}
${enterLicenseButton}
${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
- ${retryValidationButton}
`;
+ ${retryValidationButton}
+ ${complainLink}
`;
}
if (isPreviewExpiredByOneDay) {
@@ -73,7 +77,8 @@ export default async function getLicenseInformation(
Please enter a Local CI license key to keep using this.
${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${getLicenseLink}
- ${enterLicenseButton}
`;
+ ${enterLicenseButton}
+ ${complainLink}
`;
}
return `Thanks for previewing Local CI!
@@ -84,5 +89,6 @@ export default async function getLicenseInformation(
)} left in this free preview.
${hasExtendedTrial ? '' : `${takeSurveyButton}
`}
${getLicenseLink}
- ${enterLicenseButton}
`;
+ ${enterLicenseButton}
+ ${complainLink}
`;
}
From 676979e9143ebf45cbb9848d05006b0c39e43ebb Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Sat, 4 Dec 2021 21:15:22 -0600
Subject: [PATCH 20/24] Remove needless const, rearrange destructuring
---
src/utils/getLicenseInformation.ts | 8 ++++----
src/utils/getPrettyPrintedTimeRemaining.ts | 3 +--
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 1712e01a..55267338 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -11,8 +11,8 @@ import {
LICENSE_ERROR,
LICENSE_KEY,
LICENSE_VALIDITY,
- TRIAL_STARTED_TIMESTAMP,
SCHEDULE_INTERVIEW_URL,
+ TRIAL_STARTED_TIMESTAMP,
} from '../constants';
export default async function getLicenseInformation(
@@ -31,9 +31,9 @@ export default async function getLicenseInformation(
const takeSurveyButton = `Get ${
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS / dayInMilliseconds
} more free days by taking a 2-minute anonymous survey `;
- const scheduleInterviewLink = `Get a free lifetime license by doing a 30-minute Zoom interview about why you didn't buy`;
- const complainUrl = 'mailto:ryan@getlocalci.com';
- const complainLink = ` Complain to me `;
+ const scheduleInterviewLink = `Get a free lifetime license by doing a 30-minute Zoom user research interview`;
+ const complainUri = 'mailto:ryan@getlocalci.com';
+ const complainLink = ` Complain to me `;
const isValid = await isLicenseValid(context);
const hasExtendedTrial = !!context.globalState.get(HAS_EXTENDED_TRIAL);
diff --git a/src/utils/getPrettyPrintedTimeRemaining.ts b/src/utils/getPrettyPrintedTimeRemaining.ts
index bf934331..2f4e1531 100644
--- a/src/utils/getPrettyPrintedTimeRemaining.ts
+++ b/src/utils/getPrettyPrintedTimeRemaining.ts
@@ -13,9 +13,8 @@ function getTextForNumber(singular: string, plural: string, count: number) {
export default function getPrettyPrintedTimeRemaining(
millisecondsRemaining: number
): string {
- const defaultTime = 'No time';
if (millisecondsRemaining < minuteInMilliseconds) {
- return defaultTime;
+ return 'No time';
}
if (millisecondsRemaining < hourInMilliseconds) {
From 13cc31254fd834a688efeb3901cb76aaf674f042 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Sat, 4 Dec 2021 22:15:57 -0600
Subject: [PATCH 21/24] Change the URL to book a meeting
---
src/constants/index.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/constants/index.ts b/src/constants/index.ts
index b7693ed5..c48b7987 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -50,7 +50,8 @@ export const HOST_TMP_DIRECTORY = '/tmp/local-ci'; // Also hard-coded in node/un
export const PROCESS_FILE_DIRECTORY = `${HOST_TMP_DIRECTORY}/process`;
export const LOCAL_VOLUME_DIRECTORY = `${HOST_TMP_DIRECTORY}/volume`;
export const RUN_JOB_COMMAND = 'local-ci.job.run';
-export const SCHEDULE_INTERVIEW_URL = 'https://example.com';
+export const SCHEDULE_INTERVIEW_URL =
+ 'https://tidycal.com/localci/30-minute-meeting';
export const SUPPRESS_UNCOMMITTED_FILE_WARNING =
'local-ci.suppress-warning.uncommitted';
export const SURVEY_URL = 'https://example.com';
From 38ce98c01a99c7ec061dfbf16cd3cb3f28e54d47 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Sat, 4 Dec 2021 23:46:21 -0600
Subject: [PATCH 22/24] Add the survey URL
---
src/constants/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/constants/index.ts b/src/constants/index.ts
index c48b7987..089c0eeb 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -54,4 +54,4 @@ export const SCHEDULE_INTERVIEW_URL =
'https://tidycal.com/localci/30-minute-meeting';
export const SUPPRESS_UNCOMMITTED_FILE_WARNING =
'local-ci.suppress-warning.uncommitted';
-export const SURVEY_URL = 'https://example.com';
+export const SURVEY_URL = 'https://www.surveymonkey.com/r/localci';
From 93e015cdb8e46638e171589b38c984ff11883938 Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Sat, 4 Dec 2021 23:47:24 -0600
Subject: [PATCH 23/24] Bump the version to 1.0.2
---
CHANGELOG.md | 5 +++++
package-lock.json | 4 ++--
package.json | 2 +-
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77b3f64d..e84b0b50 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Change Log
+## 1.0.2 - 5 December 2021
+
+### Added
+- Extend the free preview for filling out a 2-minute survey. [#49](https://github.com/getlocalci/local-ci/pull/49/)
+
## 1.0.1 - 24 November 2021
### Added
diff --git a/package-lock.json b/package-lock.json
index aa313e98..dbcdbc9f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "local-ci",
- "version": "1.0.1",
+ "version": "1.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "local-ci",
- "version": "1.0.1",
+ "version": "1.0.2",
"hasInstallScript": true,
"license": "GPL-2.0-or-later",
"os": [
diff --git a/package.json b/package.json
index 46fc0d29..1d587177 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "local-ci",
"displayName": "Local CI",
"description": "Debug CircleCI® workflows locally, with Bash access during and after. Free preview, then paid.",
- "version": "1.0.1",
+ "version": "1.0.2",
"publisher": "LocalCI",
"contributors": [
"Ryan Kienstra"
From 7fb93fac8f2d16e216a215177ef2750c5a72525c Mon Sep 17 00:00:00 2001
From: Ryan Kienstra
Date: Sat, 4 Dec 2021 23:51:53 -0600
Subject: [PATCH 24/24] Fix the link to do the interview
Its closing tag should be a ,
not a .
---
src/utils/getLicenseInformation.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/utils/getLicenseInformation.ts b/src/utils/getLicenseInformation.ts
index 55267338..4ed93004 100644
--- a/src/utils/getLicenseInformation.ts
+++ b/src/utils/getLicenseInformation.ts
@@ -31,7 +31,7 @@ export default async function getLicenseInformation(
const takeSurveyButton = `Get ${
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS / dayInMilliseconds
} more free days by taking a 2-minute anonymous survey `;
- const scheduleInterviewLink = `Get a free lifetime license by doing a 30-minute Zoom user research interview`;
+ const scheduleInterviewLink = ` Get a free lifetime license by doing a 30-minute Zoom user research interview `;
const complainUri = 'mailto:ryan@getlocalci.com';
const complainLink = `Complain to me `;