diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..79e8ab14 Binary files /dev/null and b/.DS_Store differ diff --git a/llm-meditators/.DS_Store b/llm-meditators/.DS_Store new file mode 100644 index 00000000..c23eb0b5 Binary files /dev/null and b/llm-meditators/.DS_Store differ diff --git a/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.html b/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.html index 13a7a1ec..402421c4 100644 --- a/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.html +++ b/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.html @@ -1 +1,47 @@ -

exp-profile works!

+@if (error() == null) { +
+

Profile Setting

+

+ Please select your preferred pronouns. This will be used to refer to you in the app. +

+ + + She/Her + They/Them + He/Him + + +

+
+
+ Please select your pseudo. This will be used to refer to you in the app. +

+ +
+ + My Name + + +
+ +

+
+
+ Please select your avatar. This will be used to refer to you in the app. +

+ + + Avatar Female + Avatar Neutral + Avatar Male + + + + + +
+} @else { +
+ {{error()}} +
+} diff --git a/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.scss b/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.scss index e69de29b..fb6e9db5 100644 --- a/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.scss +++ b/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.scss @@ -0,0 +1,31 @@ +.main { + padding: 2rem 1rem; + } + + label { + font-weight: bold; + -webkit-user-select: none; + user-select: none; + } + + .pronouns-radio-group { + display: flex; + align-items: center; + + .pronouns-radio-button { + margin: 5px; + -webkit-user-select: none; + user-select: none; + } + } + + .avatar-radio-group { + display: flex; + flex-direction: column; + margin: 15px 0; + align-items: flex-start; + } + + .avatar-radio-button { + margin: 5px; + } \ No newline at end of file diff --git a/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.ts b/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.ts index 9f6f3b26..ad262ec6 100644 --- a/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.ts +++ b/llm-meditators/webapp/src/app/exp-profile/exp-profile.component.ts @@ -6,13 +6,83 @@ * found in the LICENSE file and http://www.apache.org/licenses/LICENSE-2.0 ==============================================================================*/ -import { Component } from '@angular/core'; +import { Component, Signal, computed } from '@angular/core'; +import { MatRadioChange, MatRadioModule } from '@angular/material/radio'; +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { SavedDataService } from '../services/saved-data.service'; +import { User, UserProfile } from '../../lib/staged-exp/data-model'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; + +const dummyProfileData: UserProfile = { + pronouns: "They/Them", + avatarUrl: '/assets/avatars/they.png', + name: 'John Doe', +}; @Component({ selector: 'app-exp-profile', standalone: true, - imports: [], + imports: [MatRadioModule, MatButtonModule, MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule], templateUrl: './exp-profile.component.html', styleUrl: './exp-profile.component.scss', }) -export class ExpProfileComponent {} +export class ExpProfileComponent { + public responseControl: FormControl; + public stageData: Signal; + public error: Signal; + + constructor(private dataService: SavedDataService) { + this.error = computed(() => { + const currentStage = this.dataService.user().currentStage; + if (!currentStage) { + return `currentStage is undefined`; + } + if (currentStage.kind !== 'set-profile') { + return `currentStage is kind is not right: ${JSON.stringify(currentStage, null, 2)}`; + } + return null; + }); + + // Assumption: this is only ever constructed when + // `this.dataService.data().experiment.currentStage` references a + // ExpStageUserProfile. + + this.stageData = computed(() => { + if (this.dataService.data().user.currentStage.kind !== 'set-profile') { + return dummyProfileData; + } + return this.dataService.data().user.currentStage.config as UserProfile; + }); + + this.responseControl = new FormControl(''); + this.responseControl.valueChanges.forEach((n) => { + if (n) { + const curStageData = this.stageData(); + curStageData.name = n; + this.updateStageAndUser(curStageData); + } + console.log(this.stageData()); + }); + + } + + updatePronouns(updatedValue: MatRadioChange){ + const curStageData = this.stageData(); + curStageData.pronouns = updatedValue.value; + this.updateStageAndUser(curStageData); + } + + updateAvatarUrl(updatedValue: MatRadioChange){ + const curStageData = this.stageData(); + curStageData.avatarUrl = updatedValue.value; + this.updateStageAndUser(curStageData); + } + + updateStageAndUser(curStageData: UserProfile){ + this.dataService.updateExpStage(curStageData); + this.dataService.updateUser(curStageData); + } + +} diff --git a/llm-meditators/webapp/src/app/services/saved-data.service.ts b/llm-meditators/webapp/src/app/services/saved-data.service.ts index af00d586..59ed6f7c 100644 --- a/llm-meditators/webapp/src/app/services/saved-data.service.ts +++ b/llm-meditators/webapp/src/app/services/saved-data.service.ts @@ -8,7 +8,7 @@ import { computed, effect, Injectable, Signal, signal, untracked, WritableSignal } from '@angular/core'; import { LmApiService } from './lm-api.service'; -import { Experiment, ExpStage, User, ExpDataKinds, END_STAGE } from '../../lib/staged-exp/data-model'; +import { Experiment, ExpStage, User, ExpDataKinds, END_STAGE, UserProfile } from '../../lib/staged-exp/data-model'; import { initialExperimentSetup, initUserData } from '../../lib/staged-exp/example-experiment'; import { ActivatedRoute, Router } from '@angular/router'; import * as _ from 'underscore'; @@ -192,6 +192,12 @@ export class SavedDataService { this.data.set({ ...data }); } + updateUser(newUserProfile: UserProfile) { + const data = this.data(); + Object.assign(this.user().profile, newUserProfile); + this.data.set({ ...data }); + } + reset() { this.data.set(initialAppData()); } diff --git a/llm-meditators/webapp/src/assets/avatars/he.png b/llm-meditators/webapp/src/assets/avatars/he.png new file mode 100644 index 00000000..7532d0a9 Binary files /dev/null and b/llm-meditators/webapp/src/assets/avatars/he.png differ diff --git a/llm-meditators/webapp/src/assets/avatars/she.png b/llm-meditators/webapp/src/assets/avatars/she.png new file mode 100644 index 00000000..37b13cc4 Binary files /dev/null and b/llm-meditators/webapp/src/assets/avatars/she.png differ diff --git a/llm-meditators/webapp/src/assets/avatars/they.png b/llm-meditators/webapp/src/assets/avatars/they.png new file mode 100644 index 00000000..1f95ad48 Binary files /dev/null and b/llm-meditators/webapp/src/assets/avatars/they.png differ