Trent Larson
10 months ago
5 changed files with 241 additions and 4 deletions
@ -0,0 +1,214 @@ |
|||
<template> |
|||
<div v-if="visible" class="dialog-overlay"> |
|||
<div class="dialog"> |
|||
<h1 class="text-xl font-bold text-center mb-4">Here's one:</h1> |
|||
<span class="flex justify-between h-24"> |
|||
<span |
|||
class="rounded-l border border-slate-400 bg-slate-200 h-full px-4 py-2 flex h-screen" |
|||
@click="prevIdea()" |
|||
> |
|||
<fa icon="chevron-left" class="m-auto" /> |
|||
</span> |
|||
|
|||
<div class="m-2"> |
|||
<span v-if="currentIdeaIndex < IDEAS.length"> |
|||
<p class="text-center text-lg font-bold"> |
|||
{{ IDEAS[currentIdeaIndex] }} |
|||
</p> |
|||
</span> |
|||
<div v-if="currentIdeaIndex == IDEAS.length + 0"> |
|||
<p class="text-center text-lg font-bold"> |
|||
Did this person or someone near them do something – maybe a |
|||
while ago? |
|||
<br /> |
|||
<span v-if="currentContact?.name == null" class="text-orange-500"> |
|||
That's all your contacts. |
|||
</span> |
|||
<span v-else>{{ |
|||
currentContact.name || AppString.NO_CONTACT_NAME |
|||
}}</span> |
|||
</p> |
|||
</div> |
|||
</div> |
|||
|
|||
<span |
|||
class="rounded-r border border-slate-400 bg-slate-200 h-full px-4 py-2 flex h-screen" |
|||
@click="nextIdea()" |
|||
> |
|||
<fa icon="chevron-right" class="m-auto" /> |
|||
</span> |
|||
</span> |
|||
<button |
|||
class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mt-4" |
|||
@click="cancel" |
|||
> |
|||
That's it. |
|||
</button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { Vue, Component } from "vue-facing-decorator"; |
|||
|
|||
import { AppString } from "@/constants/app"; |
|||
import { db } from "@/db/index"; |
|||
import { Contact } from "@/db/tables/contacts"; |
|||
|
|||
interface Notification { |
|||
group: string; |
|||
type: string; |
|||
title: string; |
|||
text: string; |
|||
} |
|||
|
|||
@Component |
|||
export default class GivenPrompts extends Vue { |
|||
$notify!: (notification: Notification, timeout?: number) => void; |
|||
|
|||
IDEAS = [ |
|||
"Did anyone fix food for you?", |
|||
"Did a family member do something for you?", |
|||
"Did anyone give you a compliment?", |
|||
"Did you see anyone give to someone else?", |
|||
"Did anyone give you a good laugh?", |
|||
"Do you recall anything that was given to you while you were young?", |
|||
"Do you know of a way an ancestor contributed to your life?", |
|||
]; |
|||
OTHER_PROMPTS = 1; |
|||
CONTACT_PROMPT_INDEX = this.IDEAS.length; // expected after other prompts |
|||
|
|||
currentContact: Contact | undefined = undefined; |
|||
currentIdeaIndex = 0; |
|||
numContacts = 0; |
|||
shownContactDbIndices: number[] = []; |
|||
visible = false; |
|||
|
|||
AppString = AppString; |
|||
|
|||
async open() { |
|||
this.visible = true; |
|||
|
|||
await db.open(); |
|||
this.numContacts = await db.contacts.count(); |
|||
} |
|||
|
|||
close() { |
|||
// close the dialog but don't change values (just in case some actions are added later) |
|||
this.visible = false; |
|||
} |
|||
|
|||
/** |
|||
* Get the next idea. |
|||
* If it is a contact prompt, loop through. |
|||
*/ |
|||
async nextIdea() { |
|||
// if we're incrementing to the contact prompt |
|||
// or if we're at the contact prompt and there was a previous contact... |
|||
if ( |
|||
this.currentIdeaIndex == this.CONTACT_PROMPT_INDEX - 1 || |
|||
(this.currentIdeaIndex == this.CONTACT_PROMPT_INDEX && |
|||
this.currentContact) |
|||
) { |
|||
this.currentIdeaIndex = this.CONTACT_PROMPT_INDEX; |
|||
this.findNextUnshownContact(); |
|||
} else { |
|||
// we're not at the contact prompt (or we ran out), so increment the idea index |
|||
this.currentIdeaIndex = |
|||
(this.currentIdeaIndex + 1) % (this.IDEAS.length + this.OTHER_PROMPTS); |
|||
// ... and clear out any other prompt info |
|||
this.currentContact = undefined; |
|||
this.shownContactDbIndices = []; |
|||
} |
|||
} |
|||
|
|||
prevIdea() { |
|||
if ( |
|||
this.currentIdeaIndex == |
|||
(this.CONTACT_PROMPT_INDEX + 1) % |
|||
(this.IDEAS.length + this.OTHER_PROMPTS) || |
|||
(this.currentIdeaIndex == this.CONTACT_PROMPT_INDEX && |
|||
this.currentContact) |
|||
) { |
|||
this.currentIdeaIndex = this.CONTACT_PROMPT_INDEX; |
|||
this.findNextUnshownContact(); |
|||
} else { |
|||
// we're not at the contact prompt (or we ran out), so increment the idea index |
|||
this.currentIdeaIndex--; |
|||
if (this.currentIdeaIndex < 0) { |
|||
this.currentIdeaIndex = this.IDEAS.length - 1 + this.OTHER_PROMPTS; |
|||
} |
|||
// ... and clear out any other prompt info |
|||
this.currentContact = undefined; |
|||
this.shownContactDbIndices = []; |
|||
} |
|||
} |
|||
|
|||
async findNextUnshownContact() { |
|||
// get a random contact |
|||
if (this.shownContactDbIndices.length === this.numContacts) { |
|||
// no more contacts to show |
|||
this.currentContact = undefined; |
|||
} else { |
|||
// get a random contact that hasn't been shown yet |
|||
let someContactDbIndex = Math.floor(Math.random() * this.numContacts); |
|||
// and guarantee that one is found by walking past shown contacts |
|||
let shownContactIndex = |
|||
this.shownContactDbIndices.indexOf(someContactDbIndex); |
|||
while (shownContactIndex !== -1) { |
|||
// increment both indices until we find a spot where "shown" skips a spot |
|||
shownContactIndex = (shownContactIndex + 1) % this.numContacts; |
|||
someContactDbIndex = (someContactDbIndex + 1) % this.numContacts; |
|||
if ( |
|||
this.shownContactDbIndices[shownContactIndex] !== someContactDbIndex |
|||
) { |
|||
// we found a contact that hasn't been shown yet |
|||
break; |
|||
} |
|||
// continue |
|||
// ... and there must be at least one because shownContactDbIndices length < numContacts |
|||
} |
|||
this.shownContactDbIndices.push(someContactDbIndex); |
|||
this.shownContactDbIndices.sort(); |
|||
|
|||
// get the contact at that offset |
|||
await db.open(); |
|||
this.currentContact = await db.contacts |
|||
.offset(someContactDbIndex) |
|||
.first(); |
|||
} |
|||
} |
|||
|
|||
cancel() { |
|||
this.currentContact = undefined; |
|||
this.currentIdeaIndex = 0; |
|||
this.numContacts = 0; |
|||
this.shownContactDbIndices = []; |
|||
|
|||
this.close(); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
.dialog-overlay { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
padding: 1.5rem; |
|||
} |
|||
|
|||
.dialog { |
|||
background-color: white; |
|||
padding: 1rem; |
|||
border-radius: 0.5rem; |
|||
width: 100%; |
|||
max-width: 500px; |
|||
} |
|||
</style> |
Loading…
Reference in new issue