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