forked from jsnbuchanan/crowd-funder-for-time-pwa
Merge pull request 'fix creation of did-specific settings (with a rename)' (#138) from fix-did-specifics into master
Reviewed-on: trent_larson/crowd-funder-for-time-pwa#138
This commit is contained in:
892
package-lock.json
generated
892
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -104,7 +104,6 @@ import { USE_DEXIE_DB } from "@/constants/app";
|
||||
import * as databaseUtil from "../db/databaseUtil";
|
||||
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
|
||||
import { db, retrieveSettingsForActiveAccount } from "../db/index";
|
||||
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
@@ -143,19 +142,23 @@ export default class FeedFilters extends Vue {
|
||||
async toggleHasVisibleDid() {
|
||||
this.settingChanged = true;
|
||||
this.hasVisibleDid = !this.hasVisibleDid;
|
||||
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
await databaseUtil.updateDefaultSettings({
|
||||
filterFeedByVisible: this.hasVisibleDid,
|
||||
});
|
||||
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
filterFeedByVisible: this.hasVisibleDid,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async toggleNearby() {
|
||||
this.settingChanged = true;
|
||||
this.isNearby = !this.isNearby;
|
||||
const platformService = PlatformServiceFactory.getInstance();
|
||||
await platformService.dbExec(
|
||||
`UPDATE settings SET filterFeedByNearby = ? WHERE id = ?`,
|
||||
[this.isNearby, MASTER_SETTINGS_KEY],
|
||||
);
|
||||
await databaseUtil.updateDefaultSettings({
|
||||
filterFeedByNearby: this.isNearby,
|
||||
});
|
||||
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
@@ -169,11 +172,10 @@ export default class FeedFilters extends Vue {
|
||||
this.settingChanged = true;
|
||||
}
|
||||
|
||||
const platformService = PlatformServiceFactory.getInstance();
|
||||
await platformService.dbExec(
|
||||
`UPDATE settings SET filterFeedByNearby = ? AND filterFeedByVisible = ? WHERE id = ?`,
|
||||
[false, false, MASTER_SETTINGS_KEY],
|
||||
);
|
||||
await databaseUtil.updateDefaultSettings({
|
||||
filterFeedByNearby: false,
|
||||
filterFeedByVisible: false,
|
||||
});
|
||||
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
@@ -191,11 +193,10 @@ export default class FeedFilters extends Vue {
|
||||
this.settingChanged = true;
|
||||
}
|
||||
|
||||
const platformService = PlatformServiceFactory.getInstance();
|
||||
await platformService.dbExec(
|
||||
`UPDATE settings SET filterFeedByNearby = ? AND filterFeedByVisible = ? WHERE id = ?`,
|
||||
[true, true, MASTER_SETTINGS_KEY],
|
||||
);
|
||||
await databaseUtil.updateDefaultSettings({
|
||||
filterFeedByNearby: true,
|
||||
filterFeedByVisible: true,
|
||||
});
|
||||
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
|
||||
@@ -227,6 +227,7 @@ export default class GivenPrompts extends Vue {
|
||||
|
||||
let someContactDbIndex = Math.floor(Math.random() * this.numContacts);
|
||||
let count = 0;
|
||||
|
||||
// as long as the index has an entry, loop
|
||||
while (
|
||||
this.shownContactDbIndices[someContactDbIndex] != null &&
|
||||
@@ -245,9 +246,8 @@ export default class GivenPrompts extends Vue {
|
||||
[someContactDbIndex],
|
||||
);
|
||||
if (result) {
|
||||
this.currentContact = databaseUtil.mapQueryResultToValues(result)[
|
||||
someContactDbIndex
|
||||
] as unknown as Contact;
|
||||
const mappedContacts = databaseUtil.mapQueryResultToValues(result);
|
||||
this.currentContact = mappedContacts[0] as unknown as Contact;
|
||||
}
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.open();
|
||||
|
||||
@@ -259,7 +259,7 @@ export default class OnboardingDialog extends Vue {
|
||||
this.visible = true;
|
||||
if (this.page === OnboardPage.Create) {
|
||||
// we'll assume that they've been through all the other pages
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
finishedOnboarding: true,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
@@ -273,7 +273,7 @@ export default class OnboardingDialog extends Vue {
|
||||
async onClickClose(done?: boolean, goHome?: boolean) {
|
||||
this.visible = false;
|
||||
if (done) {
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
finishedOnboarding: true,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
|
||||
@@ -37,7 +37,20 @@ export async function updateDefaultSettings(
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateAccountSettings(
|
||||
export async function insertDidSpecificSettings(
|
||||
did: string,
|
||||
settings: Partial<Settings> = {},
|
||||
): Promise<boolean> {
|
||||
const platform = PlatformServiceFactory.getInstance();
|
||||
const { sql, params } = generateInsertStatement(
|
||||
{ ...settings, accountDid: did }, // make sure accountDid is set to the given value
|
||||
"settings",
|
||||
);
|
||||
const result = await platform.dbExec(sql, params);
|
||||
return result.changes === 1;
|
||||
}
|
||||
|
||||
export async function updateDidSpecificSettings(
|
||||
accountDid: string,
|
||||
settingsChanges: Settings,
|
||||
): Promise<boolean> {
|
||||
@@ -96,9 +109,6 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
|
||||
const defaultSettings = await retrieveSettingsForDefaultAccount();
|
||||
// If no active DID, return defaults
|
||||
if (!defaultSettings.activeDid) {
|
||||
logConsoleAndDb(
|
||||
"[databaseUtil] No active DID found, returning default settings",
|
||||
);
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
@@ -111,9 +121,7 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
|
||||
);
|
||||
|
||||
if (!result?.values?.length) {
|
||||
logConsoleAndDb(
|
||||
`[databaseUtil] No account-specific settings found for ${defaultSettings.activeDid}`,
|
||||
);
|
||||
// we created DID-specific settings when generated or imported, so this shouldn't happen
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
@@ -122,6 +130,7 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
|
||||
result.columns,
|
||||
result.values,
|
||||
)[0] as Settings;
|
||||
|
||||
const overrideSettingsFiltered = Object.fromEntries(
|
||||
Object.entries(overrideSettings).filter(([_, v]) => v !== null),
|
||||
);
|
||||
@@ -131,17 +140,7 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
|
||||
|
||||
// Handle searchBoxes parsing
|
||||
if (settings.searchBoxes) {
|
||||
try {
|
||||
// @ts-expect-error - the searchBoxes field is a string in the DB
|
||||
settings.searchBoxes = JSON.parse(settings.searchBoxes);
|
||||
} catch (error) {
|
||||
logConsoleAndDb(
|
||||
`[databaseUtil] Failed to parse searchBoxes for ${defaultSettings.activeDid}: ${error}`,
|
||||
true,
|
||||
);
|
||||
// Reset to empty array on parse failure
|
||||
settings.searchBoxes = [];
|
||||
}
|
||||
settings.searchBoxes = parseJsonField(settings.searchBoxes, []);
|
||||
}
|
||||
|
||||
return settings;
|
||||
@@ -241,6 +240,7 @@ export function generateInsertStatement(
|
||||
const values = Object.values(model).filter((value) => value !== undefined);
|
||||
const placeholders = values.map(() => "?").join(", ");
|
||||
const insertSql = `INSERT INTO ${tableName} (${columns.join(", ")}) VALUES (${placeholders})`;
|
||||
|
||||
return {
|
||||
sql: insertSql,
|
||||
params: values,
|
||||
@@ -312,3 +312,115 @@ export function mapColumnsToValues(
|
||||
return obj;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug function to inspect raw settings data in the database
|
||||
* This helps diagnose issues with data corruption or malformed JSON
|
||||
* @param did Optional DID to inspect specific account settings
|
||||
* @author Matthew Raymer
|
||||
*/
|
||||
export async function debugSettingsData(did?: string): Promise<void> {
|
||||
try {
|
||||
const platform = PlatformServiceFactory.getInstance();
|
||||
|
||||
// Get all settings records
|
||||
const allSettings = await platform.dbQuery("SELECT * FROM settings");
|
||||
|
||||
logConsoleAndDb(
|
||||
`[DEBUG] Total settings records: ${allSettings?.values?.length || 0}`,
|
||||
false,
|
||||
);
|
||||
|
||||
if (allSettings?.values?.length) {
|
||||
allSettings.values.forEach((row, index) => {
|
||||
const settings = mapColumnsToValues(allSettings.columns, [row])[0];
|
||||
logConsoleAndDb(`[DEBUG] Settings record ${index + 1}:`, false);
|
||||
logConsoleAndDb(`[DEBUG] - ID: ${settings.id}`, false);
|
||||
logConsoleAndDb(`[DEBUG] - accountDid: ${settings.accountDid}`, false);
|
||||
logConsoleAndDb(`[DEBUG] - activeDid: ${settings.activeDid}`, false);
|
||||
|
||||
if (settings.searchBoxes) {
|
||||
logConsoleAndDb(
|
||||
`[DEBUG] - searchBoxes type: ${typeof settings.searchBoxes}`,
|
||||
false,
|
||||
);
|
||||
logConsoleAndDb(
|
||||
`[DEBUG] - searchBoxes value: ${String(settings.searchBoxes)}`,
|
||||
false,
|
||||
);
|
||||
|
||||
// Try to parse it
|
||||
try {
|
||||
const parsed = JSON.parse(String(settings.searchBoxes));
|
||||
logConsoleAndDb(
|
||||
`[DEBUG] - searchBoxes parsed successfully: ${JSON.stringify(parsed)}`,
|
||||
false,
|
||||
);
|
||||
} catch (parseError) {
|
||||
logConsoleAndDb(
|
||||
`[DEBUG] - searchBoxes parse error: ${parseError}`,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
logConsoleAndDb(
|
||||
`[DEBUG] - Full record: ${JSON.stringify(settings, null, 2)}`,
|
||||
false,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// If specific DID provided, also check accounts table
|
||||
if (did) {
|
||||
const account = await platform.dbQuery(
|
||||
"SELECT * FROM accounts WHERE did = ?",
|
||||
[did],
|
||||
);
|
||||
logConsoleAndDb(
|
||||
`[DEBUG] Account for ${did}: ${JSON.stringify(account, null, 2)}`,
|
||||
false,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
logConsoleAndDb(`[DEBUG] Error inspecting settings data: ${error}`, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Platform-agnostic JSON parsing utility
|
||||
* Handles different SQLite implementations:
|
||||
* - Web SQLite (wa-sqlite/absurd-sql): Auto-parses JSON strings to objects
|
||||
* - Capacitor SQLite: Returns raw strings that need manual parsing
|
||||
*
|
||||
* @param value The value to parse (could be string or already parsed object)
|
||||
* @param defaultValue Default value if parsing fails
|
||||
* @returns Parsed object or default value
|
||||
* @author Matthew Raymer
|
||||
*/
|
||||
export function parseJsonField<T>(value: unknown, defaultValue: T): T {
|
||||
try {
|
||||
// If already an object (web SQLite auto-parsed), return as-is
|
||||
if (typeof value === "object" && value !== null) {
|
||||
return value as T;
|
||||
}
|
||||
|
||||
// If it's a string (Capacitor SQLite or fallback), parse it
|
||||
if (typeof value === "string") {
|
||||
return JSON.parse(value) as T;
|
||||
}
|
||||
|
||||
// If it's null/undefined, return default
|
||||
if (value === null || value === undefined) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
} catch (error) {
|
||||
logConsoleAndDb(
|
||||
`[databaseUtil] Failed to parse JSON field: ${error}`,
|
||||
true,
|
||||
);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import { logger } from "../utils/logger";
|
||||
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||
import { sha256 } from "ethereum-cryptography/sha256";
|
||||
import { IIdentifier } from "@veramo/core";
|
||||
import { insertDidSpecificSettings, parseJsonField } from "../db/databaseUtil";
|
||||
|
||||
export interface GiverReceiverInputInfo {
|
||||
did?: string;
|
||||
@@ -697,6 +698,7 @@ export async function saveNewIdentity(
|
||||
];
|
||||
await platformService.dbExec(sql, params);
|
||||
await databaseUtil.updateDefaultSettings({ activeDid: identity.did });
|
||||
await databaseUtil.insertDidSpecificSettings(identity.did);
|
||||
|
||||
if (USE_DEXIE_DB) {
|
||||
// one of the few times we use accountsDBPromise directly; try to avoid more usage
|
||||
@@ -710,6 +712,7 @@ export async function saveNewIdentity(
|
||||
publicKeyHex: identity.keys[0].publicKeyHex,
|
||||
});
|
||||
await updateDefaultSettings({ activeDid: identity.did });
|
||||
await insertDidSpecificSettings(identity.did);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Failed to update default settings:", error);
|
||||
@@ -732,7 +735,9 @@ export const generateSaveAndActivateIdentity = async (): Promise<string> => {
|
||||
const newId = newIdentifier(address, publicHex, privateHex, derivationPath);
|
||||
|
||||
await saveNewIdentity(newId, mnemonic, derivationPath);
|
||||
await databaseUtil.updateAccountSettings(newId.did, { isRegistered: false });
|
||||
await databaseUtil.updateDidSpecificSettings(newId.did, {
|
||||
isRegistered: false,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
await updateAccountSettings(newId.did, { isRegistered: false });
|
||||
}
|
||||
@@ -774,7 +779,7 @@ export const registerSaveAndActivatePasskey = async (
|
||||
): Promise<Account> => {
|
||||
const account = await registerAndSavePasskey(keyName);
|
||||
await databaseUtil.updateDefaultSettings({ activeDid: account.did });
|
||||
await databaseUtil.updateAccountSettings(account.did, {
|
||||
await databaseUtil.updateDidSpecificSettings(account.did, {
|
||||
isRegistered: false,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
@@ -862,7 +867,7 @@ export const contactToCsvLine = (contact: Contact): string => {
|
||||
|
||||
// Handle contactMethods array by stringifying it
|
||||
const contactMethodsStr = contact.contactMethods
|
||||
? escapeField(JSON.stringify(contact.contactMethods))
|
||||
? escapeField(JSON.stringify(parseJsonField(contact.contactMethods, [])))
|
||||
: "";
|
||||
|
||||
const fields = [
|
||||
@@ -907,7 +912,7 @@ export const contactsToExportJson = (contacts: Contact[]): DatabaseExport => {
|
||||
did: contact.did,
|
||||
name: contact.name || null,
|
||||
contactMethods: contact.contactMethods
|
||||
? JSON.stringify(contact.contactMethods)
|
||||
? JSON.stringify(parseJsonField(contact.contactMethods, []))
|
||||
: null,
|
||||
nextPubKeyHashB64: contact.nextPubKeyHashB64 || null,
|
||||
notes: contact.notes || null,
|
||||
|
||||
@@ -1814,7 +1814,7 @@ export default class AccountViewView extends Vue {
|
||||
if (!this.isRegistered) {
|
||||
// the user was not known to be registered, but now they are (because we got no error) so let's record it
|
||||
try {
|
||||
await databaseUtil.updateAccountSettings(did, {
|
||||
await databaseUtil.updateDidSpecificSettings(did, {
|
||||
isRegistered: true,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
@@ -2018,7 +2018,7 @@ export default class AccountViewView extends Vue {
|
||||
if ((error as any).response.status === 404) {
|
||||
logger.error("The image was already deleted:", error);
|
||||
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
profileImageUrl: undefined,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
|
||||
@@ -138,11 +138,13 @@ import { RouteLocationNormalizedLoaded, Router } from "vue-router";
|
||||
|
||||
import QuickNav from "../components/QuickNav.vue";
|
||||
import TopMessage from "../components/TopMessage.vue";
|
||||
import { AppString, NotificationIface, USE_DEXIE_DB } from "../constants/app";
|
||||
import { db } from "../db/index";
|
||||
import { Contact, ContactMethod } from "../db/tables/contacts";
|
||||
import { NotificationIface, USE_DEXIE_DB } from "../constants/app";
|
||||
import * as databaseUtil from "../db/databaseUtil";
|
||||
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||
import { parseJsonField } from "../db/databaseUtil";
|
||||
import { db } from "../db/index";
|
||||
import { PlatformServiceFactory } from "../services/PlatformServiceFactory";
|
||||
import { Contact, ContactMethod } from "../db/tables/contacts";
|
||||
import { AppString } from "../constants/app";
|
||||
|
||||
/**
|
||||
* Contact Edit View Component
|
||||
@@ -230,9 +232,7 @@ export default class ContactEditView extends Vue {
|
||||
let contact: Contact | undefined = databaseUtil.mapQueryResultToValues(
|
||||
dbContact,
|
||||
)[0] as unknown as Contact;
|
||||
contact.contactMethods = JSON.parse(
|
||||
(contact?.contactMethods as unknown as string) || "[]",
|
||||
);
|
||||
contact.contactMethods = parseJsonField(contact?.contactMethods, []);
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.open();
|
||||
contact = await db.contacts.get(contactDid || "");
|
||||
|
||||
@@ -213,6 +213,7 @@ import {
|
||||
} from "../db/index";
|
||||
import { Contact, ContactMethod } from "../db/tables/contacts";
|
||||
import * as databaseUtil from "../db/databaseUtil";
|
||||
import { parseJsonField } from "../db/databaseUtil";
|
||||
import * as libsUtil from "../libs/util";
|
||||
import {
|
||||
capitalizeAndInsertSpacesBeforeCaps,
|
||||
@@ -289,7 +290,7 @@ function dbRecordToContact(record: ContactDbRecord): Contact {
|
||||
profileImageUrl: safeString(record.profileImageUrl),
|
||||
publicKeyBase64: safeString(record.publicKeyBase64),
|
||||
nextPubKeyHashB64: safeString(record.nextPubKeyHashB64),
|
||||
contactMethods: JSON.parse(record.contactMethods || "[]"),
|
||||
contactMethods: parseJsonField(record.contactMethods, []),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ import UserNameDialog from "../components/UserNameDialog.vue";
|
||||
import { generateEndorserJwtUrlForAccount } from "../libs/endorserServer";
|
||||
import { retrieveAccountMetadata } from "../libs/util";
|
||||
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
||||
import { parseJsonField } from "../db/databaseUtil";
|
||||
|
||||
interface QRScanResult {
|
||||
rawValue?: string;
|
||||
@@ -474,7 +475,9 @@ export default class ContactQRScan extends Vue {
|
||||
|
||||
// Add new contact
|
||||
// @ts-expect-error because we're just using the value to store to the DB
|
||||
contact.contactMethods = JSON.stringify(contact.contactMethods);
|
||||
contact.contactMethods = JSON.stringify(
|
||||
parseJsonField(contact.contactMethods, []),
|
||||
);
|
||||
const { sql, params } = databaseUtil.generateInsertStatement(
|
||||
contact as unknown as Record<string, unknown>,
|
||||
"contacts",
|
||||
|
||||
@@ -171,6 +171,7 @@ import { db, retrieveSettingsForActiveAccount } from "../db/index";
|
||||
import { Contact } from "../db/tables/contacts";
|
||||
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
|
||||
import * as databaseUtil from "../db/databaseUtil";
|
||||
import { parseJsonField } from "../db/databaseUtil";
|
||||
import { getContactJwtFromJwtUrl } from "../libs/crypto";
|
||||
import {
|
||||
generateEndorserJwtUrlForAccount,
|
||||
@@ -778,7 +779,9 @@ export default class ContactQRScanShow extends Vue {
|
||||
|
||||
// Add new contact
|
||||
// @ts-expect-error because we're just using the value to store to the DB
|
||||
contact.contactMethods = JSON.stringify(contact.contactMethods);
|
||||
contact.contactMethods = JSON.stringify(
|
||||
parseJsonField(contact.contactMethods, []),
|
||||
);
|
||||
const { sql, params } = databaseUtil.generateInsertStatement(
|
||||
contact as unknown as Record<string, unknown>,
|
||||
"contacts",
|
||||
|
||||
@@ -103,8 +103,12 @@
|
||||
v-if="!showGiveNumbers"
|
||||
:class="
|
||||
contactsSelected.length > 0
|
||||
? 'text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-3 px-3 py-1.5 rounded-md cursor-pointer'
|
||||
: 'text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-slate-300 ml-3 px-3 py-1.5 rounded-md cursor-not-allowed'
|
||||
? 'text-md bg-gradient-to-b from-blue-400 to-blue-700 ' +
|
||||
'shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ' +
|
||||
'ml-3 px-3 py-1.5 rounded-md cursor-pointer'
|
||||
: 'text-md bg-gradient-to-b from-slate-400 to-slate-700 ' +
|
||||
'shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-slate-300 ' +
|
||||
'ml-3 px-3 py-1.5 rounded-md cursor-not-allowed'
|
||||
"
|
||||
data-testId="copySelectedContactsButtonTop"
|
||||
@click="copySelectedContacts()"
|
||||
@@ -112,9 +116,9 @@
|
||||
Copy
|
||||
</button>
|
||||
<font-awesome
|
||||
@click="showCopySelectionsInfo()"
|
||||
icon="circle-info"
|
||||
class="text-2xl text-blue-500 ml-2"
|
||||
@click="showCopySelectionsInfo()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -142,16 +146,13 @@
|
||||
class="text-md 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-3 py-1.5 rounded-md"
|
||||
@click="toggleShowContactAmounts()"
|
||||
>
|
||||
{{
|
||||
showGiveNumbers ? "Hide Actions" : "See Actions"
|
||||
}}
|
||||
{{ showGiveNumbers ? "Hide Actions" : "See Actions" }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showGiveNumbers" class="my-3">
|
||||
<div class="w-full text-center text-sm italic text-slate-600">
|
||||
Only the most recent hours are included. <br />To see more,
|
||||
click
|
||||
Only the most recent hours are included. <br />To see more, click
|
||||
<span
|
||||
class="text-sm 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 py-0.5 rounded"
|
||||
>
|
||||
@@ -223,9 +224,7 @@
|
||||
/>
|
||||
</router-link>
|
||||
|
||||
<span class="text-xs truncate">{{
|
||||
contact.did
|
||||
}}</span>
|
||||
<span class="text-xs truncate">{{ contact.did }}</span>
|
||||
</div>
|
||||
<div class="text-sm">
|
||||
{{ contact.notes }}
|
||||
@@ -237,7 +236,7 @@
|
||||
v-if="showGiveNumbers && contact.did != activeDid"
|
||||
class="flex gap-1.5 items-end"
|
||||
>
|
||||
<div class='text-center'>
|
||||
<div class="text-center">
|
||||
<div class="text-xs leading-none mb-1">From/To</div>
|
||||
<div class="flex items-center">
|
||||
<button
|
||||
@@ -317,8 +316,12 @@
|
||||
v-if="!showGiveNumbers"
|
||||
:class="
|
||||
contactsSelected.length > 0
|
||||
? 'text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-3 px-3 py-1.5 rounded-md cursor-pointer'
|
||||
: 'text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-slate-300 ml-3 px-3 py-1.5 rounded-md cursor-not-allowed'
|
||||
? 'text-md bg-gradient-to-b from-blue-400 to-blue-700 ' +
|
||||
'shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ' +
|
||||
'ml-3 px-3 py-1.5 rounded-md cursor-pointer'
|
||||
: 'text-md bg-gradient-to-b from-slate-400 to-slate-700 ' +
|
||||
'shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-slate-300 ' +
|
||||
'ml-3 px-3 py-1.5 rounded-md cursor-not-allowed'
|
||||
"
|
||||
@click="copySelectedContacts()"
|
||||
>
|
||||
@@ -541,7 +544,7 @@ export default class ContactsView extends Vue {
|
||||
if (response.status != 201) {
|
||||
throw { error: { response: response } };
|
||||
}
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
isRegistered: true,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
|
||||
@@ -622,7 +622,7 @@ export default class HelpView extends Vue {
|
||||
}
|
||||
|
||||
if (settings.activeDid) {
|
||||
await databaseUtil.updateAccountSettings(settings.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(settings.activeDid, {
|
||||
finishedOnboarding: false,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
|
||||
@@ -630,7 +630,7 @@ export default class HomeView extends Vue {
|
||||
this.activeDid,
|
||||
);
|
||||
if (resp.status === 200) {
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
isRegistered: true,
|
||||
...(await databaseUtil.retrieveSettingsForActiveAccount()),
|
||||
});
|
||||
@@ -785,7 +785,7 @@ export default class HomeView extends Vue {
|
||||
if (USE_DEXIE_DB) {
|
||||
settings = await retrieveSettingsForActiveAccount();
|
||||
}
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
apiServer: this.apiServer,
|
||||
isRegistered: true,
|
||||
...settings,
|
||||
|
||||
@@ -79,7 +79,8 @@ import {
|
||||
newIdentifier,
|
||||
nextDerivationPath,
|
||||
} from "../libs/crypto";
|
||||
import { accountsDBPromise, db } from "../db/index";
|
||||
import * as databaseUtil from "../db/databaseUtil";
|
||||
import { db } from "../db/index";
|
||||
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
|
||||
import {
|
||||
retrieveAllAccountsMetadata,
|
||||
@@ -164,23 +165,15 @@ export default class ImportAccountView extends Vue {
|
||||
|
||||
try {
|
||||
await saveNewIdentity(newId, mne, newDerivPath);
|
||||
if (USE_DEXIE_DB) {
|
||||
const accountsDB = await accountsDBPromise;
|
||||
await accountsDB.accounts.add({
|
||||
dateCreated: new Date().toISOString(),
|
||||
derivationPath: newDerivPath,
|
||||
did: newId.did,
|
||||
identity: JSON.stringify(newId),
|
||||
mnemonic: mne,
|
||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
||||
});
|
||||
}
|
||||
|
||||
// record that as the active DID
|
||||
const platformService = PlatformServiceFactory.getInstance();
|
||||
await platformService.dbExec("UPDATE settings SET activeDid = ?", [
|
||||
newId.did,
|
||||
]);
|
||||
await databaseUtil.updateDidSpecificSettings(newId.did, {
|
||||
isRegistered: false,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
activeDid: newId.did,
|
||||
|
||||
@@ -257,7 +257,7 @@ export default class NewActivityView extends Vue {
|
||||
async expandOffersToUserAndMarkRead() {
|
||||
this.showOffersDetails = !this.showOffersDetails;
|
||||
if (this.showOffersDetails) {
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
lastAckedOfferToUserJwtId: this.newOffersToUser[0].jwtId,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
@@ -285,7 +285,7 @@ export default class NewActivityView extends Vue {
|
||||
);
|
||||
if (index !== -1 && index < this.newOffersToUser.length - 1) {
|
||||
// Set to the next offer's jwtId
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
lastAckedOfferToUserJwtId: this.newOffersToUser[index + 1].jwtId,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
@@ -295,7 +295,7 @@ export default class NewActivityView extends Vue {
|
||||
}
|
||||
} else {
|
||||
// it's the last entry (or not found), so just keep it the same
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
lastAckedOfferToUserJwtId: this.lastAckedOfferToUserJwtId,
|
||||
});
|
||||
if (USE_DEXIE_DB) {
|
||||
@@ -319,7 +319,7 @@ export default class NewActivityView extends Vue {
|
||||
this.showOffersToUserProjectsDetails =
|
||||
!this.showOffersToUserProjectsDetails;
|
||||
if (this.showOffersToUserProjectsDetails) {
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
lastAckedOfferToUserProjectsJwtId:
|
||||
this.newOffersToUserProjects[0].jwtId,
|
||||
});
|
||||
@@ -349,7 +349,7 @@ export default class NewActivityView extends Vue {
|
||||
);
|
||||
if (index !== -1 && index < this.newOffersToUserProjects.length - 1) {
|
||||
// Set to the next offer's jwtId
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
lastAckedOfferToUserProjectsJwtId:
|
||||
this.newOffersToUserProjects[index + 1].jwtId,
|
||||
});
|
||||
@@ -361,7 +361,7 @@ export default class NewActivityView extends Vue {
|
||||
}
|
||||
} else {
|
||||
// it's the last entry (or not found), so just keep it the same
|
||||
await databaseUtil.updateAccountSettings(this.activeDid, {
|
||||
await databaseUtil.updateDidSpecificSettings(this.activeDid, {
|
||||
lastAckedOfferToUserProjectsJwtId:
|
||||
this.lastAckedOfferToUserProjectsJwtId,
|
||||
});
|
||||
|
||||
@@ -215,7 +215,7 @@ export default class SearchAreaView extends Vue {
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.open();
|
||||
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
searchBoxes: [newSearchBox],
|
||||
searchBoxes: searchBoxes as unknown, // Type assertion for Dexie compatibility
|
||||
});
|
||||
}
|
||||
this.searchBox = newSearchBox;
|
||||
@@ -269,7 +269,7 @@ export default class SearchAreaView extends Vue {
|
||||
if (USE_DEXIE_DB) {
|
||||
await db.open();
|
||||
await db.settings.update(MASTER_SETTINGS_KEY, {
|
||||
searchBoxes: [],
|
||||
searchBoxes: "[]" as unknown as string, // Type assertion for Dexie compatibility
|
||||
filterFeedByNearby: false,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user