You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							242 lines
						
					
					
						
							7.7 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							242 lines
						
					
					
						
							7.7 KiB
						
					
					
				
								<template>
							 | 
						|
								  <div v-if="visible" class="dialog-overlay">
							 | 
						|
								    <div class="dialog">
							 | 
						|
								      <h1 class="text-xl font-bold text-center mb-4 relative">
							 | 
						|
								        Here's one:
							 | 
						|
								        <div
							 | 
						|
								          class="text-lg text-center p-2 leading-none absolute right-0 -top-1"
							 | 
						|
								          @click="cancel"
							 | 
						|
								        >
							 | 
						|
								          <fa icon="xmark" class="w-[1em]"></fa>
							 | 
						|
								        </div>
							 | 
						|
								      </h1>
							 | 
						|
								      <span class="flex justify-between">
							 | 
						|
								        <span
							 | 
						|
								          class="rounded-l border border-slate-400 bg-slate-200 px-4 py-2 flex"
							 | 
						|
								          @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">
							 | 
						|
								              <span
							 | 
						|
								                v-if="currentContact == null"
							 | 
						|
								                class="text-orange-500 text-lg font-bold"
							 | 
						|
								              >
							 | 
						|
								                That's all your contacts.
							 | 
						|
								              </span>
							 | 
						|
								              <span v-else>
							 | 
						|
								                <span class="text-lg font-bold">
							 | 
						|
								                  Did {{ currentContact.name || AppString.NO_CONTACT_NAME }}
							 | 
						|
								                  <br />
							 | 
						|
								                  or someone near them do anything – maybe a while ago?
							 | 
						|
								                </span>
							 | 
						|
								                <span class="flex justify-between">
							 | 
						|
								                  <span />
							 | 
						|
								                  <button
							 | 
						|
								                    class="text-center bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4"
							 | 
						|
								                    @click="nextIdeaPastContacts()"
							 | 
						|
								                  >
							 | 
						|
								                    Skip Contacts <fa icon="forward" />
							 | 
						|
								                  </button>
							 | 
						|
								                </span>
							 | 
						|
								              </span>
							 | 
						|
								            </p>
							 | 
						|
								          </div>
							 | 
						|
								        </div>
							 | 
						|
								
							 | 
						|
								        <span
							 | 
						|
								          class="rounded-r border border-slate-400 bg-slate-200 px-4 py-2 flex"
							 | 
						|
								          @click="nextIdea()"
							 | 
						|
								        >
							 | 
						|
								          <fa icon="chevron-right" class="m-auto" />
							 | 
						|
								        </span>
							 | 
						|
								      </span>
							 | 
						|
								      <button
							 | 
						|
								        class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] 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, NotificationIface } from "@/constants/app";
							 | 
						|
								import { db } from "@/db/index";
							 | 
						|
								import { Contact } from "@/db/tables/contacts";
							 | 
						|
								
							 | 
						|
								@Component
							 | 
						|
								export default class GivenPrompts extends Vue {
							 | 
						|
								  $notify!: (notification: NotificationIface, timeout?: number) => void;
							 | 
						|
								
							 | 
						|
								  IDEAS = [
							 | 
						|
								    "Did anyone fix food for you?",
							 | 
						|
								    "Did a family member do something for you?",
							 | 
						|
								    "Did anyone give you a compliment?",
							 | 
						|
								    "Who is someone you can always rely on, and how did they demonstrate that?",
							 | 
						|
								    "Did you see anyone give to someone else?",
							 | 
						|
								    "Is there someone who you have never met who has helped you somehow?",
							 | 
						|
								    "How did an artist or musician or author inspire you?",
							 | 
						|
								    "What inspiration did you get from someone who handled tragedy well?",
							 | 
						|
								    "Did some organization give something worth respect?",
							 | 
						|
								    "Who last gave you a good laugh?",
							 | 
						|
								    "Do you recall anything that was given to you while you were young?",
							 | 
						|
								    "Did someone forgive you or overlook a mistake?",
							 | 
						|
								    "Do you know of a way an ancestor contributed to your life?",
							 | 
						|
								    "Did anyone give you help at work?",
							 | 
						|
								    "How did a teacher or mentor or great example help you?",
							 | 
						|
								  ];
							 | 
						|
								  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.shownContactDbIndices.length < this.numContacts)
							 | 
						|
								    ) {
							 | 
						|
								      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.shownContactDbIndices.length < this.numContacts)
							 | 
						|
								    ) {
							 | 
						|
								      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 = [];
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  nextIdeaPastContacts() {
							 | 
						|
								    this.currentIdeaIndex = 0;
							 | 
						|
								    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>
							 | 
						|
								
							 |