Skip to content

Commit

Permalink
Make experience sampling skippable, store skipped values, improve exp…
Browse files Browse the repository at this point in the history
…erience sampling
  • Loading branch information
SRichner committed Feb 21, 2024
1 parent 9136d83 commit a1795a0
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 17 deletions.
14 changes: 12 additions & 2 deletions src/electron/electron/ipc/IpcHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,18 @@ export class IpcHandler {
});
}

private async createExperienceSample(promptedAt: number, question: string, response: number) {
await this.experienceSamplingService.createExperienceSample(promptedAt, question, response);
private async createExperienceSample(
promptedAt: number,
question: string,
response: number,
skipped: boolean = false
) {
await this.experienceSamplingService.createExperienceSample(
promptedAt,
question,
response,
skipped
);
}

private async closeExperienceSamplingWindow(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export class ExperienceSamplingResponseEntity extends BaseTrackedEntity {
@Column('text')
question: string;

@Column('int')
@Column('int', { nullable: true })
response: number;

@Column('boolean', { default: false, nullable: false })
skipped: boolean;
}
12 changes: 9 additions & 3 deletions src/electron/electron/main/services/ExperienceSamplingService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ import { getLogger } from '../../shared/Logger';
const LOG = getLogger('ExperienceSamplingService');

export class ExperienceSamplingService {
public async createExperienceSample(promptedAt: number, question: string, response: number) {
public async createExperienceSample(
promptedAt: number,
question: string,
response: number,
skipped: boolean
): Promise<void> {
LOG.debug(
`createExperienceSample: promptedAt=${promptedAt}, question=${question}, response=${response}`
`createExperienceSample: promptedAt=${promptedAt}, question=${question}, response=${response}, skipped=${skipped}`
);
await ExperienceSamplingResponseEntity.save({
question,
response,
promptedAt
promptedAt,
skipped
});
}
}
7 changes: 6 additions & 1 deletion src/electron/src/utils/Commands.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { StudyInfoDto } from '../../shared/dto/StudyInfoDto';

type Commands = {
createExperienceSample: (promptedAt: number, question: string, response: number) => Promise<void>;
createExperienceSample: (
promptedAt: number,
question: string,
response?: number,
skipped?: boolean
) => Promise<void>;
closeExperienceSamplingWindow: () => Promise<void>;
getStudyInfo: () => Promise<StudyInfoDto>;
};
Expand Down
53 changes: 43 additions & 10 deletions src/electron/src/views/ExperienceSamplingView.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts" setup>
import typedIpcRenderer from '../utils/typedIpcRenderer';
import studyConfig from '../../shared/study.config';
import { ref } from 'vue';
const esConfig = studyConfig.trackers.experienceSampling;
const studyQuestions = esConfig.questions;
Expand All @@ -13,9 +14,34 @@ const scale = Array.from({ length: esConfig.scale }, (_, i) => i + 1);
const promptedAt = new Date(Date.now());
const promptedAtString = promptedAt.toLocaleTimeString().substring(0, 5);
const sampleLoadingValue = ref<number | null>();
async function createExperienceSample(value: number) {
sampleLoadingValue.value = value;
try {
await typedIpcRenderer.invoke('createExperienceSample', promptedAt.getTime(), question, value);
await Promise.all([
typedIpcRenderer.invoke('createExperienceSample', promptedAt.getTime(), question, value),
new Promise((resolve) => setTimeout(resolve, 150))
]);
await typedIpcRenderer.invoke('closeExperienceSamplingWindow');
} catch (error) {
console.error('Error creating team', error);
}
}
async function skipExperienceSample() {
sampleLoadingValue.value = null;
try {
await Promise.all([
typedIpcRenderer.invoke(
'createExperienceSample',
promptedAt.getTime(),
question,
undefined,
true
),
new Promise((resolve) => setTimeout(resolve, 150))
]);
await typedIpcRenderer.invoke('closeExperienceSamplingWindow');
} catch (error) {
console.error('Error creating team', error);
Expand All @@ -33,33 +59,40 @@ async function createExperienceSample(value: number) {
<div class="flex items-start">
<div class="w-0 flex-1">
<p class="prompt">{{ question }}</p>
<div class="-mx-2 mt-2 flex flex-row justify-between">
<div class="-mx-1 mt-2 flex flex-row justify-between">
<div
v-for="value in scale"
:key="value"
class="sample-answer"
@click="createExperienceSample(value)"
>
<span v-if="true" class="mx-auto flex font-medium">
<span v-if="sampleLoadingValue !== value" class="mx-auto flex font-medium">
{{ value }}
</span>
<span v-else class="mx-auto flex font-medium">
<span class="loading loading-spinner loading-xs" />
</span>
</div>
</div>
<div class="mt-1 flex flex-row text-sm text-gray-400">
<div>{{ questionLabels[0] }}</div>
<div class="mx-auto">
<div class="basis-1/3">{{ questionLabels[0] }}</div>
<div class="basis-1/3 text-center">
<span v-if="questionLabels.length === 3">{{ questionLabels[1] }}</span>
</div>
<div>{{ questionLabels[2] || questionLabels[1] }}</div>
<div class="basis-1/3 text-right">{{ questionLabels[2] || questionLabels[1] }}</div>
</div>
</div>
</div>
</div>
<div class="flex cursor-pointer border-l border-gray-200">
<div
class="flex w-full items-center justify-center rounded-none rounded-r-lg border border-transparent p-4 text-sm font-medium text-gray-600 hover:text-gray-900 focus:outline-none"
class="flex w-full items-center justify-center rounded-none border border-transparent p-4 text-sm font-medium text-gray-600 hover:bg-gray-100 hover:text-gray-900 focus:outline-none"
@click="skipExperienceSample()"
>
Skip
<span v-if="sampleLoadingValue !== null" class="w-6"> Skip </span>
<span v-else class="w-6 font-medium">
<span class="loading loading-spinner loading-xs" />
</span>
</div>
</div>
</div>
Expand All @@ -79,12 +112,12 @@ async function createExperienceSample(value: number) {
}
.prompt {
@apply font-medium;
@apply font-bold;
color: @primary-color;
}
.sample-answer {
@apply mx-1 flex h-8 w-8 cursor-pointer items-center rounded-md border border-gray-200 bg-gray-100 text-center align-middle text-gray-500 outline-none ring-2 ring-gray-900 transition-all hover:bg-gray-700 hover:text-white;
@apply mx-1 flex h-8 w-8 cursor-pointer items-center rounded-md border border-gray-200 bg-gray-100 text-center align-middle text-gray-500 transition-all hover:bg-gray-700 hover:text-white;
}
}
</style>

0 comments on commit a1795a0

Please sign in to comment.