From e424b5f39356c18fc536b8c883df4a16d678e095 Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Fri, 10 Jun 2022 12:30:09 +0200 Subject: [PATCH 1/9] survey notification implementation --- .../browser/arduino-ide-frontend-module.ts | 8 +++ .../contributions/survey-notification.ts | 62 +++++++++++++++++++ .../src/browser/survey/survey-retriever.ts | 20 ++++++ 3 files changed, 90 insertions(+) create mode 100644 arduino-ide-extension/src/browser/contributions/survey-notification.ts create mode 100644 arduino-ide-extension/src/browser/survey/survey-retriever.ts diff --git a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts index 9ef3c2423..91552e53e 100644 --- a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts +++ b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts @@ -121,6 +121,8 @@ import { SaveAsSketch } from './contributions/save-as-sketch'; import { SaveSketch } from './contributions/save-sketch'; import { VerifySketch } from './contributions/verify-sketch'; import { UploadSketch } from './contributions/upload-sketch'; +import { SurveyNotification } from './contributions/survey-notification'; +import { SurveyRetriever } from './survey/survey-retriever'; import { CommonFrontendContribution } from './theia/core/common-frontend-contribution'; import { EditContributions } from './contributions/edit-contributions'; import { OpenSketchExternal } from './contributions/open-sketch-external'; @@ -475,6 +477,12 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(EditorMode).toSelf().inSingletonScope(); bind(FrontendApplicationContribution).toService(EditorMode); + // Survey notification + bind(SurveyRetriever).toSelf().inSingletonScope(); + + bind(SurveyNotification).toSelf().inSingletonScope(); + bind(FrontendApplicationContribution).toService(SurveyNotification); + // Layout and shell customizations. rebind(TheiaOutlineViewContribution) .to(OutlineViewContribution) diff --git a/arduino-ide-extension/src/browser/contributions/survey-notification.ts b/arduino-ide-extension/src/browser/contributions/survey-notification.ts new file mode 100644 index 000000000..0da778118 --- /dev/null +++ b/arduino-ide-extension/src/browser/contributions/survey-notification.ts @@ -0,0 +1,62 @@ +import { MessageService } from '@theia/core'; +import { FrontendApplicationContribution } from '@theia/core/lib/browser'; +import { inject, injectable } from '@theia/core/shared/inversify'; +import { shell } from '@theia/electron/shared/electron'; +import { LocalStorageService } from '@theia/core/lib/browser'; +import { SurveyRetriever } from '../survey/survey-retriever'; +import { nls } from '@theia/core/lib/common'; + +const SURVEY_MESSAGE = nls.localize( + 'arduino/survey/surveyMessage', + 'Please help us improve by answering this super short survey. We value our community and would like to get to know our supporters a little better.' +); +const DO_NOT_SHOW_AGAIN = nls.localize( + 'arduino/survey/dismissSurvey', + 'DON’T SHOW ANYMORE' +); +const GO_TO_SURVEY = nls.localize( + 'arduino/survey/answerSurvey', + 'ANSWER SURVEY' +); + +@injectable() +export class SurveyNotification implements FrontendApplicationContribution { + @inject(MessageService) + protected readonly messageService: MessageService; + + @inject(LocalStorageService) + protected readonly localStorageService: LocalStorageService; + + @inject(SurveyRetriever) + protected readonly surveyRetriever: SurveyRetriever; + + async onStart(): Promise { + const survey = await this.surveyRetriever.getSurvey(); + const surveyAnswered = await this.localStorageService.getData( + this.surveyKey(survey.id), + 'notAnswered' + ); + + if (surveyAnswered !== 'notAnswered') { + return; + } + + this.messageService + .info(SURVEY_MESSAGE, DO_NOT_SHOW_AGAIN, GO_TO_SURVEY) + .then(async (answer) => { + switch (answer) { + case GO_TO_SURVEY: + shell.openExternal(survey.url.href); + this.localStorageService.setData(this.surveyKey(survey.id), true); + break; + case DO_NOT_SHOW_AGAIN: + this.localStorageService.setData(this.surveyKey(survey.id), false); + break; + } + }); + } + + private surveyKey(id: string): string { + return `answered_survey:${id}`; + } +} diff --git a/arduino-ide-extension/src/browser/survey/survey-retriever.ts b/arduino-ide-extension/src/browser/survey/survey-retriever.ts new file mode 100644 index 000000000..4778ff0bd --- /dev/null +++ b/arduino-ide-extension/src/browser/survey/survey-retriever.ts @@ -0,0 +1,20 @@ +import { injectable } from '@theia/core/shared/inversify'; + +export type Survey = { + url: URL; + id: string; +}; + +const SURVEY_BASE_URL = 'https://surveys.hotjar.com/'; +const surveyId = '17887b40-e1f0-4bd6-b9f0-a37f229ccd8b'; + +@injectable() +export class SurveyRetriever { + public async getSurvey(): Promise { + const survey: Survey = { + url: new URL(SURVEY_BASE_URL + surveyId), + id: surveyId, + }; + return new Promise((resolve) => setTimeout(() => resolve(survey), 1000)); + } +} From fb2d99d3796c47f025c3a7637132f78d2e8172ba Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Fri, 10 Jun 2022 15:32:43 +0200 Subject: [PATCH 2/9] update i18n/en.json with new strings --- i18n/en.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/i18n/en.json b/i18n/en.json index 959f0e989..eb989e436 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -305,6 +305,11 @@ "verify": "Verify", "verifyOrCompile": "Verify/Compile" }, + "survey": { + "answerSurvey": "ANSWER SURVEY", + "dismissSurvey": "DON’T SHOW ANYMORE", + "surveyMessage": "Please help us improve by answering this super short survey. We value our community and would like to get to know our supporters a little better." + }, "upload": { "error": "{0} error: {1}" }, From f215547a7bb5ff76d29aa64b80040d75ff6402ff Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Mon, 13 Jun 2022 15:20:31 +0200 Subject: [PATCH 3/9] survey implementation improvements --- .../browser/arduino-ide-frontend-module.ts | 3 -- .../contributions/survey-notification.ts | 49 +++++++++++-------- .../src/browser/survey/survey-retriever.ts | 20 -------- 3 files changed, 29 insertions(+), 43 deletions(-) delete mode 100644 arduino-ide-extension/src/browser/survey/survey-retriever.ts diff --git a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts index 91552e53e..fe4a5503b 100644 --- a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts +++ b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts @@ -122,7 +122,6 @@ import { SaveSketch } from './contributions/save-sketch'; import { VerifySketch } from './contributions/verify-sketch'; import { UploadSketch } from './contributions/upload-sketch'; import { SurveyNotification } from './contributions/survey-notification'; -import { SurveyRetriever } from './survey/survey-retriever'; import { CommonFrontendContribution } from './theia/core/common-frontend-contribution'; import { EditContributions } from './contributions/edit-contributions'; import { OpenSketchExternal } from './contributions/open-sketch-external'; @@ -478,8 +477,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(FrontendApplicationContribution).toService(EditorMode); // Survey notification - bind(SurveyRetriever).toSelf().inSingletonScope(); - bind(SurveyNotification).toSelf().inSingletonScope(); bind(FrontendApplicationContribution).toService(SurveyNotification); diff --git a/arduino-ide-extension/src/browser/contributions/survey-notification.ts b/arduino-ide-extension/src/browser/contributions/survey-notification.ts index 0da778118..d93dbda6a 100644 --- a/arduino-ide-extension/src/browser/contributions/survey-notification.ts +++ b/arduino-ide-extension/src/browser/contributions/survey-notification.ts @@ -1,10 +1,14 @@ import { MessageService } from '@theia/core'; import { FrontendApplicationContribution } from '@theia/core/lib/browser'; import { inject, injectable } from '@theia/core/shared/inversify'; -import { shell } from '@theia/electron/shared/electron'; import { LocalStorageService } from '@theia/core/lib/browser'; -import { SurveyRetriever } from '../survey/survey-retriever'; import { nls } from '@theia/core/lib/common'; +import { WindowService } from '@theia/core/lib/browser/window/window-service'; + +export type Survey = { + url: URL; + id: string; +}; const SURVEY_MESSAGE = nls.localize( 'arduino/survey/surveyMessage', @@ -19,6 +23,9 @@ const GO_TO_SURVEY = nls.localize( 'ANSWER SURVEY' ); +const SURVEY_BASE_URL = 'https://surveys.hotjar.com/'; +const surveyId = '17887b40-e1f0-4bd6-b9f0-a37f229ccd8b'; + @injectable() export class SurveyNotification implements FrontendApplicationContribution { @inject(MessageService) @@ -27,30 +34,32 @@ export class SurveyNotification implements FrontendApplicationContribution { @inject(LocalStorageService) protected readonly localStorageService: LocalStorageService; - @inject(SurveyRetriever) - protected readonly surveyRetriever: SurveyRetriever; + @inject(WindowService) + protected readonly windowService: WindowService; async onStart(): Promise { - const survey = await this.surveyRetriever.getSurvey(); - const surveyAnswered = await this.localStorageService.getData( - this.surveyKey(survey.id), - 'notAnswered' - ); - - if (surveyAnswered !== 'notAnswered') { - return; - } - - this.messageService - .info(SURVEY_MESSAGE, DO_NOT_SHOW_AGAIN, GO_TO_SURVEY) - .then(async (answer) => { + this.localStorageService + .getData(this.surveyKey(surveyId), undefined) + .then((surveyAnswered) => { + if (surveyAnswered !== undefined) { + return; + } + return this.messageService.info( + SURVEY_MESSAGE, + DO_NOT_SHOW_AGAIN, + GO_TO_SURVEY + ); + }) + .then((answer) => { switch (answer) { case GO_TO_SURVEY: - shell.openExternal(survey.url.href); - this.localStorageService.setData(this.surveyKey(survey.id), true); + this.windowService.openNewWindow(SURVEY_BASE_URL + surveyId, { + external: true, + }); + this.localStorageService.setData(this.surveyKey(surveyId), true); break; case DO_NOT_SHOW_AGAIN: - this.localStorageService.setData(this.surveyKey(survey.id), false); + this.localStorageService.setData(this.surveyKey(surveyId), false); break; } }); diff --git a/arduino-ide-extension/src/browser/survey/survey-retriever.ts b/arduino-ide-extension/src/browser/survey/survey-retriever.ts deleted file mode 100644 index 4778ff0bd..000000000 --- a/arduino-ide-extension/src/browser/survey/survey-retriever.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { injectable } from '@theia/core/shared/inversify'; - -export type Survey = { - url: URL; - id: string; -}; - -const SURVEY_BASE_URL = 'https://surveys.hotjar.com/'; -const surveyId = '17887b40-e1f0-4bd6-b9f0-a37f229ccd8b'; - -@injectable() -export class SurveyRetriever { - public async getSurvey(): Promise { - const survey: Survey = { - url: new URL(SURVEY_BASE_URL + surveyId), - id: surveyId, - }; - return new Promise((resolve) => setTimeout(() => resolve(survey), 1000)); - } -} From ab3acda46750d661aa5c9aaf81aed268fa490467 Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Tue, 14 Jun 2022 11:26:15 +0200 Subject: [PATCH 4/9] add setting to disable surveys in advanced preferences --- .../src/browser/arduino-preferences.ts | 9 +++ .../contributions/survey-notification.ts | 56 ++++++++++--------- i18n/en.json | 1 + 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/arduino-ide-extension/src/browser/arduino-preferences.ts b/arduino-ide-extension/src/browser/arduino-preferences.ts index 0aec020d5..8450012a6 100644 --- a/arduino-ide-extension/src/browser/arduino-preferences.ts +++ b/arduino-ide-extension/src/browser/arduino-preferences.ts @@ -174,6 +174,14 @@ export const ArduinoConfigSchema: PreferenceSchema = { ), default: 'https://auth.arduino.cc/login#/register', }, + 'arduino.survey.notification': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/survey.notification', + 'True if users should be notified if a survey is available. True by default.' + ), + default: true, + }, }, }; @@ -198,6 +206,7 @@ export interface ArduinoConfiguration { 'arduino.auth.domain': string; 'arduino.auth.audience': string; 'arduino.auth.registerUri': string; + 'arduino.survey.notification': boolean; } export const ArduinoPreferences = Symbol('ArduinoPreferences'); diff --git a/arduino-ide-extension/src/browser/contributions/survey-notification.ts b/arduino-ide-extension/src/browser/contributions/survey-notification.ts index d93dbda6a..f15ce5aae 100644 --- a/arduino-ide-extension/src/browser/contributions/survey-notification.ts +++ b/arduino-ide-extension/src/browser/contributions/survey-notification.ts @@ -4,6 +4,7 @@ import { inject, injectable } from '@theia/core/shared/inversify'; import { LocalStorageService } from '@theia/core/lib/browser'; import { nls } from '@theia/core/lib/common'; import { WindowService } from '@theia/core/lib/browser/window/window-service'; +import { ArduinoPreferences } from '../arduino-preferences'; export type Survey = { url: URL; @@ -37,32 +38,37 @@ export class SurveyNotification implements FrontendApplicationContribution { @inject(WindowService) protected readonly windowService: WindowService; + @inject(ArduinoPreferences) + protected readonly arduinoPreferences: ArduinoPreferences; + async onStart(): Promise { - this.localStorageService - .getData(this.surveyKey(surveyId), undefined) - .then((surveyAnswered) => { - if (surveyAnswered !== undefined) { - return; - } - return this.messageService.info( - SURVEY_MESSAGE, - DO_NOT_SHOW_AGAIN, - GO_TO_SURVEY - ); - }) - .then((answer) => { - switch (answer) { - case GO_TO_SURVEY: - this.windowService.openNewWindow(SURVEY_BASE_URL + surveyId, { - external: true, - }); - this.localStorageService.setData(this.surveyKey(surveyId), true); - break; - case DO_NOT_SHOW_AGAIN: - this.localStorageService.setData(this.surveyKey(surveyId), false); - break; - } - }); + if (this.arduinoPreferences.get('arduino.survey.notification')) { + this.localStorageService + .getData(this.surveyKey(surveyId), undefined) + .then((surveyAnswered) => { + if (surveyAnswered !== undefined) { + return; + } + return this.messageService.info( + SURVEY_MESSAGE, + DO_NOT_SHOW_AGAIN, + GO_TO_SURVEY + ); + }) + .then((answer) => { + switch (answer) { + case GO_TO_SURVEY: + this.windowService.openNewWindow(SURVEY_BASE_URL + surveyId, { + external: true, + }); + this.localStorageService.setData(this.surveyKey(surveyId), true); + break; + case DO_NOT_SHOW_AGAIN: + this.localStorageService.setData(this.surveyKey(surveyId), false); + break; + } + }); + } } private surveyKey(id: string): string { diff --git a/i18n/en.json b/i18n/en.json index eb989e436..00d57bd31 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -256,6 +256,7 @@ "showVerbose": "Show verbose output during", "sketchbook.location": "Sketchbook location", "sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.", + "survey.notification": "True if users should be notified if a survey is available. True by default.", "unofficialBoardSupport": "Click for a list of unofficial board support URLs", "upload": "upload", "upload.verbose": "True for verbose upload output. False by default.", From fb7ec54d60e6af7ab4eca0008862355e5f81cf81 Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Tue, 14 Jun 2022 15:59:31 +0200 Subject: [PATCH 5/9] code clean up --- .../contributions/survey-notification.ts | 79 ++++++++++--------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/arduino-ide-extension/src/browser/contributions/survey-notification.ts b/arduino-ide-extension/src/browser/contributions/survey-notification.ts index f15ce5aae..012d88487 100644 --- a/arduino-ide-extension/src/browser/contributions/survey-notification.ts +++ b/arduino-ide-extension/src/browser/contributions/survey-notification.ts @@ -6,18 +6,13 @@ import { nls } from '@theia/core/lib/common'; import { WindowService } from '@theia/core/lib/browser/window/window-service'; import { ArduinoPreferences } from '../arduino-preferences'; -export type Survey = { - url: URL; - id: string; -}; - const SURVEY_MESSAGE = nls.localize( 'arduino/survey/surveyMessage', 'Please help us improve by answering this super short survey. We value our community and would like to get to know our supporters a little better.' ); const DO_NOT_SHOW_AGAIN = nls.localize( 'arduino/survey/dismissSurvey', - 'DON’T SHOW ANYMORE' + "DON'T SHOW ANYMORE" ); const GO_TO_SURVEY = nls.localize( 'arduino/survey/answerSurvey', @@ -30,45 +25,53 @@ const surveyId = '17887b40-e1f0-4bd6-b9f0-a37f229ccd8b'; @injectable() export class SurveyNotification implements FrontendApplicationContribution { @inject(MessageService) - protected readonly messageService: MessageService; + private readonly messageService: MessageService; @inject(LocalStorageService) - protected readonly localStorageService: LocalStorageService; + private readonly localStorageService: LocalStorageService; @inject(WindowService) - protected readonly windowService: WindowService; + private readonly windowService: WindowService; @inject(ArduinoPreferences) - protected readonly arduinoPreferences: ArduinoPreferences; + private readonly arduinoPreferences: ArduinoPreferences; - async onStart(): Promise { - if (this.arduinoPreferences.get('arduino.survey.notification')) { - this.localStorageService - .getData(this.surveyKey(surveyId), undefined) - .then((surveyAnswered) => { - if (surveyAnswered !== undefined) { - return; - } - return this.messageService.info( - SURVEY_MESSAGE, - DO_NOT_SHOW_AGAIN, - GO_TO_SURVEY - ); - }) - .then((answer) => { - switch (answer) { - case GO_TO_SURVEY: - this.windowService.openNewWindow(SURVEY_BASE_URL + surveyId, { - external: true, - }); - this.localStorageService.setData(this.surveyKey(surveyId), true); - break; - case DO_NOT_SHOW_AGAIN: - this.localStorageService.setData(this.surveyKey(surveyId), false); - break; - } - }); - } + onStart(): void { + this.arduinoPreferences.ready.then(() => { + if (this.arduinoPreferences.get('arduino.survey.notification')) { + this.localStorageService + .getData(this.surveyKey(surveyId)) + .then((surveyAnswered) => { + if (surveyAnswered !== undefined) { + return; + } + return this.messageService.info( + SURVEY_MESSAGE, + DO_NOT_SHOW_AGAIN, + GO_TO_SURVEY + ); + }) + .then((answer) => { + switch (answer) { + case GO_TO_SURVEY: + this.windowService.openNewWindow(SURVEY_BASE_URL + surveyId, { + external: true, + }); + this.localStorageService.setData( + this.surveyKey(surveyId), + true + ); + break; + case DO_NOT_SHOW_AGAIN: + this.localStorageService.setData( + this.surveyKey(surveyId), + false + ); + break; + } + }); + } + }); } private surveyKey(id: string): string { From 884a9e894d25e72abbe334c30aac241baf982363 Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Tue, 14 Jun 2022 16:19:33 +0200 Subject: [PATCH 6/9] code clean up and i18n update --- .../contributions/survey-notification.ts | 55 ++++++++----------- i18n/en.json | 2 +- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/arduino-ide-extension/src/browser/contributions/survey-notification.ts b/arduino-ide-extension/src/browser/contributions/survey-notification.ts index 012d88487..674b0e7e5 100644 --- a/arduino-ide-extension/src/browser/contributions/survey-notification.ts +++ b/arduino-ide-extension/src/browser/contributions/survey-notification.ts @@ -37,39 +37,30 @@ export class SurveyNotification implements FrontendApplicationContribution { private readonly arduinoPreferences: ArduinoPreferences; onStart(): void { - this.arduinoPreferences.ready.then(() => { + this.arduinoPreferences.ready.then(async () => { if (this.arduinoPreferences.get('arduino.survey.notification')) { - this.localStorageService - .getData(this.surveyKey(surveyId)) - .then((surveyAnswered) => { - if (surveyAnswered !== undefined) { - return; - } - return this.messageService.info( - SURVEY_MESSAGE, - DO_NOT_SHOW_AGAIN, - GO_TO_SURVEY - ); - }) - .then((answer) => { - switch (answer) { - case GO_TO_SURVEY: - this.windowService.openNewWindow(SURVEY_BASE_URL + surveyId, { - external: true, - }); - this.localStorageService.setData( - this.surveyKey(surveyId), - true - ); - break; - case DO_NOT_SHOW_AGAIN: - this.localStorageService.setData( - this.surveyKey(surveyId), - false - ); - break; - } - }); + const surveyAnswered = await this.localStorageService.getData( + this.surveyKey(surveyId) + ); + if (surveyAnswered !== undefined) { + return; + } + const answer = await this.messageService.info( + SURVEY_MESSAGE, + DO_NOT_SHOW_AGAIN, + GO_TO_SURVEY + ); + switch (answer) { + case GO_TO_SURVEY: + this.windowService.openNewWindow(SURVEY_BASE_URL + surveyId, { + external: true, + }); + this.localStorageService.setData(this.surveyKey(surveyId), true); + break; + case DO_NOT_SHOW_AGAIN: + this.localStorageService.setData(this.surveyKey(surveyId), false); + break; + } } }); } diff --git a/i18n/en.json b/i18n/en.json index 00d57bd31..a956955fd 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -308,7 +308,7 @@ }, "survey": { "answerSurvey": "ANSWER SURVEY", - "dismissSurvey": "DON’T SHOW ANYMORE", + "dismissSurvey": "DON'T SHOW ANYMORE", "surveyMessage": "Please help us improve by answering this super short survey. We value our community and would like to get to know our supporters a little better." }, "upload": { From e5531396cdd4553211d1c5408f66f88ad4e45cc1 Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Tue, 14 Jun 2022 16:25:11 +0200 Subject: [PATCH 7/9] avoid caps strings --- .../src/browser/contributions/survey-notification.ts | 4 ++-- i18n/en.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arduino-ide-extension/src/browser/contributions/survey-notification.ts b/arduino-ide-extension/src/browser/contributions/survey-notification.ts index 674b0e7e5..6d15e8a7f 100644 --- a/arduino-ide-extension/src/browser/contributions/survey-notification.ts +++ b/arduino-ide-extension/src/browser/contributions/survey-notification.ts @@ -12,11 +12,11 @@ const SURVEY_MESSAGE = nls.localize( ); const DO_NOT_SHOW_AGAIN = nls.localize( 'arduino/survey/dismissSurvey', - "DON'T SHOW ANYMORE" + "Don't show again" ); const GO_TO_SURVEY = nls.localize( 'arduino/survey/answerSurvey', - 'ANSWER SURVEY' + 'Answer survey' ); const SURVEY_BASE_URL = 'https://surveys.hotjar.com/'; diff --git a/i18n/en.json b/i18n/en.json index a956955fd..08cafdf72 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -307,8 +307,8 @@ "verifyOrCompile": "Verify/Compile" }, "survey": { - "answerSurvey": "ANSWER SURVEY", - "dismissSurvey": "DON'T SHOW ANYMORE", + "answerSurvey": "Answer survey", + "dismissSurvey": "Don't show again", "surveyMessage": "Please help us improve by answering this super short survey. We value our community and would like to get to know our supporters a little better." }, "upload": { From bda7f6bb1d6eccae43e067d368cacaacc569ed79 Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Thu, 16 Jun 2022 17:45:38 +0200 Subject: [PATCH 8/9] avoid multiple notifications in different windows --- .../browser/arduino-ide-frontend-module.ts | 13 +++++++++++ .../contributions/survey-notification.ts | 9 +++++++- .../src/common/protocol/survey-service.ts | 7 ++++++ .../arduino-electron-main-module.ts | 22 +++++++++++++++++++ .../src/node/survey-service-impl.ts | 15 +++++++++++++ 5 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 arduino-ide-extension/src/common/protocol/survey-service.ts create mode 100644 arduino-ide-extension/src/node/survey-service-impl.ts diff --git a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts index fe4a5503b..d52969253 100644 --- a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts +++ b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts @@ -292,6 +292,10 @@ import { PreferenceTreeGenerator } from './theia/preferences/preference-tree-gen import { PreferenceTreeGenerator as TheiaPreferenceTreeGenerator } from '@theia/preferences/lib/browser/util/preference-tree-generator'; import { AboutDialog } from './theia/core/about-dialog'; import { AboutDialog as TheiaAboutDialog } from '@theia/core/lib/browser/about-dialog'; +import { + SurveyNotificationService, + SurveyNotificationServicePath, +} from '../common/protocol/survey-service'; MonacoThemingService.register({ id: 'arduino-theme', @@ -480,6 +484,15 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(SurveyNotification).toSelf().inSingletonScope(); bind(FrontendApplicationContribution).toService(SurveyNotification); + bind(SurveyNotificationService) + .toDynamicValue((context) => { + return ElectronIpcConnectionProvider.createProxy( + context.container, + SurveyNotificationServicePath + ); + }) + .inSingletonScope(); + // Layout and shell customizations. rebind(TheiaOutlineViewContribution) .to(OutlineViewContribution) diff --git a/arduino-ide-extension/src/browser/contributions/survey-notification.ts b/arduino-ide-extension/src/browser/contributions/survey-notification.ts index 6d15e8a7f..e1a4817a6 100644 --- a/arduino-ide-extension/src/browser/contributions/survey-notification.ts +++ b/arduino-ide-extension/src/browser/contributions/survey-notification.ts @@ -5,6 +5,7 @@ import { LocalStorageService } from '@theia/core/lib/browser'; import { nls } from '@theia/core/lib/common'; import { WindowService } from '@theia/core/lib/browser/window/window-service'; import { ArduinoPreferences } from '../arduino-preferences'; +import { SurveyNotificationService } from '../../common/protocol/survey-service'; const SURVEY_MESSAGE = nls.localize( 'arduino/survey/surveyMessage', @@ -36,9 +37,15 @@ export class SurveyNotification implements FrontendApplicationContribution { @inject(ArduinoPreferences) private readonly arduinoPreferences: ArduinoPreferences; + @inject(SurveyNotificationService) + private readonly surveyNotificationService: SurveyNotificationService; + onStart(): void { this.arduinoPreferences.ready.then(async () => { - if (this.arduinoPreferences.get('arduino.survey.notification')) { + if ( + (await this.surveyNotificationService.isFirstInstance()) && + this.arduinoPreferences.get('arduino.survey.notification') + ) { const surveyAnswered = await this.localStorageService.getData( this.surveyKey(surveyId) ); diff --git a/arduino-ide-extension/src/common/protocol/survey-service.ts b/arduino-ide-extension/src/common/protocol/survey-service.ts new file mode 100644 index 000000000..3ab53b230 --- /dev/null +++ b/arduino-ide-extension/src/common/protocol/survey-service.ts @@ -0,0 +1,7 @@ +export const SurveyNotificationServicePath = + '/services/survey-notification-service'; +export const SurveyNotificationService = Symbol('SurveyNotificationService'); + +export interface SurveyNotificationService { + isFirstInstance(): Promise; +} diff --git a/arduino-ide-extension/src/electron-main/arduino-electron-main-module.ts b/arduino-ide-extension/src/electron-main/arduino-electron-main-module.ts index 7df38d649..7da0c7314 100644 --- a/arduino-ide-extension/src/electron-main/arduino-electron-main-module.ts +++ b/arduino-ide-extension/src/electron-main/arduino-electron-main-module.ts @@ -21,6 +21,11 @@ import { import { IDEUpdaterImpl } from './ide-updater/ide-updater-impl'; import { TheiaElectronWindow } from './theia/theia-electron-window'; import { TheiaElectronWindow as DefaultTheiaElectronWindow } from '@theia/core/lib/electron-main/theia-electron-window'; +import { SurveyNotificationServiceImpl } from '../node/survey-service-impl'; +import { + SurveyNotificationService, + SurveyNotificationServicePath, +} from '../common/protocol/survey-service'; export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(ElectronMainApplication).toSelf().inSingletonScope(); @@ -61,4 +66,21 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(TheiaElectronWindow).toSelf(); rebind(DefaultTheiaElectronWindow).toService(TheiaElectronWindow); + + // Survey notification bindings + bind(SurveyNotificationServiceImpl).toSelf().inSingletonScope(); + bind(SurveyNotificationService).toService(SurveyNotificationServiceImpl); + bind(ElectronMainApplicationContribution).toService( + SurveyNotificationService + ); + bind(ElectronConnectionHandler) + .toDynamicValue( + (context) => + new JsonRpcConnectionHandler(SurveyNotificationServicePath, () => + context.container.get( + SurveyNotificationService + ) + ) + ) + .inSingletonScope(); }); diff --git a/arduino-ide-extension/src/node/survey-service-impl.ts b/arduino-ide-extension/src/node/survey-service-impl.ts new file mode 100644 index 000000000..18aa32223 --- /dev/null +++ b/arduino-ide-extension/src/node/survey-service-impl.ts @@ -0,0 +1,15 @@ +import { injectable } from '@theia/core/shared/inversify'; +import { SurveyNotificationService } from '../common/protocol/survey-service'; + +@injectable() +export class SurveyNotificationServiceImpl + implements SurveyNotificationService +{ + private isSurveyShown = false; + async isFirstInstance(): Promise { + if (this.isSurveyShown) { + return false; + } + return (this.isSurveyShown = true); + } +} From 77698f8f8b206ac2af277f6b935938e79958dfaf Mon Sep 17 00:00:00 2001 From: Francesco Spissu Date: Thu, 16 Jun 2022 18:28:56 +0200 Subject: [PATCH 9/9] document the purpose of the service --- arduino-ide-extension/src/node/survey-service-impl.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arduino-ide-extension/src/node/survey-service-impl.ts b/arduino-ide-extension/src/node/survey-service-impl.ts index 18aa32223..aea8c0472 100644 --- a/arduino-ide-extension/src/node/survey-service-impl.ts +++ b/arduino-ide-extension/src/node/survey-service-impl.ts @@ -1,15 +1,20 @@ import { injectable } from '@theia/core/shared/inversify'; import { SurveyNotificationService } from '../common/protocol/survey-service'; +/** + * Service for checking if it is the first instance of the IDE, in this case it sets a flag to true. + * This flag is used to prevent the survey notification from being visible in every open window. It must only be shown on one window. + */ @injectable() export class SurveyNotificationServiceImpl implements SurveyNotificationService { - private isSurveyShown = false; + private surveyDidShow = false; async isFirstInstance(): Promise { - if (this.isSurveyShown) { + if (this.surveyDidShow) { return false; } - return (this.isSurveyShown = true); + this.surveyDidShow = true; + return this.surveyDidShow; } }