modify the settings to allow account-specific settings, eg. for "isRegistered"

This commit is contained in:
2024-09-15 16:30:46 -06:00
parent fe627ed6b2
commit 8111b0e5cf
44 changed files with 452 additions and 340 deletions

View File

@@ -9,24 +9,11 @@
Your Identity
</h1>
<div class="flex justify-between mb-2 mt-4">
<span />
<span class="whitespace-nowrap">
<router-link
:to="{ name: 'contact-qr' }"
class="text-xs bg-slate-500 text-white px-1.5 py-1 rounded-md"
>
<fa icon="qrcode" class="fa-fw"></fa>
</router-link>
</span>
<span />
</div>
<!-- ID notice -->
<div
v-if="!activeDid"
id="noticeBeforeShare"
class="bg-amber-200 text-amber-900 border-amber-500 border-dashed border text-center rounded-md overflow-hidden px-4 py-3 mb-4"
class="bg-amber-200 text-amber-900 border-amber-500 border-dashed border text-center rounded-md overflow-hidden px-4 py-3 mt-4"
>
<p class="mb-4">
<b>Note:</b> Before you can share with others or take any action, you
@@ -43,10 +30,18 @@
<!-- Identity Details -->
<div
id="sectionIdentityDetails"
class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4"
class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mt-4"
>
<div v-if="givenName">
<h2 class="text-xl font-semibold mb-2">
<span class="whitespace-nowrap">
<router-link
:to="{ name: 'contact-qr' }"
class="bg-slate-500 text-white px-1.5 py-1 rounded-md"
>
<fa icon="qrcode" class="fa-fw text-xl"></fa>
</router-link>
</span>
{{ givenName }}
<router-link :to="{ name: 'new-edit-account' }">
<fa icon="pen" class="text-xs text-blue-500 ml-2 mb-1"></fa>
@@ -160,7 +155,7 @@
<div
v-if="!loadingLimits && !endorserLimits?.nextWeekBeginDateTime"
id="noticeBeforeAnnounce"
class="bg-amber-200 text-amber-900 border-amber-500 border-dashed border text-center rounded-md overflow-hidden px-4 py-3 mb-4"
class="bg-amber-200 text-amber-900 border-amber-500 border-dashed border text-center rounded-md overflow-hidden px-4 py-3 mt-4"
>
<p class="mb-4">
<b>Note:</b> Before you can publicly announce a new project or time
@@ -312,7 +307,7 @@
>
If no download happened yet, click again here to download now.
</a>
<div>
<div class="mt-4">
<p>
After the download, you can save the file in your preferred storage
location.
@@ -731,13 +726,17 @@ import {
IMAGE_TYPE_PROFILE,
NotificationIface,
} from "@/constants/app";
import { db, accountsDB } from "@/db/index";
import {
db,
accountsDB,
retrieveSettingsForActiveAccount,
updateAccountSettings,
} from "@/db/index";
import { Account } from "@/db/tables/accounts";
import { Contact } from "@/db/tables/contacts";
import {
DEFAULT_PASSKEY_EXPIRATION_MINUTES,
MASTER_SETTINGS_KEY,
Settings,
} from "@/db/tables/settings";
import {
clearPasskeyToken,
@@ -865,31 +864,29 @@ export default class AccountViewView extends Vue {
*/
async initializeState() {
await db.open();
const settings: Settings | undefined =
await db.settings.get(MASTER_SETTINGS_KEY);
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = (settings?.activeDid as string) || "";
this.apiServer = (settings?.apiServer as string) || "";
this.apiServerInput = (settings?.apiServer as string) || "";
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.apiServerInput = settings.apiServer || "";
this.givenName =
(settings?.firstName || "") +
(settings?.lastName ? ` ${settings.lastName}` : ""); // pre v 0.1.3
this.isRegistered = !!settings?.isRegistered;
this.imageServer = (settings?.imageServer as string) || "";
this.profileImageUrl = settings?.profileImageUrl as string;
this.showContactGives = !!settings?.showContactGivesInline;
this.imageServer = settings.imageServer || "";
this.profileImageUrl = settings.profileImageUrl;
this.showContactGives = !!settings.showContactGivesInline;
this.hideRegisterPromptOnNewContact =
!!settings?.hideRegisterPromptOnNewContact;
!!settings.hideRegisterPromptOnNewContact;
this.passkeyExpirationMinutes =
(settings?.passkeyExpirationMinutes as number) ??
DEFAULT_PASSKEY_EXPIRATION_MINUTES;
settings.passkeyExpirationMinutes ?? DEFAULT_PASSKEY_EXPIRATION_MINUTES;
this.previousPasskeyExpirationMinutes = this.passkeyExpirationMinutes;
this.showGeneralAdvanced = !!settings?.showGeneralAdvanced;
this.showShortcutBvc = !!settings?.showShortcutBvc;
this.warnIfProdServer = !!settings?.warnIfProdServer;
this.warnIfTestServer = !!settings?.warnIfTestServer;
this.webPushServer = (settings?.webPushServer as string) || "";
this.webPushServerInput = (settings?.webPushServer as string) || "";
this.showGeneralAdvanced = !!settings.showGeneralAdvanced;
this.showShortcutBvc = !!settings.showShortcutBvc;
this.warnIfProdServer = !!settings.warnIfProdServer;
this.warnIfTestServer = !!settings.warnIfTestServer;
this.webPushServer = settings.webPushServer || "";
this.webPushServerInput = settings.webPushServer || "";
}
// call fn, copy text to the clipboard, then redo fn after 2 seconds
@@ -1264,10 +1261,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 db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
isRegistered: true,
});
await updateAccountSettings(did, { isRegistered: true });
this.isRegistered = true;
} catch (err) {
console.error("Got an error updating settings:", err);
@@ -1478,8 +1472,7 @@ export default class AccountViewView extends Vue {
if ((error as any).response.status === 404) {
console.error("The image was already deleted:", error);
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await updateAccountSettings(this.activeDid, {
profileImageUrl: undefined,
});

View File

@@ -33,8 +33,7 @@ import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";
import { NotificationIface } from "@/constants/app";
import { db } from "@/db/index";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { retrieveSettingsForActiveAccount } from "@/db/index";
import * as serverUtil from "@/libs/endorserServer";
import QuickNav from "@/components/QuickNav.vue";
@@ -50,10 +49,9 @@ export default class ClaimAddRawView extends Vue {
claimStr = "";
async mounted() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.claimStr = (this.$route as Router).query["claim"];
try {

View File

@@ -454,9 +454,8 @@ import { useClipboard } from "@vueuse/core";
import GiftedDialog from "@/components/GiftedDialog.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import * as serverUtil from "@/libs/endorserServer";
import * as libsUtil from "@/libs/util";
import QuickNav from "@/components/QuickNav.vue";
@@ -519,12 +518,11 @@ export default class ClaimView extends Vue {
}
async created() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.allContacts = await db.contacts.toArray();
this.isRegistered = settings?.isRegistered || false;
this.isRegistered = settings.isRegistered || false;
await accountsDB.open();
const accounts = accountsDB.accounts;

View File

@@ -65,7 +65,7 @@
<!-- Details -->
<div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mt-4">
<div class="block flex gap-4 overflow-hidden">
<div class="flex gap-4 overflow-hidden">
<div class="overflow-hidden">
<div class="text-sm">
<div>
@@ -100,7 +100,7 @@
<router-link
:to="
'/project/' +
encodeURIComponent(giveDetails?.fulfillsPlanHandleId)
encodeURIComponent(giveDetails?.fulfillsPlanHandleId || '')
"
class="text-blue-500 mt-2 cursor-pointer"
target="_blank"
@@ -121,7 +121,7 @@
<router-link
:to="
'/claim/' +
encodeURIComponent(giveDetails?.fulfillsHandleId)
encodeURIComponent(giveDetails?.fulfillsHandleId || '')
"
class="text-blue-500 mt-2 cursor-pointer"
target="_blank"
@@ -129,7 +129,7 @@
This fulfills
{{
capitalizeAndInsertSpacesBeforeCapsWithAPrefix(
giveDetails.fulfillsType,
giveDetails?.fulfillsType || "",
)
}}
<fa icon="arrow-up-right-from-square" class="fa-fw" />
@@ -405,10 +405,9 @@ import { Router } from "vue-router";
import QuickNav from "@/components/QuickNav.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Account } from "@/db/tables/accounts";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import * as serverUtil from "@/libs/endorserServer";
import { displayAmount, GiveSummaryRecord } from "@/libs/endorserServer";
import * as libsUtil from "@/libs/util";
@@ -464,12 +463,11 @@ export default class ClaimView extends Vue {
async mounted() {
this.isLoading = true;
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.allContacts = await db.contacts.toArray();
this.isRegistered = settings?.isRegistered || false;
this.isRegistered = settings.isRegistered || false;
await accountsDB.open();
const accounts = accountsDB.accounts;

View File

@@ -112,9 +112,8 @@ import { Router } from "vue-router";
import QuickNav from "@/components/QuickNav.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import {
AgreeVerifiableCredential,
createEndorserJwtVcFromClaim,
@@ -144,13 +143,12 @@ export default class ContactAmountssView extends Vue {
async created() {
try {
await db.open();
const contactDid = (this.$route as Router).query["contactDid"] as string;
this.contact = (await db.contacts.get(contactDid)) || null;
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = (settings?.activeDid as string) || "";
this.apiServer = (settings?.apiServer as string) || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || "";
if (this.activeDid && this.contact) {
this.loadGives(this.activeDid, this.contact);

View File

@@ -77,9 +77,8 @@ import GiftedDialog from "@/components/GiftedDialog.vue";
import QuickNav from "@/components/QuickNav.vue";
import EntityIcon from "@/components/EntityIcon.vue";
import { NotificationIface } from "@/constants/app";
import { db } from "@/db/index";
import { db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { GiverReceiverInputInfo } from "@/libs/util";
@Component({
@@ -97,10 +96,9 @@ export default class ContactGiftingView extends Vue {
async created() {
try {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.apiServer = settings?.apiServer || "";
this.activeDid = settings?.activeDid || "";
const settings = await retrieveSettingsForActiveAccount();
this.apiServer = settings.apiServer || "";
this.activeDid = settings.activeDid || "";
// .orderBy("name") wouldn't retrieve any entries with a blank name
// .toCollection.sortBy("name") didn't sort in an order I understood

View File

@@ -16,9 +16,9 @@
Contact Import
</h1>
<span>
Note that you will have to make them visible one-by-one in the list of
Contacts.
<span class="flex justify-center">
<input type="checkbox" v-model="makeVisible" class="mr-2" />
Make my activity visible to these contacts.
</span>
<div v-if="sameCount > 0">
<span v-if="sameCount == 1"
@@ -115,6 +115,7 @@ export default class ContactImportView extends Vue {
Record<string, { new: string; old: string }>
> = {}; // for existing contacts, it shows the difference between imported and existing contacts for each key
importing = false;
makeVisible = true;
sameCount = 0;
async created() {

View File

@@ -101,7 +101,7 @@ import { useClipboard } from "@vueuse/core";
import QuickNav from "@/components/QuickNav.vue";
import UserNameDialog from "@/components/UserNameDialog.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import {
@@ -141,14 +141,13 @@ export default class ContactQRScanShow extends Vue {
ETHR_DID_PREFIX = ETHR_DID_PREFIX;
async created() {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = (settings?.activeDid as string) || "";
this.apiServer = (settings?.apiServer as string) || "";
this.givenName = (settings?.firstName as string) || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.givenName = settings.firstName || "";
this.hideRegisterPromptOnNewContact =
!!settings?.hideRegisterPromptOnNewContact;
this.isRegistered = !!settings?.isRegistered;
!!settings.hideRegisterPromptOnNewContact;
this.isRegistered = !!settings.isRegistered;
await accountsDB.open();
const accounts = await accountsDB.accounts.toArray();
@@ -162,22 +161,17 @@ export default class ContactQRScanShow extends Vue {
iss: this.activeDid,
own: {
name:
(settings?.firstName || "") +
(settings?.lastName ? ` ${settings.lastName}` : ""), // lastName is deprecated, pre v 0.1.3
(settings.firstName || "") +
(settings.lastName ? ` ${settings.lastName}` : ""), // lastName is deprecated, pre v 0.1.3
publicEncKey,
profileImageUrl: settings?.profileImageUrl,
registered: settings?.isRegistered,
profileImageUrl: settings.profileImageUrl,
registered: settings.isRegistered,
},
};
if (account?.mnemonic && account?.derivationPath) {
const newDerivPath = nextDerivationPath(
account.derivationPath as string,
);
const nextPublicHex = deriveAddress(
account.mnemonic as string,
newDerivPath,
)[2];
const newDerivPath = nextDerivationPath(account.derivationPath);
const nextPublicHex = deriveAddress(account.mnemonic, newDerivPath)[2];
const nextPublicEncKey = Buffer.from(nextPublicHex, "hex");
const nextPublicEncKeyHash = sha256(nextPublicEncKey);
const nextPublicEncKeyHashBase64 =
@@ -191,14 +185,14 @@ export default class ContactQRScanShow extends Vue {
viewPrefix + vcJwt;
const name =
(settings?.firstName || "") +
(settings?.lastName ? ` ${settings.lastName}` : ""); // lastName is deprecated, pre v 0.1.3
(settings.firstName || "") +
(settings.lastName ? ` ${settings.lastName}` : ""); // lastName is deprecated, pre v 0.1.3
this.qrValue = await generateEndorserJwtForAccount(
account,
!!settings?.isRegistered,
!!settings.isRegistered,
name,
settings?.profileImageUrl as string,
settings.profileImageUrl,
);
}
}

View File

@@ -292,9 +292,12 @@ import { Router } from "vue-router";
import { useClipboard } from "@vueuse/core";
import { AppString, NotificationIface } from "@/constants/app";
import { db } from "@/db/index";
import {
db,
retrieveSettingsForActiveAccount,
updateDefaultSettings,
} from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { getContactPayloadFromJwtUrl } from "@/libs/crypto";
import {
CONTACT_CSV_HEADER,
@@ -352,14 +355,14 @@ export default class ContactsView extends Vue {
public async created() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || "";
this.isRegistered = !!settings?.isRegistered;
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.isRegistered = !!settings.isRegistered;
this.showGiveNumbers = !!settings?.showContactGivesInline;
this.showGiveNumbers = !!settings.showContactGivesInline;
this.hideRegisterPromptOnNewContact =
!!settings?.hideRegisterPromptOnNewContact;
!!settings.hideRegisterPromptOnNewContact;
if (this.showGiveNumbers) {
this.loadGives();
@@ -715,7 +718,7 @@ export default class ContactsView extends Vue {
text: "Do you want to register them?",
onCancel: async (stopAsking: boolean) => {
if (stopAsking) {
await db.settings.update(MASTER_SETTINGS_KEY, {
await updateDefaultSettings({
hideRegisterPromptOnNewContact: stopAsking,
});
this.hideRegisterPromptOnNewContact = stopAsking;
@@ -723,7 +726,7 @@ export default class ContactsView extends Vue {
},
onNo: async (stopAsking: boolean) => {
if (stopAsking) {
await db.settings.update(MASTER_SETTINGS_KEY, {
await updateDefaultSettings({
hideRegisterPromptOnNewContact: stopAsking,
});
this.hideRegisterPromptOnNewContact = stopAsking;
@@ -1067,8 +1070,7 @@ export default class ContactsView extends Vue {
private async toggleShowContactAmounts() {
const newShowValue = !this.showGiveNumbers;
try {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await updateDefaultSettings({
showContactGivesInline: newShowValue,
});
} catch (err) {

View File

@@ -237,9 +237,9 @@ import QuickNav from "@/components/QuickNav.vue";
import InfiniteScroll from "@/components/InfiniteScroll.vue";
import TopMessage from "@/components/TopMessage.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { BoundingBox } from "@/db/tables/settings";
import {
capitalizeAndInsertSpacesBeforeCaps,
didInfoForContact,
@@ -290,10 +290,9 @@ export default class DIDView extends Vue {
displayAmount = displayAmount;
async mounted() {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = (settings?.activeDid as string) || "";
this.apiServer = (settings?.apiServer as string) || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
const pathParam = window.location.pathname.substring("/did/".length);
let theContact: Contact | undefined;

View File

@@ -146,9 +146,9 @@ import InfiniteScroll from "@/components/InfiniteScroll.vue";
import ProjectIcon from "@/components/ProjectIcon.vue";
import TopMessage from "@/components/TopMessage.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { BoundingBox } from "@/db/tables/settings";
import { didInfo, getHeaders, PlanData } from "@/libs/endorserServer";
@Component({
@@ -179,11 +179,10 @@ export default class DiscoverView extends Vue {
didInfo = didInfo;
async mounted() {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = (settings?.activeDid as string) || "";
this.apiServer = (settings?.apiServer as string) || "";
this.searchBox = settings?.searchBoxes?.[0] || null;
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = (settings.activeDid as string) || "";
this.apiServer = (settings.apiServer as string) || "";
this.searchBox = settings.searchBoxes?.[0] || null;
this.allContacts = await db.contacts.toArray();

View File

@@ -181,8 +181,7 @@ import ImageMethodDialog from "@/components/ImageMethodDialog.vue";
import QuickNav from "@/components/QuickNav.vue";
import TopMessage from "@/components/TopMessage.vue";
import { DEFAULT_IMAGE_API_SERVER, NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import {
createAndSubmitGive,
didInfo,
@@ -319,10 +318,9 @@ export default class GiftedDetails extends Vue {
}
try {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.apiServer = settings?.apiServer || "";
this.activeDid = settings?.activeDid || "";
const settings = await retrieveSettingsForActiveAccount();
this.apiServer = settings.apiServer || "";
this.activeDid = settings.activeDid || "";
let allContacts: Contact[] = [];
let allMyDids: string[] = [];

View File

@@ -84,11 +84,11 @@
id="noticeSomeoneMustRegisterYou"
class="bg-amber-200 rounded-md overflow-hidden text-center px-4 py-3 mb-4"
>
<!-- activeDid && !isRegistered -->
<!-- !isCreatingIdentifier && !isRegistered -->
To share, someone must register you.
<div class="block text-center">
<button
@click="showNameDialog()"
@click="showNameThenIdDialog()"
class="text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mt-2 px-2 py-3 rounded-md"
>
Show them {{ PASSKEYS_ENABLED ? "default" : "your" }} identifier
@@ -107,7 +107,7 @@
</div>
<div v-else id="sectionRecordSomethingGiven">
<!-- activeDid && isRegistered -->
<!-- !isCreatingIdentifier && isRegistered -->
<!-- show the actions for recognizing a give -->
<div class="flex justify-between">
@@ -325,13 +325,17 @@ import {
NotificationIface,
PASSKEYS_ENABLED,
} from "@/constants/app";
import { db, accountsDB } from "@/db/index";
import {
db,
accountsDB,
updateAccountSettings,
retrieveSettingsForActiveAccount,
} from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import {
BoundingBox,
isAnyFeedFilterOn,
MASTER_SETTINGS_KEY,
Settings,
} from "@/db/tables/settings";
import {
contactForDid,
@@ -420,18 +424,17 @@ export default class HomeView extends Vue {
this.allMyDids = [newDid];
}
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.apiServer = settings?.apiServer || "";
this.activeDid = settings?.activeDid || "";
const settings = await retrieveSettingsForActiveAccount();
this.apiServer = settings.apiServer || "";
this.activeDid = settings.activeDid || "";
this.allContacts = await db.contacts.toArray();
this.feedLastViewedClaimId = settings?.lastViewedClaimId;
this.givenName = settings?.firstName || "";
this.isFeedFilteredByVisible = !!settings?.filterFeedByVisible;
this.isFeedFilteredByNearby = !!settings?.filterFeedByNearby;
this.isRegistered = !!settings?.isRegistered;
this.searchBoxes = settings?.searchBoxes || [];
this.showShortcutBvc = !!settings?.showShortcutBvc;
this.feedLastViewedClaimId = settings.lastViewedClaimId;
this.givenName = settings.firstName || "";
this.isFeedFilteredByVisible = !!settings.filterFeedByVisible;
this.isFeedFilteredByNearby = !!settings.filterFeedByNearby;
this.isRegistered = !!settings.isRegistered;
this.searchBoxes = settings.searchBoxes || [];
this.showShortcutBvc = !!settings.showShortcutBvc;
this.isAnyFeedFilterOn = isAnyFeedFilterOn(settings);
@@ -444,9 +447,7 @@ export default class HomeView extends Vue {
this.activeDid,
);
if (resp.status === 200) {
// we just needed to know that they're registered
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await updateAccountSettings(this.activeDid, {
isRegistered: true,
});
this.isRegistered = true;
@@ -495,10 +496,9 @@ export default class HomeView extends Vue {
// only called when a setting was changed
async reloadFeedOnChange() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.isFeedFilteredByVisible = !!settings?.filterFeedByVisible;
this.isFeedFilteredByNearby = !!settings?.filterFeedByNearby;
const settings = await retrieveSettingsForActiveAccount();
this.isFeedFilteredByVisible = !!settings.filterFeedByVisible;
this.isFeedFilteredByNearby = !!settings.filterFeedByNearby;
this.isAnyFeedFilterOn = isAnyFeedFilterOn(settings);
this.feedData = [];
@@ -555,7 +555,7 @@ export default class HomeView extends Vue {
// This has indeed proven problematic. See loadMoreGives
// We should display it immediately and then get the plan later.
const plan = await getPlanFromCache(
record.fulfillsPlanHandleId,
record.fulfillsPlanHandleId || "",
this.axios,
this.apiServer,
this.activeDid,
@@ -782,7 +782,7 @@ export default class HomeView extends Vue {
return known ? "text-slate-500" : "text-slate-100";
}
showNameDialog() {
showNameThenIdDialog() {
if (!this.givenName) {
(this.$refs.userNameDialog as UserNameDialog).open(() => {
this.promptForShareMethod();

View File

@@ -102,8 +102,8 @@ import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";
import { NotificationIface } from "@/constants/app";
import { db, accountsDB } from "@/db/index";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { db, accountsDB, retrieveSettingsForActiveAccount } from "@/db/index";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import QuickNav from "@/components/QuickNav.vue";
@Component({ components: { QuickNav } })
@@ -118,11 +118,10 @@ export default class IdentitySwitcherView extends Vue {
async created() {
try {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || "";
this.apiServerInput = settings?.apiServer || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.apiServerInput = settings.apiServer || "";
await accountsDB.open();
const accounts = await accountsDB.accounts.toArray();

View File

@@ -47,8 +47,8 @@
import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";
import { db } from "@/db/index";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { db, retrieveSettingsForActiveAccount } from "@/db/index";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
@Component({
components: {},
@@ -58,11 +58,10 @@ export default class NewEditAccountView extends Vue {
// 'created' hook runs when the Vue instance is first created
async created() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
const settings = await retrieveSettingsForActiveAccount();
this.givenName =
(settings?.firstName || "") +
(settings?.lastName ? ` ${settings.lastName}` : ""); // deprecated, pre v 0.1.3
(settings.firstName || "") +
(settings.lastName ? ` ${settings.lastName}` : ""); // deprecated, pre v 0.1.3
}
async onClickSaveChanges() {

View File

@@ -185,8 +185,7 @@ import { Router } from "vue-router";
import ImageMethodDialog from "@/components/ImageMethodDialog.vue";
import QuickNav from "@/components/QuickNav.vue";
import { DEFAULT_IMAGE_API_SERVER, NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accountsDB, retrieveSettingsForActiveAccount } from "@/db/index";
import {
createEndorserJwtVcFromClaim,
getHeaders,
@@ -234,10 +233,9 @@ export default class NewEditProjectView extends Vue {
await accountsDB.open();
this.numAccounts = await accountsDB.accounts.count();
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = (settings?.activeDid as string) || "";
this.apiServer = (settings?.apiServer as string) || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.projectId = (this.$route as Router).query["projectId"] || "";

View File

@@ -181,8 +181,7 @@ import { Router } from "vue-router";
import QuickNav from "@/components/QuickNav.vue";
import TopMessage from "@/components/TopMessage.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import {
createAndSubmitOffer,
didInfo,
@@ -296,10 +295,9 @@ export default class OfferDetailsView extends Vue {
this.prevCredToEdit?.claim?.validThrough || this.validThroughDateInput;
try {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.apiServer = settings?.apiServer || "";
this.activeDid = settings?.activeDid || "";
const settings = await retrieveSettingsForActiveAccount();
this.apiServer = settings.apiServer || "";
this.activeDid = settings.activeDid || "";
let allContacts: Contact[] = [];
let allMyDids: string[] = [];

View File

@@ -431,10 +431,9 @@ import QuickNav from "@/components/QuickNav.vue";
import EntityIcon from "@/components/EntityIcon.vue";
import ProjectIcon from "@/components/ProjectIcon.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Account } from "@/db/tables/accounts";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import * as libsUtil from "@/libs/util";
import {
BLANK_GENERIC_SERVER_RECORD,
@@ -494,12 +493,11 @@ export default class ProjectViewView extends Vue {
serverUtil = serverUtil;
async created() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || "";
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.allContacts = await db.contacts.toArray();
this.isRegistered = !!settings?.isRegistered;
this.isRegistered = !!settings.isRegistered;
await accountsDB.open();
const accounts = accountsDB.accounts;

View File

@@ -208,6 +208,15 @@
/>
button. You'll never know until you try.
</div>
<div v-else>
<button
@click="showNameThenIdDialog()"
class="text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mt-2 px-2 py-3 rounded-md"
>
Get someone to onboard you.
</button>
<UserNameDialog ref="userNameDialog" />
</div>
</div>
<ul id="listProjects" class="border-t border-slate-300">
<li
@@ -247,8 +256,7 @@ import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import * as libsUtil from "@/libs/util";
import InfiniteScroll from "@/components/InfiniteScroll.vue";
import QuickNav from "@/components/QuickNav.vue";
@@ -263,9 +271,17 @@ import {
} from "@/libs/endorserServer";
import EntityIcon from "@/components/EntityIcon.vue";
import { Contact } from "@/db/tables/contacts";
import UserNameDialog from "@/components/UserNameDialog.vue";
@Component({
components: { EntityIcon, InfiniteScroll, QuickNav, ProjectIcon, TopMessage },
components: {
EntityIcon,
InfiniteScroll,
QuickNav,
ProjectIcon,
TopMessage,
UserNameDialog,
},
})
export default class ProjectsView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -280,11 +296,12 @@ export default class ProjectsView extends Vue {
allContacts: Array<Contact> = [];
allMyDids: Array<string> = [];
apiServer = "";
projects: PlanData[] = [];
givenName = "";
isLoading = false;
isRegistered = false;
offers: OfferSummaryRecord[] = [];
projectNameFromHandleId: Record<string, string> = {}; // mapping from handleId to description
projects: PlanData[] = [];
showOffers = true;
showProjects = false;
@@ -293,11 +310,11 @@ export default class ProjectsView extends Vue {
async mounted() {
try {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = (settings?.activeDid as string) || "";
this.apiServer = (settings?.apiServer as string) || "";
this.isRegistered = !!settings?.isRegistered;
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
this.isRegistered = !!settings.isRegistered;
this.givenName = settings.firstName || "";
this.allContacts = await db.contacts.toArray();
@@ -497,6 +514,37 @@ export default class ProjectsView extends Vue {
await this.offerDataLoader(url);
}
showNameThenIdDialog() {
if (!this.givenName) {
(this.$refs.userNameDialog as UserNameDialog).open(() => {
this.promptForShareMethod();
});
} else {
this.promptForShareMethod();
}
}
promptForShareMethod() {
this.$notify(
{
group: "modal",
type: "confirm",
title: "Are you nearby with cameras?",
text: "If so, we'll use those with QR codes to share.",
onCancel: async () => {},
onNo: async () => {
(this.$router as Router).push({ name: "share-my-contact-info" });
},
onYes: async () => {
(this.$router as Router).push({ name: "contact-qr" });
},
noText: "we will share another way",
yesText: "we are nearby with cameras",
},
-1,
);
}
public computedOfferTabClassNames() {
return {
"inline-block": true,

View File

@@ -72,7 +72,7 @@ import { Component, Vue } from "vue-facing-decorator";
import QuickNav from "@/components/QuickNav.vue";
import TopMessage from "@/components/TopMessage.vue";
import { NotificationIface } from "@/constants/app";
import { db } from "@/db/index";
import { retrieveSettingsForActiveAccount } from "@/db/index";
import {
BVC_MEETUPS_PROJECT_CLAIM_ID,
bvcMeetingJoinClaim,
@@ -80,7 +80,6 @@ import {
createAndSubmitGive,
} from "@/libs/endorserServer";
import * as libsUtil from "@/libs/util";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
@Component({
components: {
@@ -117,10 +116,9 @@ export default class QuickActionBvcBeginView extends Vue {
}
async record() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
const activeDid = settings?.activeDid || "";
const apiServer = settings?.apiServer || "";
const settings = await retrieveSettingsForActiveAccount();
const activeDid = settings.activeDid || "";
const apiServer = settings.apiServer || "";
try {
const hoursNum = libsUtil.numberOrZero(this.hoursStr);

View File

@@ -144,9 +144,8 @@ import { Router } from "vue-router";
import QuickNav from "@/components/QuickNav.vue";
import TopMessage from "@/components/TopMessage.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import {
BVC_MEETUPS_PROJECT_CLAIM_ID,
claimSpecialDescription,
@@ -182,10 +181,9 @@ export default class QuickActionBvcBeginView extends Vue {
someoneGave = false;
async created() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.apiServer = settings?.apiServer || "";
this.activeDid = settings?.activeDid || "";
const settings = await retrieveSettingsForActiveAccount();
this.apiServer = settings.apiServer || "";
this.activeDid = settings.activeDid || "";
this.allContacts = await db.contacts.toArray();
}

View File

@@ -109,7 +109,7 @@ import { Router } from "vue-router";
import QuickNav from "@/components/QuickNav.vue";
import { NotificationIface } from "@/constants/app";
import { db } from "@/db/index";
import { db, retrieveSettingsForActiveAccount } from "@/db/index";
import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings";
const DEFAULT_LAT_LONG_DIFF = 0.01;
@@ -142,9 +142,8 @@ export default class DiscoverView extends Vue {
searchBox: { name: string; bbox: BoundingBox } | null = null;
async mounted() {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.searchBox = settings?.searchBoxes?.[0] || null;
const settings = await retrieveSettingsForActiveAccount();
this.searchBox = settings.searchBoxes?.[0] || null;
this.resetLatLong();
}

View File

@@ -105,9 +105,8 @@ import { useClipboard } from "@vueuse/core";
import QuickNav from "@/components/QuickNav.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { accountsDB, retrieveSettingsForActiveAccount } from "@/db/index";
import { Account } from "@/db/tables/accounts";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
@Component({ components: { QuickNav } })
export default class SeedBackupView extends Vue {
@@ -122,9 +121,8 @@ export default class SeedBackupView extends Vue {
// 'created' hook runs when the Vue instance is first created
async created() {
try {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
const activeDid = settings?.activeDid || "";
const settings = await retrieveSettingsForActiveAccount();
const activeDid = settings.activeDid || "";
await accountsDB.open();
const accounts = await accountsDB.accounts.toArray();

View File

@@ -49,8 +49,7 @@ import { useClipboard } from "@vueuse/core";
import QuickNav from "@/components/QuickNav.vue";
import TopMessage from "@/components/TopMessage.vue";
import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { generateEndorserJwtForAccount } from "@/libs/endorserServer";
@Component({
@@ -60,12 +59,11 @@ export default class ShareMyContactInfoView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
async onClickShare() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
const activeDid = settings?.activeDid || "";
const givenName = settings?.firstName || "";
const isRegistered = !!settings?.isRegistered;
const profileImageUrl = settings?.profileImageUrl || "";
const settings = await retrieveSettingsForActiveAccount();
const activeDid = settings.activeDid || "";
const givenName = settings.firstName || "";
const isRegistered = !!settings.isRegistered;
const profileImageUrl = settings.profileImageUrl || "";
await accountsDB.open();
const accounts = await accountsDB.accounts.toArray();

View File

@@ -75,7 +75,7 @@ import {
IMAGE_TYPE_PROFILE,
NotificationIface,
} from "@/constants/app";
import { db } from "@/db/index";
import { db, retrieveSettingsForActiveAccount } from "@/db/index";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accessToken } from "@/libs/crypto";
import { base64ToBlob, SHARED_PHOTO_BASE64_KEY } from "@/libs/util";
@@ -94,9 +94,8 @@ export default class SharedPhotoView extends Vue {
// 'created' hook runs when the Vue instance is first created
async mounted() {
try {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = settings?.activeDid as string;
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid;
const temp = await db.temp.get(SHARED_PHOTO_BASE64_KEY);
const imageB64 = temp?.blobB64 as string;

View File

@@ -92,8 +92,7 @@ import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";
import { AppString, PASSKEYS_ENABLED } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { accountsDB, retrieveSettingsForActiveAccount } from "@/db/index";
import { registerSaveAndActivatePasskey } from "@/libs/util";
@Component({
@@ -106,9 +105,8 @@ export default class StartView extends Vue {
numAccounts = 0;
async mounted() {
await db.open();
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
this.givenName = settings?.firstName || "";
const settings = await retrieveSettingsForActiveAccount();
this.givenName = settings.firstName || "";
await accountsDB.open();
this.numAccounts = await accountsDB.accounts.count();

View File

@@ -247,8 +247,7 @@ import { Router } from "vue-router";
import QuickNav from "@/components/QuickNav.vue";
import { AppString, NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import * as vcLib from "@/libs/crypto/vc";
import {
PeerSetup,
@@ -291,10 +290,9 @@ export default class Help extends Vue {
userName?: string;
async mounted() {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
this.activeDid = (settings?.activeDid as string) || "";
this.userName = settings?.firstName as string;
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.userName = settings.firstName;
await accountsDB.open();
const account: { identity?: string } | undefined = await accountsDB.accounts