Skip to content

Commit

Permalink
fix: Ask user to rate the Spell Checker. (#3570)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S authored Aug 26, 2024
1 parent c53eefa commit 4d2c51e
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 41 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@
{
"command": "cSpell.createCSpellTerminal",
"category": "Spell",
"title": "Create CSpell REPL Terminal",
"title": "Open a new CSpell REPL Terminal",
"icon": "$(terminal)"
},
{
Expand Down Expand Up @@ -637,10 +637,10 @@
"icon": "$(heart)"
},
{
"command": "cSpell.sponsorshipRequest",
"command": "cSpell.rateTheSpellChecker",
"category": "Spell",
"title": "Become a Sponsor of the Spell Checker",
"icon": "$(heart)"
"title": "Rate the Spell Checker",
"icon": "$(star)"
}
],
"languages": [
Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/commands.mts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import {
targetsForUri,
targetsFromConfigurationTarget,
} from './settings/targetHelpers.mjs';
import { about, callForSponsors, releaseNotes, reportIssue, sponsor, supportRequest } from './support/index.mjs';
import { about, rateTheSpellChecker, releaseNotes, reportIssue, sponsor, supportRequest } from './support/index.mjs';
import { experimentWithSymbols } from './symbolServer/index.mjs';
import { findNotebookCell } from './util/documentUri.js';
import { catchErrors, handleErrors } from './util/errors.js';
Expand Down Expand Up @@ -187,7 +187,7 @@ export const commandHandlers = {
'cSpell.reportIssue': reportIssue,
'cSpell.about': about,
'cSpell.sponsor': sponsor,
'cSpell.sponsorshipRequest': callForSponsors,
'cSpell.rateTheSpellChecker': rateTheSpellChecker,
'cSpell.releaseNotes': releaseNotes,

// Deprecated Commands
Expand Down
111 changes: 111 additions & 0 deletions packages/client/src/support/commands.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { commands, Uri, window } from 'vscode';

import { getExtensionContext } from '../di.mjs';
import { openExternalUrl } from '../util/openUrl.mjs';
import { openNegativeFeedbackIssue } from './openIssue.mjs';

export async function about(): Promise<void> {
const uriReadme = Uri.joinPath(getExtensionContext().extensionUri, 'resources/pages/About the Spell Checker.md');
return commands.executeCommand('markdown.showPreview', null, [uriReadme], { lock: true });
}

export function supportRequest(): Promise<void> {
return openMarkdown('resources/pages/Spell Checker Support Request.md');
}

export function reportIssue(): Promise<void> {
return openMarkdown('resources/pages/Spell Checker Report Issue.md');
}

export function sponsor(): Promise<boolean> {
return openExternalUrl('https://streetsidesoftware.com/sponsor/');
}

export async function rateTheSpellChecker(): Promise<void> {
const ratings = ['⭐️⭐️⭐️⭐️', '⭐️⭐️⭐️', '⭐️⭐️', '⭐️'];
const choice = await window.showInformationMessage('How would you rate the Spell Checker?', ...ratings);
if (!choice) {
// register that it was dismissed and reschedule.
return;
}
const idx = ratings.indexOf(choice);
const rating = 4 - idx;
if (rating === 1) {
const result = await window.showInformationMessage(
'Thank you for your feedback. Would you provide more detail on how the Spell Checker can be improved by opening an issue on GitHub?',
'Open Issue',
'Not Now',
);
if (result === 'Open Issue') {
return openNegativeFeedbackIssue();
}
return;
}
if (rating === 2) {
await window.showInformationMessage('Thank you for your feedback.', 'Close');
return;
}
const resultGTD = await window.showInformationMessage(
'Does the Spell Checker help you avoid spelling mistakes and get things done?',
'Yes',
'No',
);

switch (resultGTD) {
case 'Yes': {
const result = await window.showInformationMessage(
'Thank you for your feedback. The Spell Checker needs your support to continue to improve. Would you consider sponsoring the Spell Checker?',
'Open Sponsor Page',
'Ask me Later',
'No',
);
switch (result) {
case 'Open Sponsor Page':
await sponsor();
return;
case 'Ask me Later':
// register that it was dismissed and reschedule.
await window.showInformationMessage('Thank you. We will ask again in about a month.', 'Close');
return;
case 'No': {
const result = await window.showInformationMessage('Are you already a sponsor?', 'Yes', 'No');
if (result === 'Yes') {
// register response and do not ask again.
await window.showInformationMessage('Thank you for your support!', 'Close');
return;
}
await window.showInformationMessage(
'Thank you for your feedback. Would you provide more detail on how the Spell Checker can be improved by opening an issue on GitHub?',
'Open Issue',
'Not Now',
);
return;
}
}
return;
}
case 'No': {
const result = await window.showInformationMessage(
'Thank you for your feedback. Would you provide more detail on how the Spell Checker can be improved by opening an issue on GitHub?',
'Open Issue',
'Not Now',
);
if (result === 'Open Issue') {
return openNegativeFeedbackIssue();
}
return;
}
}
await window.showInformationMessage('Thank you for your feedback.', 'Close');
}

export function releaseNotes(): Promise<void> {
return openMarkdown('resources/pages/Spell Checker Release Notes.md');
}

async function openMarkdown(uri: Uri | string): Promise<void> {
if (typeof uri === 'string') {
uri = Uri.joinPath(getExtensionContext().extensionUri, uri);
}
return commands.executeCommand('markdown.showPreview', null, [uri], { lock: true });
}
36 changes: 1 addition & 35 deletions packages/client/src/support/index.mts
Original file line number Diff line number Diff line change
@@ -1,35 +1 @@
import { commands, Uri } from 'vscode';

import { getExtensionContext } from '../di.mjs';

export async function about(): Promise<void> {
const uriReadme = Uri.joinPath(getExtensionContext().extensionUri, 'resources/pages/About the Spell Checker.md');
return commands.executeCommand('markdown.showPreview', null, [uriReadme], { lock: true });
}

export function supportRequest(): Promise<void> {
return openMarkdown('resources/pages/Spell Checker Support Request.md');
}

export function reportIssue(): Promise<void> {
return openMarkdown('resources/pages/Spell Checker Report Issue.md');
}

export function sponsor(): Promise<void> {
return openMarkdown('resources/pages/Sponsor the Spell Checker.md');
}

export function callForSponsors(): Promise<void> {
return openMarkdown('resources/pages/Sponsor the Spell Checker.md');
}

export function releaseNotes(): Promise<void> {
return openMarkdown('resources/pages/Spell Checker Release Notes.md');
}

async function openMarkdown(uri: Uri | string): Promise<void> {
if (typeof uri === 'string') {
uri = Uri.joinPath(getExtensionContext().extensionUri, uri);
}
return commands.executeCommand('markdown.showPreview', null, [uri], { lock: true });
}
export { about, rateTheSpellChecker, releaseNotes, reportIssue, sponsor, supportRequest } from './commands.mjs';
40 changes: 40 additions & 0 deletions packages/client/src/support/openIssue.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { openExternalUrl } from '../util/openUrl.mjs';

const feedbackBody = `\
# Feedback
Thank you for providing feedback on the Spell Checker. Your feedback is important to us.
## How can the Spell Checker be improved?
<!-- Please provide details on how the Spell Checker can be improved. -->
## What issues are you experiencing?
<!-- Please provide details on the issues you are experiencing. -->
`;

export async function openNegativeFeedbackIssue(): Promise<void> {
await openExternalUrl(createNegativeFeedbackIssueURL());
}

export function createNegativeFeedbackIssueURL(): URL {
return formatGitHubIssueUrl({ title: 'Feedback', body: feedbackBody, labels: ['feedback'] });
}

interface GitHubIssue {
title?: string;
body?: string;
labels?: string[];
}

export function formatGitHubIssueUrl(issue?: GitHubIssue): URL {
const url = new URL('https://github.com/streetsidesoftware/vscode-spell-checker/issues/new');

const params = url.searchParams;
if (issue?.title) params.set('title', issue.title);
if (issue?.body) params.set('body', issue.body);
if (issue?.labels) params.set('labels', issue.labels.join(','));
return url;
}
12 changes: 12 additions & 0 deletions packages/client/src/support/openIssue.test.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { describe, expect, test, vi } from 'vitest';

import { createNegativeFeedbackIssueURL } from './openIssue.mjs';

vi.mock('vscode');

describe('openIssue', () => {
test('createNegativeFeedbackIssueUri', () => {
const url = createNegativeFeedbackIssueURL();
expect(url.href).toContain('issues/new');
});
});
7 changes: 7 additions & 0 deletions packages/client/src/util/openUrl.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Uri } from 'vscode';
import { env } from 'vscode';

export async function openExternalUrl(url: string | URL): Promise<boolean> {
// Hack to work around bug in VSCode see: https://github.com/microsoft/vscode/issues/85930
return env.openExternal(url.toString() as unknown as Uri);
}

0 comments on commit 4d2c51e

Please sign in to comment.