Skip to content

Commit

Permalink
feat: Allows to provide feedback from the tool itself (podman-desktop…
Browse files Browse the repository at this point in the history
…#1078)

fixes podman-desktop#1028

Change-Id: I230db5a705b34cf87d220d0b511d40e81b156130
Signed-off-by: Florent Benoit <[email protected]>

Signed-off-by: Florent Benoit <[email protected]>
  • Loading branch information
benoitf authored Dec 22, 2022
1 parent 4eaed9e commit 9889429
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 2 deletions.
19 changes: 19 additions & 0 deletions packages/main/src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,21 @@ export class PluginSystem {

statusBarRegistry.setEntry('help', false, 0, undefined, 'Help', 'fa fa-question-circle', true, 'help', undefined);

statusBarRegistry.setEntry(
'feedback',
false,
0,
undefined,
'Share your feedback',
'fa fa-comment',
true,
'feedback',
undefined,
);
commandRegistry.registerCommand('feedback', () => {
apiSender.send('display-feedback', '');
});

commandRegistry.registerCommand('help', () => {
apiSender.send('display-help', '');
});
Expand Down Expand Up @@ -973,6 +988,10 @@ export class PluginSystem {
return kubernetesClient.getCurrentNamespace();
});

this.ipcHandle('feedback:send', async (_listener, feedbackProperties: unknown): Promise<void> => {
return telemetry.sendFeedback(feedbackProperties);
});

const dockerDesktopInstallation = new DockerDesktopInstallation(
apiSender,
containerProviderRegistry,
Expand Down
16 changes: 15 additions & 1 deletion packages/main/src/plugin/telemetry/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export class Telemetry {

private telemetryInitialized = false;

private telemetryConfigured = false;

private pendingItems: { eventName: string; properties: unknown }[] = [];

protected lastTimeEvents: Map<string, number>;
Expand Down Expand Up @@ -125,20 +127,25 @@ export class Telemetry {
const enabled = telemetryConfiguration.get<boolean>('enabled');
if (enabled === true) {
await this.configureTelemetry();
this.telemetryConfigured = true;
this.telemetryEnabled = true;
}
this.telemetryInitialized = true;
}
}

protected async configureTelemetry(): Promise<void> {
protected async initTelemetry(): Promise<void> {
const anonymousId = await this.identity.getUserId();
const traits = await this.getSegmentIdentifyTraits();

this.analytics?.identify({
anonymousId,
traits,
});
}

protected async configureTelemetry(): Promise<void> {
this.initTelemetry();

this.internalTrack('startup');
let sendShutdownAnalytics = false;
Expand Down Expand Up @@ -222,6 +229,13 @@ export class Telemetry {
this.internalTrack(event, eventProperties);
}

async sendFeedback(feedbackProperties: unknown): Promise<void> {
if (!this.telemetryConfigured) {
await this.initTelemetry();
}
this.internalTrack('feedback', feedbackProperties);
}

protected async getLocale(): Promise<string> {
if (!this.locale) {
this.locale = (await osLocale.osLocale()).replace('_', '-');
Expand Down
10 changes: 10 additions & 0 deletions packages/preload/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ import type { V1ConfigMap, V1NamespaceList, V1Pod, V1PodList, V1Service } from '

export type DialogResultCallback = (openDialogReturnValue: Electron.OpenDialogReturnValue) => void;

export interface FeedbackProperties {
rating: number;
comment?: string;
contact?: string;
}

// initialize extension loader mechanism
function initExposure(): void {
const eventEmitter = new EventEmitter();
Expand Down Expand Up @@ -995,6 +1001,10 @@ function initExposure(): void {
contextBridge.exposeInMainWorld('getOsHostname', async (): Promise<string> => {
return ipcInvoke('os:getHostname');
});

contextBridge.exposeInMainWorld('sendFeedback', async (feedback: FeedbackProperties): Promise<void> => {
return ipcInvoke('feedback:send', feedback);
});
}

// expose methods
Expand Down
2 changes: 2 additions & 0 deletions packages/renderer/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import PodDetails from './lib/pod/PodDetails.svelte';
import PodCreateFromContainers from './lib/pod/PodCreateFromContainers.svelte';
import DeployPodToKube from './lib/pod/DeployPodToKube.svelte';
import RunImage from './lib/image/RunImage.svelte';
import SendFeedback from './lib/feedback/SendFeedback.svelte';
router.mode.hash();
Expand Down Expand Up @@ -88,6 +89,7 @@ window.events?.receive('display-help', () => {
{/if}

<div class="z-0 w-full h-full bg-zinc-800 flex flex-col overflow-y-scroll">
<SendFeedback />
<Route path="/">
<WelcomePage />
</Route>
Expand Down
1 change: 1 addition & 0 deletions packages/renderer/src/lib/dialogs/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
transform: translate(-50%, -50%);
padding: 1em;
border-radius: 0.2em;
z-index: 50;
}
button {
Expand Down
125 changes: 125 additions & 0 deletions packages/renderer/src/lib/feedback/SendFeedback.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<script lang="ts">
import { faFrown, faGrinStars, faMeh, faSmile } from '@fortawesome/free-solid-svg-icons';
import Fa from 'svelte-fa/src/fa.svelte';
import Modal from '../dialogs/Modal.svelte';
import type { FeedbackProperties } from '../../../../preload/src/index';
let displayModal = false;
// feedback of the user
let smileyRating = 0;
let tellUsWhyFeedback = '';
let contactInformation = '';
window.events?.receive('display-feedback', () => {
displayModal = true;
});
function hideModal(): void {
displayModal = false;
// reset fields
smileyRating = 0;
tellUsWhyFeedback = '';
contactInformation = '';
}
function selectSmiley(item: number): void {
smileyRating = item;
}
async function sendFeedback(): Promise<void> {
const properties: FeedbackProperties = {
rating: smileyRating,
};
if (tellUsWhyFeedback) {
properties.comment = tellUsWhyFeedback;
}
if (contactInformation) {
properties.contact = contactInformation;
}
// send
await window.sendFeedback(properties);
// close the modal
hideModal();
}
</script>

{#if displayModal}
<Modal on:close="{() => hideModal()}">
<div
class="inline-block w-full overflow-hidden text-left transition-all transform bg-zinc-800 z-50 rounded-xl shadow-xl shadow-neutral-900">
<div class="flex items-center justify-between bg-black px-5 py-4 border-b-2 border-violet-700">
<h1 class="text-xl font-bold">Share your feedback</h1>

<button class="hover:text-gray-200 px-2 py-1" on:click="{() => hideModal()}">
<i class="fas fa-times" aria-hidden="true"></i>
</button>
</div>

<div class="overflow-y-auto p-4">
<label for="smiley" class="block mb-2 text-sm font-medium text-gray-300 dark:text-gray-300"
>How was your experience with Podman Desktop ?</label>
<div class="flex space-x-4">
<div on:click="{() => selectSmiley(1)}">
<Fa
size="24"
class="cursor-pointer {smileyRating === 1 ? 'text-violet-400' : 'text-gray-500'}"
icon="{faFrown}" />
</div>
<div on:click="{() => selectSmiley(2)}">
<Fa
size="24"
class="cursor-pointer {smileyRating === 2 ? 'text-violet-400' : 'text-gray-500'}"
icon="{faMeh}" />
</div>
<div on:click="{() => selectSmiley(3)}">
<Fa
size="24"
class="cursor-pointer {smileyRating === 3 ? 'text-violet-400' : 'text-gray-500'}"
icon="{faSmile}" />
</div>
<div on:click="{() => selectSmiley(4)}">
<Fa
size="24"
class="cursor-pointer {smileyRating === 4 ? 'text-violet-400' : 'text-gray-500'}"
icon="{faGrinStars}" />
</div>
</div>

<label for="tellUsWhyFeedback" class="block mt-4 mb-2 text-sm font-medium text-gray-300 dark:text-gray-300"
>Tell us why, or share any suggestion or issue to improve your experience: ({1000 - tellUsWhyFeedback.length} characters
left)</label>
<textarea
type="text"
rows="4"
maxlength="1000"
name="tellUsWhyFeedback"
id="tellUsWhyFeedback"
bind:value="{tellUsWhyFeedback}"
placeholder="Leave blank to generate a name"
class="w-full p-2 outline-none text-sm bg-zinc-900 rounded-sm text-gray-400 placeholder-gray-400"></textarea>

<label for="contactInformation" class="block mt-4 mb-2 text-sm font-medium text-gray-300 dark:text-gray-300"
>Share your contact information if you'd like us to answer you:</label>
<input
type="text"
name="contactInformation"
id="contactInformation"
bind:value="{contactInformation}"
placeholder="Enter email address, phone number or leave blank for anonymous feedback"
class="w-full p-2 outline-none text-sm bg-zinc-900 rounded-sm text-gray-400 placeholder-gray-400" />

<div class="pt-5 flex flex-row justify-end">
<button
disabled="{smileyRating === 0}"
class="pf-c-button pf-m-primary"
type="button"
on:click="{() => sendFeedback()}">Send feedback</button>
</div>
</div>
</div>
</Modal>
{/if}
14 changes: 13 additions & 1 deletion packages/renderer/src/lib/help/HelpPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,26 @@
</p>
</li>

<li class="pb-2">
<i class="fas fa-solid fa-comment" aria-hidden="true"></i>
<p
on:click="{() => {
window.events.send('display-feedback', undefined);
}}"
title="Share your Feedback"
class="text-sm inline-flex ml-1 cursor-pointer text-violet-400 hover:text-violet-600 hover:no-underline">
Share your Feedback
</p>
</li>

<li class="pb-2">
<i class="fas fa-solid fa-comment" aria-hidden="true"></i>
<p
on:click="{() =>
window.openExternal('https://github.com/containers/podman-desktop/discussions/categories/general')}"
title="https://github.com/containers/podman-desktop/discussions/categories/general"
class="text-sm inline-flex ml-1 cursor-pointer text-violet-400 hover:text-violet-600 hover:no-underline">
Share a Feedback
Create a GitHub discussion
</p>
</li>

Expand Down

0 comments on commit 9889429

Please sign in to comment.