forked from trent_larson/crowd-funder-for-time-pwa
add a way to copy a list of contacts with a shorter URL
This commit is contained in:
@@ -197,16 +197,30 @@
|
|||||||
Import Contacts
|
Import Contacts
|
||||||
</button>
|
</button>
|
||||||
</ul>
|
</ul>
|
||||||
<p v-else-if="contactsImporting.length > 0">
|
<div v-else-if="contactsImporting.length > 0">
|
||||||
|
<p>
|
||||||
All those contacts are already in your list with the same information.
|
All those contacts are already in your list with the same information.
|
||||||
|
</p>
|
||||||
|
<div class="mt-3 flex flex-col items-center gap-2">
|
||||||
<button
|
<button
|
||||||
v-if="applyLabelsToExisting"
|
data-testId="copyUnsignedImportLinkButton"
|
||||||
class="bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-sm text-white mt-2 px-2 py-1.5 rounded"
|
class="bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-sm text-white px-2 py-1.5 rounded w-fit"
|
||||||
@click="importContacts"
|
@click="copyUnsignedImportLink"
|
||||||
|
>
|
||||||
|
Copy Unsigned Link for These Contacts
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-sm text-white px-2 py-1.5 rounded w-fit"
|
||||||
|
:class="{
|
||||||
|
'opacity-50 cursor-not-allowed': !canApplyLabelsToExisting,
|
||||||
|
}"
|
||||||
|
@click="handleApplyLabelsToExistingClick"
|
||||||
>
|
>
|
||||||
Apply Labels to Existing Contacts
|
Apply Labels to Existing Contacts
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</div>
|
||||||
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
There are no contacts in that import. If some were sent, try again to
|
There are no contacts in that import. If some were sent, try again to
|
||||||
get the full text and paste it. (Note that iOS cuts off data in text
|
get the full text and paste it. (Note that iOS cuts off data in text
|
||||||
@@ -291,7 +305,8 @@ import { RouteLocationNormalizedLoaded, Router } from "vue-router";
|
|||||||
import QuickNav from "../components/QuickNav.vue";
|
import QuickNav from "../components/QuickNav.vue";
|
||||||
import EntityIcon from "../components/EntityIcon.vue";
|
import EntityIcon from "../components/EntityIcon.vue";
|
||||||
import OfferDialog from "../components/OfferDialog.vue";
|
import OfferDialog from "../components/OfferDialog.vue";
|
||||||
import { AppString, NotificationIface } from "../constants/app";
|
import { APP_SERVER, AppString, NotificationIface } from "../constants/app";
|
||||||
|
import { copyToClipboard } from "../services/ClipboardService";
|
||||||
import {
|
import {
|
||||||
Contact,
|
Contact,
|
||||||
ContactWithLabels,
|
ContactWithLabels,
|
||||||
@@ -647,6 +662,52 @@ export default class ContactImportView extends Vue {
|
|||||||
this.checkingImports = false;
|
this.checkingImports = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private buildUnsignedImportLink(): string {
|
||||||
|
const contactsForLink: Array<Contact> = this.contactsImporting.map((c) => {
|
||||||
|
const contact: Contact = {
|
||||||
|
did: c.did,
|
||||||
|
};
|
||||||
|
if (c.name) {
|
||||||
|
contact.name = c.name;
|
||||||
|
}
|
||||||
|
if (c.nextPubKeyHashB64) {
|
||||||
|
contact.nextPubKeyHashB64 = c.nextPubKeyHashB64;
|
||||||
|
}
|
||||||
|
if (c.profileImageUrl) {
|
||||||
|
contact.profileImageUrl = c.profileImageUrl;
|
||||||
|
}
|
||||||
|
if (c.publicKeyBase64) {
|
||||||
|
contact.publicKeyBase64 = c.publicKeyBase64;
|
||||||
|
}
|
||||||
|
if (typeof c.registered === "boolean") {
|
||||||
|
contact.registered = c.registered;
|
||||||
|
}
|
||||||
|
return contact;
|
||||||
|
});
|
||||||
|
const contactsParam = encodeURIComponent(JSON.stringify(contactsForLink));
|
||||||
|
return `${APP_SERVER}/deep-link/contact-import?contacts=${contactsParam}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async copyUnsignedImportLink() {
|
||||||
|
if (this.contactsImporting.length === 0) {
|
||||||
|
this.notify.error(
|
||||||
|
"No contacts are loaded to build a link.",
|
||||||
|
TIMEOUTS.SHORT,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const link = this.buildUnsignedImportLink();
|
||||||
|
await copyToClipboard(link);
|
||||||
|
this.notify.copied("unsigned contact import link", TIMEOUTS.STANDARD);
|
||||||
|
} catch (error) {
|
||||||
|
const fullError =
|
||||||
|
"Error copying unsigned import link: " + errorStringForLog(error);
|
||||||
|
this.$logAndConsole(fullError, true);
|
||||||
|
this.notify.error("Failed to copy link to clipboard.", TIMEOUTS.STANDARD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new label to the selected labels list
|
* Adds a new label to the selected labels list
|
||||||
*/
|
*/
|
||||||
@@ -803,5 +864,20 @@ export default class ContactImportView extends Vue {
|
|||||||
);
|
);
|
||||||
this.$router.push({ name: "contacts" });
|
this.$router.push({ name: "contacts" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get canApplyLabelsToExisting(): boolean {
|
||||||
|
return this.applyLabelsToExisting && this.selectedLabels.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleApplyLabelsToExistingClick() {
|
||||||
|
if (!this.canApplyLabelsToExisting) {
|
||||||
|
this.notify.warning(
|
||||||
|
`You must choose some labels and check the "Apply" checkbox to use this.`,
|
||||||
|
TIMEOUTS.LONG,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this.importContacts();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user