+
+ {{ project.name || unnamedProject }}
+
-
-
- {{ issuerDisplayName }}
+
+
+ {{ issuerDisplayName }}
+
diff --git a/src/components/ShowAllCard.vue b/src/components/ShowAllCard.vue
deleted file mode 100644
index b4a43c43..00000000
--- a/src/components/ShowAllCard.vue
+++ /dev/null
@@ -1,66 +0,0 @@
-/** * ShowAllCard.vue - Show All navigation card component * * Extracted from
-GiftedDialog.vue to handle "Show All" navigation * for both people and projects
-entity types. * * @author Matthew Raymer */
-
-
-
-
-
- Show All
-
-
-
-
-
-
-
-
diff --git a/src/components/SpecialEntityCard.vue b/src/components/SpecialEntityCard.vue
index e489d003..30e6131c 100644
--- a/src/components/SpecialEntityCard.vue
+++ b/src/components/SpecialEntityCard.vue
@@ -63,23 +63,24 @@ export default class SpecialEntityCard extends Vue {
conflictContext!: string;
/**
- * Computed CSS classes for the card container
+ * Computed CSS classes for the card
*/
get cardClasses(): string {
- const baseClasses = "block";
+ const baseCardClasses =
+ "flex items-center gap-2 px-2 py-1.5 border-b border-slate-300";
if (!this.selectable || this.conflicted) {
- return `${baseClasses} cursor-not-allowed opacity-50`;
+ return `${baseCardClasses} *:opacity-50 cursor-not-allowed`;
}
- return `${baseClasses} cursor-pointer`;
+ return `${baseCardClasses} cursor-pointer hover:bg-slate-50`;
}
/**
* Computed CSS classes for the icon
*/
get iconClasses(): string {
- const baseClasses = "text-5xl mb-1";
+ const baseClasses = "text-[2rem]";
if (this.conflicted) {
return `${baseClasses} text-slate-400`;
@@ -101,7 +102,7 @@ export default class SpecialEntityCard extends Vue {
*/
get nameClasses(): string {
const baseClasses =
- "text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden";
+ "text-sm font-semibold text-ellipsis whitespace-nowrap overflow-hidden";
if (this.conflicted) {
return `${baseClasses} text-slate-400`;
diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts
index 36bfa223..8eb2cd68 100644
--- a/src/libs/endorserServer.ts
+++ b/src/libs/endorserServer.ts
@@ -1686,7 +1686,10 @@ export async function register(
"Registration thrown error:",
errorMessage || JSON.stringify(err),
);
- return { error: errorMessage || "Got a server error when registering." };
+ return {
+ error:
+ (errorMessage as string) || "Got a server error when registering.",
+ };
}
return { error: "Got a server error when registering." };
}
diff --git a/src/services/platforms/CapacitorPlatformService.ts b/src/services/platforms/CapacitorPlatformService.ts
index 6ff9b503..4b49d123 100644
--- a/src/services/platforms/CapacitorPlatformService.ts
+++ b/src/services/platforms/CapacitorPlatformService.ts
@@ -96,16 +96,92 @@ export class CapacitorPlatformService
}
try {
- // Create/Open database
- this.db = await this.sqlite.createConnection(
- this.dbName,
- false,
- "no-encryption",
- 1,
- false,
- );
+ // Try to create/Open database connection
+ try {
+ this.db = await this.sqlite.createConnection(
+ this.dbName,
+ false,
+ "no-encryption",
+ 1,
+ false,
+ );
+ } catch (createError: unknown) {
+ // If connection already exists, try to retrieve it or handle gracefully
+ const errorMessage =
+ createError instanceof Error
+ ? createError.message
+ : String(createError);
+ const errorObj =
+ typeof createError === "object" && createError !== null
+ ? (createError as { errorMessage?: string; message?: string })
+ : {};
+
+ const fullErrorMessage =
+ errorObj.errorMessage || errorObj.message || errorMessage;
+
+ if (fullErrorMessage.includes("already exists")) {
+ logger.debug(
+ "[CapacitorPlatformService] Connection already exists on native side, attempting to retrieve",
+ );
+ // Check if connection exists in JavaScript Map
+ const isConnResult = await this.sqlite.isConnection(
+ this.dbName,
+ false,
+ );
+ if (isConnResult.result) {
+ // Connection exists in Map, retrieve it
+ this.db = await this.sqlite.retrieveConnection(this.dbName, false);
+ logger.debug(
+ "[CapacitorPlatformService] Successfully retrieved existing connection from Map",
+ );
+ } else {
+ // Connection exists on native side but not in JavaScript Map
+ // This can happen when the app is restarted but native connections persist
+ // Try to close the native connection first, then create a new one
+ logger.debug(
+ "[CapacitorPlatformService] Connection exists natively but not in Map, closing and recreating",
+ );
+ try {
+ await this.sqlite.closeConnection(this.dbName, false);
+ } catch (closeError) {
+ // Ignore close errors - connection might not be properly tracked
+ logger.debug(
+ "[CapacitorPlatformService] Error closing connection (may be expected):",
+ closeError,
+ );
+ }
+ // Now try to create the connection again
+ this.db = await this.sqlite.createConnection(
+ this.dbName,
+ false,
+ "no-encryption",
+ 1,
+ false,
+ );
+ logger.debug(
+ "[CapacitorPlatformService] Successfully created connection after cleanup",
+ );
+ }
+ } else {
+ // Re-throw if it's a different error
+ throw createError;
+ }
+ }
- await this.db.open();
+ // Open the connection if it's not already open
+ try {
+ await this.db.open();
+ } catch (openError: unknown) {
+ const openErrorMessage =
+ openError instanceof Error ? openError.message : String(openError);
+ // If already open, that's fine - continue
+ if (!openErrorMessage.includes("already open")) {
+ throw openError;
+ }
+ logger.debug(
+ "[CapacitorPlatformService] Database connection already open",
+ );
+ }
// Set journal mode to WAL for better performance
// await this.db.execute("PRAGMA journal_mode=WAL;");
diff --git a/src/test/EntityGridFunctionPropTest.vue b/src/test/EntityGridFunctionPropTest.vue
index 91796f7c..3b10461a 100644
--- a/src/test/EntityGridFunctionPropTest.vue
+++ b/src/test/EntityGridFunctionPropTest.vue
@@ -19,7 +19,6 @@
{
- return entities
- .filter((person) => person.profileImageUrl)
- .slice(0, maxItems);
+ return entities.filter((person) => person.profileImageUrl);
};
/**
@@ -165,7 +160,6 @@ export default class EntityGridFunctionPropTest extends Vue {
customProjectsFunction = (
entities: PlanData[],
_entityType: string,
- _maxItems: number,
): PlanData[] => {
return entities.sort((a, b) => a.name.localeCompare(b.name)).slice(0, 3);
};
@@ -200,16 +194,16 @@ export default class EntityGridFunctionPropTest extends Vue {
*/
get displayedPeopleCount(): number {
if (this.useCustomFunction) {
- return this.customPeopleFunction(this.people, "people", 5).length;
+ return this.customPeopleFunction(this.people, "people").length;
}
- return Math.min(5, this.people.length);
+ return Math.min(10, this.people.length); // Initial batch size for infinite scroll
}
get displayedProjectsCount(): number {
if (this.useCustomFunction) {
- return this.customProjectsFunction(this.projects, "projects", 3).length;
+ return this.customProjectsFunction(this.projects, "projects").length;
}
- return Math.min(7, this.projects.length);
+ return Math.min(10, this.projects.length); // Initial batch size for infinite scroll
}
}
diff --git a/src/utils/PlatformServiceMixin.ts b/src/utils/PlatformServiceMixin.ts
index ad0b249f..cc649373 100644
--- a/src/utils/PlatformServiceMixin.ts
+++ b/src/utils/PlatformServiceMixin.ts
@@ -970,6 +970,20 @@ export const PlatformServiceMixin = {
return this.$normalizeContacts(rawContacts);
},
+ /**
+ * Load all contacts sorted by when they were added (by ID)
+ * Always fetches fresh data from database for consistency
+ * Handles JSON string/object duality for contactMethods field
+ * @returns Promise Array of normalized contact objects sorted by addition date (newest first)
+ */
+ async $contactsByDateAdded(): Promise {
+ const rawContacts = (await this.$query(
+ "SELECT * FROM contacts ORDER BY id DESC",
+ )) as ContactMaybeWithJsonStrings[];
+
+ return this.$normalizeContacts(rawContacts);
+ },
+
/**
* Ultra-concise shortcut for getting number of contacts
* @returns Promise Total number of contacts
@@ -2057,6 +2071,7 @@ declare module "@vue/runtime-core" {
// Specialized shortcuts - contacts cached, settings fresh
$contacts(): Promise;
+ $contactsByDateAdded(): Promise;
$contactCount(): Promise;
$settings(defaults?: Settings): Promise;
$accountSettings(did?: string, defaults?: Settings): Promise;