Add additional properties
All checks were successful
Gitea Actions Demo / build (push) Successful in 2m9s

This commit is contained in:
2025-06-17 18:45:31 -06:00
parent 5a7bad327f
commit aba378ab44
3 changed files with 162 additions and 37 deletions

View File

@@ -34,11 +34,14 @@ export class BabyNamesController {
const currentIndex = await this.babyNamesService.getCurrentNumber( const currentIndex = await this.babyNamesService.getCurrentNumber(
key as string, key as string,
); );
const name = this.babyNamesService.nameList[currentIndex];
const synonyms = this.babyNamesService.getSynonyms(name);
return { return {
key: key, key: key,
name: this.babyNamesService.nameList[currentIndex], name,
index: currentIndex, index: currentIndex,
message: request.query.message || null, message: request.query.message || null,
synonyms: synonyms.join(', '),
}; };
} }
@@ -52,14 +55,23 @@ export class BabyNamesController {
name: string; name: string;
nameindex: string; nameindex: string;
opinion: string; opinion: string;
pronunciation: string;
spelling: string;
comment: string;
}, },
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,
) { ) {
const { key, name, opinion, nameindex } = body; const { key, name, opinion, nameindex, pronunciation, spelling, comment } =
body;
if (!key) { if (!key) {
throw new Error("Missing 'key' field"); throw new Error("Missing 'key' field");
} }
await this.babyNamesService.addUserScore(key, name, parseInt(opinion, 10)); await this.babyNamesService.addUserScore(key, name, {
opinion: parseInt(opinion, 10),
pronunciation: parseInt(pronunciation, 10),
spelling: parseInt(spelling, 10),
comment: comment || '',
});
await this.babyNamesService.writeUserNumber( await this.babyNamesService.writeUserNumber(
key, key,
parseInt(nameindex, 10) + 1, parseInt(nameindex, 10) + 1,

View File

@@ -20,11 +20,26 @@ export interface NameCountMap {
[key: string]: number; [key: string]: number;
} }
interface NameSynonyms {
name: string;
gender: string;
synonyms: string[];
}
export interface NameSynonymsMap {
[key: string]: NameSynonyms;
}
interface UserScoreMap {
[key: string]: object;
}
@Injectable() @Injectable()
export class BabyNamesService { export class BabyNamesService {
public nameList: NameList = []; public nameList: NameList = [];
public nameCountMap: NameCountMap = {}; public nameCountMap: NameCountMap = {};
private readonly kvNamespace = 'baby-names'; public nameSynonymsMap: NameSynonymsMap = {};
public userScoreMap: UserScoreMap = {};
constructor(private readonly minioService: MinioService) { constructor(private readonly minioService: MinioService) {
this.refreshNames(); this.refreshNames();
@@ -37,6 +52,16 @@ export class BabyNamesService {
this.nameList = ( this.nameList = (
await axios.get('https://cache.sh/baby-name-data/namecount-list.json') await axios.get('https://cache.sh/baby-name-data/namecount-list.json')
).data; ).data;
this.nameSynonymsMap = (
await axios.get('https://cache.sh/baby-name-data/btn_synonyms.json')
).data;
this.nameSynonymsMap = Object.keys(this.nameSynonymsMap).reduce(
(acc, key) => {
acc[key.toLowerCase()] = this.nameSynonymsMap[key];
return acc;
},
{} as NameSynonymsMap,
);
} }
public async getCurrentNumber(userKey: string): Promise<number> { public async getCurrentNumber(userKey: string): Promise<number> {
@@ -63,7 +88,7 @@ export class BabyNamesService {
); );
} }
public async getUserScores(userKey: string): Promise<NameCountMap> { public async getUserScores(userKey: string): Promise<UserScoreMap> {
const scoresKey = await this.minioService const scoresKey = await this.minioService
.getBuffer( .getBuffer(
this.minioService.defaultBucketName, this.minioService.defaultBucketName,
@@ -79,7 +104,7 @@ export class BabyNamesService {
public async saveUserScores( public async saveUserScores(
userKey: string, userKey: string,
scores: NameCountMap, scores: UserScoreMap,
): Promise<void> { ): Promise<void> {
await this.minioService.uploadBuffer( await this.minioService.uploadBuffer(
this.minioService.defaultBucketName, this.minioService.defaultBucketName,
@@ -91,10 +116,18 @@ export class BabyNamesService {
public async addUserScore( public async addUserScore(
userKey: string, userKey: string,
name: string, name: string,
score: number, score: object,
): Promise<void> { ): Promise<void> {
const scores = await this.getUserScores(userKey); const scores = await this.getUserScores(userKey);
scores[name] = score; scores[name] = score;
await this.saveUserScores(userKey, scores); await this.saveUserScores(userKey, scores);
} }
public getSynonyms(name: string): string[] {
const entry = this.nameSynonymsMap[name.toLowerCase()];
if (entry) {
return entry.synonyms;
}
return [];
}
} }

View File

@@ -9,41 +9,121 @@
<input type='text' name='key' value='{{key}}' required /> <input type='text' name='key' value='{{key}}' required />
</div> </div>
<div> <div>
<h1>{{name}}</h1> <h1>{{name}} <span style='color:gray'>{{lastName}}</span></h1>
</div>
<div>
<h3>{{synonyms}}</h3>
</div> </div>
<input type='hidden' name='name' value='{{name}}' /> <input type='hidden' name='name' value='{{name}}' />
<input type='hidden' name='nameindex' value='{{index}}' /> <input type='hidden' name='nameindex' value='{{index}}' />
<div> <div
<label for='opinion'>How do you feel about this name?</label> style='display: flex; flex-direction: column; gap: 1em; margin-bottom: 1em;'
<div style='width: 300px;'> >
<input {{! Opinion }}
type='range' <div>
id='opinion' <label for='opinion'>How do you feel about this name?</label>
name='opinion' <div style='width: 300px;'>
min='-2' <input
max='2' type='range'
step='1' id='opinion'
list='opinion-ticks' name='opinion'
style='width: 100%;' min='-2'
required max='2'
/> step='1'
<datalist id='opinion-ticks'> list='opinion-ticks'
<option value='-2' label='Hate it'></option> style='width: 100%;'
<option value='-1' label='Dislike it'></option> required
<option value='0' label='Neutral'></option> />
<option value='1' label='Like it'></option> <datalist id='opinion-ticks'>
<option value='2' label='Love it'></option> <option value='-2' label='Hate it'></option>
</datalist> <option value='-1' label='Dislike it'></option>
<div <option value='0' label='Neutral'></option>
style='display: flex; justify-content: space-between; font-size: 0.9em; margin-top: 0.2em;' <option value='1' label='Like it'></option>
> <option value='2' label='Love it'></option>
<span>Hate it</span> </datalist>
<span>Dislike it</span> <div
<span>Neutral</span> style='display: flex; justify-content: space-between; font-size: 0.9em; margin-top: 0.2em;'
<span>Like it</span> >
<span>Love it</span> <span>Hate it</span>
<span>Dislike it</span>
<span>Neutral</span>
<span>Like it</span>
<span>Love it</span>
</div>
</div> </div>
</div> </div>
{{! Pronunciation }}
<div>
<label for='pronunciation'>Is this pronounceable?</label>
<div style='width: 300px;'>
<input
type='range'
id='pronunciation'
name='pronunciation'
min='-2'
max='2'
step='1'
list='pronunciation-ticks'
style='width: 100%;'
required
/>
<datalist id='pronunciation-ticks'>
<option value='-2' label='Very Hard'></option>
<option value='0' label='Normal'></option>
<option value='2' label='Very Easy'></option>
</datalist>
<div
style='display: flex; justify-content: space-between; font-size: 0.9em; margin-top: 0.2em;'
>
<span>Very Hard</span>
<span></span>
<span>Normal</span>
<span></span>
<span>Very Easy</span>
</div>
</div>
</div>
{{! Spelling }}
<div>
<label for='spelling'>How easy is this to spell?</label>
<div style='width: 300px;'>
<input
type='range'
id='spelling'
name='spelling'
min='-2'
max='2'
step='1'
list='spelling-ticks'
style='width: 100%;'
required
/>
<datalist id='spelling-ticks'>
<option value='-2' label='Very Hard'></option>
<option value='0' label='Normal'></option>
<option value='2' label='Very Easy'></option>
</datalist>
<div
style='display: flex; justify-content: space-between; font-size: 0.9em; margin-top: 0.2em;'
>
<span>Very Hard</span>
<span></span>
<span>Normal</span>
<span></span>
<span>Very Easy</span>
</div>
</div>
</div>
<div>
</div>
<div>
<textarea
name='comment'
rows='4'
cols='50'
placeholder='Any additional comments?'
></textarea>
</div>
</div> </div>
<button type='submit'>Submit Opinion</button> <button type='submit'>Submit Opinion</button>
</form> </form>