From 866a1d740c0efe8966e80137749d7aa36fc50628 Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Tue, 17 Sep 2024 18:30:50 -0600 Subject: [PATCH] allow bulk-imported contacts to have visibility set --- CHANGELOG.md | 7 ++- README.md | 2 +- package-lock.json | 4 +- package.json | 2 +- src/views/AccountViewView.vue | 2 +- src/views/ContactImportView.vue | 44 ++++++++++++- src/views/ContactsView.vue | 68 -------------------- src/views/DIDView.vue | 19 +++--- test-playwright/40-add-contact.spec.ts | 18 ++++++ test-playwright/exported-data.json | 86 ++++++++++++++++++++++++++ 10 files changed, 166 insertions(+), 86 deletions(-) create mode 100644 test-playwright/exported-data.json diff --git a/CHANGELOG.md b/CHANGELOG.md index f44c3dad2..d836b0c44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.3.26] +## [0.3.?] +### Fixed +- Allow visibility of bulk-imported contacts + + +## [0.3.26] - 2024.09.16 - 8263ed2b29947b3ccc6f3133bbc9454c222bce28 ### Added - Separate 'isRegistered' flag for each account ### Fixed diff --git a/README.md b/README.md index b80172823..0f4c17def 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ npm run lint ``` # (Let's replace this with a .env.development or .env.staging file.) # The test BVC_MEETUPS_PROJECT_CLAIM_ID does not resolve as a URL because it's only in the test DB and the prod redirect won't redirect there. -TIME_SAFARI_APP_TITLE="TimeSafari_Test" VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_PASSKEYS_ENABLED=yep npm run build +TIME_SAFARI_APP_TITLE="TimeSafari_Test" VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_PASSKEYS_ENABLED=true npm run build ``` * Production diff --git a/package-lock.json b/package-lock.json index 64e32573c..19c53cfb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "TimeSafari", - "version": "0.3.26", + "version": "0.3.27-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "TimeSafari", - "version": "0.3.26", + "version": "0.3.27-beta", "dependencies": { "@dicebear/collection": "^5.4.1", "@dicebear/core": "^5.4.1", diff --git a/package.json b/package.json index 96ec6090f..af0c4dd55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "TimeSafari", - "version": "0.3.26", + "version": "0.3.27-beta", "scripts": { "dev": "vite", "serve": "vite preview", diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue index 6f9325880..09679d1cb 100644 --- a/src/views/AccountViewView.vue +++ b/src/views/AccountViewView.vue @@ -436,7 +436,7 @@ class="block text-center 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 px-1.5 py-2 rounded-md mb-6" @click="checkContactImports()" > - Import Contacts + Import Only Contacts
after comparing diff --git a/src/views/ContactImportView.vue b/src/views/ContactImportView.vue index f494fb8fe..a01a9b8e3 100644 --- a/src/views/ContactImportView.vue +++ b/src/views/ContactImportView.vue @@ -90,12 +90,13 @@ import { Component, Vue } from "vue-facing-decorator"; import { Router } from "vue-router"; import { AppString, NotificationIface } from "@/constants/app"; -import { db } from "@/db/index"; +import { db, retrieveSettingsForActiveAccount } from "@/db/index"; import { Contact } from "@/db/tables/contacts"; import * as libsUtil from "@/libs/util"; import QuickNav from "@/components/QuickNav.vue"; import EntityIcon from "@/components/EntityIcon.vue"; import OfferDialog from "@/components/OfferDialog.vue"; +import { setVisibilityUtil } from "@/libs/endorserServer"; @Component({ components: { EntityIcon, OfferDialog, QuickNav }, @@ -107,6 +108,8 @@ export default class ContactImportView extends Vue { libsUtil = libsUtil; R = R; + activeDid = ""; + apiServer = ""; contactsExisting: Record = {}; // user's contacts already in the system, keyed by DID contactsImporting: Array = []; // contacts from the import contactsSelected: Array = []; // whether each contact in contactsImporting is selected @@ -119,6 +122,10 @@ export default class ContactImportView extends Vue { sameCount = 0; async created() { + const settings = await retrieveSettingsForActiveAccount(); + this.activeDid = settings.activeDid || ""; + this.apiServer = settings.apiServer || ""; + // Retrieve the imported contacts from the query parameter const importedContacts = ((this.$route as Router).query["contacts"] as string) || "[]"; @@ -176,13 +183,46 @@ export default class ContactImportView extends Vue { } } } + if (this.makeVisible) { + const failedVisibileToContacts = []; + for (let i = 0; i < this.contactsImporting.length; i++) { + const contact = this.contactsImporting[i]; + if (contact) { + const visResult = await setVisibilityUtil( + this.activeDid, + this.apiServer, + this.axios, + db, + contact, + true, + ); + if (!visResult.success) { + failedVisibileToContacts.push(contact); + } + } + } + if (failedVisibileToContacts.length) { + this.$notify( + { + group: "alert", + type: "danger", + title: "Visibility Error", + text: `Failed to set visibility for ${failedVisibileToContacts.length} contact${ + failedVisibileToContacts.length == 1 ? "" : "s" + }. You must set them individually: ${failedVisibileToContacts.map((c) => c.name).join(", ")}`, + }, + -1, + ); + } + } + this.importing = false; this.$notify( { group: "alert", type: "success", - title: "Import Success", + title: "Imported", text: `${importedCount} contact${importedCount == 1 ? "" : "s"} imported.` + (updatedCount ? ` ${updatedCount} updated.` : ""), diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue index c4c374394..04d1ca472 100644 --- a/src/views/ContactsView.vue +++ b/src/views/ContactsView.vue @@ -907,74 +907,6 @@ export default class ContactsView extends Vue { } } - // note that this is also in DIDView.vue - private async checkVisibility(contact: Contact) { - const url = - this.apiServer + - "/api/report/canDidExplicitlySeeMe?did=" + - encodeURIComponent(contact.did); - const headers = await getHeaders(this.activeDid); - if (!headers["Authorization"]) { - this.$notify( - { - group: "alert", - type: "danger", - title: "No Identity", - text: "There is no identity to use to check visibility.", - }, - 3000, - ); - return; - } - - try { - const resp = await this.axios.get(url, { headers }); - if (resp.status === 200) { - const visibility = resp.data; - contact.seesMe = visibility; - //console.log("Visi check:", visibility, contact.seesMe, contact.did); - await db.contacts.update(contact.did, { seesMe: visibility }); - - this.$notify( - { - group: "alert", - type: "info", - title: "Visibility Refreshed", - text: - libsUtil.nameForContact(contact, true) + - " can " + - (visibility ? "" : "not ") + - "see your activity.", - }, - 3000, - ); - } else { - console.error("Got bad server response checking visibility:", resp); - const message = resp.data.error?.message || "Got bad server response."; - this.$notify( - { - group: "alert", - type: "danger", - title: "Error Checking Visibility", - text: message, - }, - 5000, - ); - } - } catch (err) { - console.error("Caught error from request to check visibility:", err); - this.$notify( - { - group: "alert", - type: "danger", - title: "Error Checking Visibility", - text: "Check connectivity and try again.", - }, - 3000, - ); - } - } - private confirmShowGiftedDialog(giverDid: string, recipientDid: string) { // if they have unconfirmed amounts, ask to confirm those if ( diff --git a/src/views/DIDView.vue b/src/views/DIDView.vue index e3dbaefea..c7e5720c8 100644 --- a/src/views/DIDView.vue +++ b/src/views/DIDView.vue @@ -88,8 +88,6 @@ > - - - - - -