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 @@
>
-
-
-
-
-
-