diff --git a/src/interfaces/records.ts b/src/interfaces/records.ts index 3df8469..44d0c65 100644 --- a/src/interfaces/records.ts +++ b/src/interfaces/records.ts @@ -58,6 +58,7 @@ export interface PlanSummaryRecord { name?: string; startTime?: string; url?: string; + jwtId?: string; } /** diff --git a/src/lib/capacitor/app.ts b/src/lib/capacitor/app.ts index 3dec280..038fe67 100644 --- a/src/lib/capacitor/app.ts +++ b/src/lib/capacitor/app.ts @@ -4,7 +4,7 @@ import { App as CapacitorApp, AppLaunchUrl, BackButtonListener, -} from '../../../node_modules/@capacitor/app'; +} from "../../../node_modules/@capacitor/app"; import type { PluginListenerHandle } from "@capacitor/core"; /** diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts index f64b568..181ce23 100644 --- a/src/libs/endorserServer.ts +++ b/src/libs/endorserServer.ts @@ -1,18 +1,18 @@ /** * @fileoverview Endorser Server Interface and Utilities * @author Matthew Raymer - * + * * This module provides the interface and utilities for interacting with the Endorser server. * It handles authentication, data validation, and server communication for claims, contacts, * and other core functionality. - * + * * Key Features: * - Deep link URL path constants * - DID validation and handling * - Contact management utilities * - Server authentication * - Plan caching - * + * * @module endorserServer */ @@ -136,35 +136,35 @@ export function isEmptyOrHiddenDid(did?: string): boolean { * @param {Function} func - Test function to apply to strings * @param {any} input - Object/array to recursively test * @returns {boolean} True if any string passes the test function - * + * * @example * testRecursivelyOnStrings(isDid, { user: { id: "did:example:123" } }) * // Returns: true */ /** * Recursively tests strings within a nested object/array structure against a test function - * + * * This function traverses through objects and arrays to find all string values and applies * a test function to each string found. It handles: * - Direct string values * - Strings in objects (at any depth) * - Strings in arrays (at any depth) * - Mixed nested structures (objects containing arrays containing objects, etc) - * + * * @param {Function} func - Test function that takes a string and returns boolean * @param {any} input - Value to recursively search (can be string, object, array, or other) * @returns {boolean} True if any string in the structure passes the test function - * + * * @example * // Test if any string is a DID * const obj = { - * user: { + * user: { * id: "did:example:123", - * details: ["name", "did:example:456"] + * details: ["name", "did:example:456"] * } * }; * testRecursivelyOnStrings(isDid, obj); // Returns: true - * + * * @example * // Test for hidden DIDs * const obj = { @@ -175,12 +175,12 @@ export function isEmptyOrHiddenDid(did?: string): boolean { */ function testRecursivelyOnStrings( func: (arg0: any) => boolean, - input: any + input: any, ): boolean { // Test direct string values if (Object.prototype.toString.call(input) === "[object String]") { return func(input); - } + } // Recursively test objects and arrays else if (input instanceof Object) { if (!Array.isArray(input)) { @@ -482,7 +482,7 @@ const planCache: LRUCache = new LRUCache({ * @param {string} apiServer - API server URL * @param {string} [requesterDid] - Optional requester DID for private info * @returns {Promise} Plan data or undefined if not found - * + * * @throws {Error} If server request fails */ export async function getPlanFromCache( diff --git a/src/views/ContactEditView.vue b/src/views/ContactEditView.vue index cc73e1e..34d7dd7 100644 --- a/src/views/ContactEditView.vue +++ b/src/views/ContactEditView.vue @@ -145,28 +145,28 @@ import { Contact, ContactMethod } from "../db/tables/contacts"; /** * Contact Edit View Component * @author Matthew Raymer - * + * * This component provides a full-featured contact editing interface with support for: * - Basic contact information (name, notes) * - Multiple contact methods with type selection * - Data validation and persistence - * + * * Workflow: * 1. Component loads with DID from route params * 2. Fetches existing contact data from IndexedDB * 3. Presents editable form with current values * 4. Validates and saves updates back to database - * + * * Contact Method Types: * - CELL: Mobile phone numbers * - EMAIL: Email addresses * - WHATSAPP: WhatsApp contact info - * + * * State Management: * - Maintains separate state for form fields to prevent direct mutation * - Handles array cloning for contact methods to prevent reference issues * - Manages dropdown state for method type selection - * + * * Navigation: * - Back button returns to previous view * - Save redirects to contact detail view @@ -207,13 +207,13 @@ export default class ContactEditView extends Vue { /** * Component lifecycle hook that initializes the contact edit form - * + * * Workflow: * 1. Extracts DID from route parameters * 2. Queries database for existing contact * 3. Populates form fields with contact data * 4. Handles missing contact error case - * + * * @throws Will not throw but redirects on error * @emits Notification on contact not found * @emits Router navigation on error @@ -240,7 +240,7 @@ export default class ContactEditView extends Vue { /** * Adds a new empty contact method to the methods array - * + * * Creates a new method object with empty fields for: * - label: Custom label for the method * - type: Communication type (CELL, EMAIL, WHATSAPP) @@ -252,7 +252,7 @@ export default class ContactEditView extends Vue { /** * Removes a contact method at the specified index - * + * * @param index The array index of the method to remove */ removeContactMethod(index: number) { @@ -261,10 +261,10 @@ export default class ContactEditView extends Vue { /** * Toggles the type selection dropdown for a contact method - * + * * If the clicked dropdown is already open, closes it. * If another dropdown is open, closes it and opens the clicked one. - * + * * @param index The array index of the method whose dropdown to toggle */ toggleDropdown(index: number) { @@ -273,7 +273,7 @@ export default class ContactEditView extends Vue { /** * Sets the type for a contact method and closes the dropdown - * + * * @param index The array index of the method to update * @param type The new type value (CELL, EMAIL, WHATSAPP) */ @@ -284,7 +284,7 @@ export default class ContactEditView extends Vue { /** * Saves the edited contact information to the database - * + * * Workflow: * 1. Clones contact methods array to prevent reference issues * 2. Normalizes method types to uppercase @@ -292,7 +292,7 @@ export default class ContactEditView extends Vue { * 4. Updates database with new values * 5. Notifies user of success * 6. Redirects to contact detail view - * + * * @throws Will not throw but notifies on validation errors * @emits Notification on type changes or success * @emits Router navigation on success @@ -300,7 +300,7 @@ export default class ContactEditView extends Vue { async saveEdit() { // without this conversion, "Failed to execute 'put' on 'IDBObjectStore': [object Array] could not be cloned." const contactMethodsObj = JSON.parse(JSON.stringify(this.contactMethods)); - + // Normalize method types to uppercase const contactMethods = contactMethodsObj.map((method: ContactMethod) => R.set(R.lensProp("type"), method.type.toUpperCase(), method), diff --git a/src/views/ContactImportView.vue b/src/views/ContactImportView.vue index e817618..7e25e85 100644 --- a/src/views/ContactImportView.vue +++ b/src/views/ContactImportView.vue @@ -3,7 +3,10 @@
-

+

@@ -17,28 +20,43 @@
- + Make my activity visible to these contacts.
- One contact is the same as an existing contact - {{ sameCount }} contacts are the same as existing contacts + One contact is the same as an existing contact + {{ sameCount }} contacts are the same as existing contacts
-
    +
    • -
      +

      {{ contact.name || AppString.NO_CONTACT_NAME }} - - Existing + Existing New

      @@ -51,9 +69,13 @@
      Old Value
      New Value
      -
      +
      {{ capitalizeAndInsertSpacesBeforeCaps(contactField) }}
      @@ -66,7 +88,8 @@
    @@ -78,10 +101,18 @@ get the full text and paste it. (Note that iOS cuts off data in text messages.) Ask the person to send the data a different way, eg. email.
    -