Browse Source

Fix: iOS copy function

- Update ContactsView, ShareMyContactInfoView, ContactQRScanShowView to use new service
- Replace unreliable web navigator.clipboard with native Capacitor clipboard
- Add comprehensive error handling and logging for clipboard operations
- Sync Capacitor plugins to include clipboard functionality
pull/149/head
Jose Olarte III 4 weeks ago
parent
commit
c3bd22fb83
  1. 37
      src/views/ContactQRScanShowView.vue
  2. 16
      src/views/ContactsView.vue
  3. 4
      src/views/ShareMyContactInfoView.vue

37
src/views/ContactQRScanShowView.vue

@ -140,7 +140,7 @@ import { AxiosError } from "axios";
import { Buffer } from "buffer/"; import { Buffer } from "buffer/";
import QRCodeVue3 from "qr-code-generator-vue3"; import QRCodeVue3 from "qr-code-generator-vue3";
import { Component, Vue } from "vue-facing-decorator"; import { Component, Vue } from "vue-facing-decorator";
import { useClipboard } from "@vueuse/core";
import { QrcodeStream } from "vue-qrcode-reader"; import { QrcodeStream } from "vue-qrcode-reader";
import QuickNav from "../components/QuickNav.vue"; import QuickNav from "../components/QuickNav.vue";
@ -185,7 +185,7 @@ import {
createQRContactAddedMessage, createQRContactAddedMessage,
createQRRegistrationSuccessMessage, createQRRegistrationSuccessMessage,
QR_TIMEOUT_SHORT, QR_TIMEOUT_SHORT,
QR_TIMEOUT_MEDIUM,
QR_TIMEOUT_STANDARD, QR_TIMEOUT_STANDARD,
QR_TIMEOUT_LONG, QR_TIMEOUT_LONG,
} from "@/constants/notifications"; } from "@/constants/notifications";
@ -547,8 +547,8 @@ export default class ContactQRScanShow extends Vue {
name: contact.name, name: contact.name,
}); });
this.notify.toast( this.notify.toast(
NOTIFY_QR_REGISTRATION_SUBMITTED.title,
NOTIFY_QR_REGISTRATION_SUBMITTED.message, NOTIFY_QR_REGISTRATION_SUBMITTED.message,
QR_TIMEOUT_SHORT,
); );
try { try {
@ -621,24 +621,33 @@ export default class ContactQRScanShow extends Vue {
this.profileImageUrl, this.profileImageUrl,
true, true,
); );
useClipboard() try {
.copy(jwtUrl) const { copyToClipboard } = await import("../services/ClipboardService");
.then(() => { await copyToClipboard(jwtUrl);
this.notify.toast(NOTIFY_QR_URL_COPIED.message, QR_TIMEOUT_MEDIUM); this.notify.toast(
}); NOTIFY_QR_URL_COPIED.title,
NOTIFY_QR_URL_COPIED.message,
);
} catch (error) {
this.$logAndConsole(`Error copying URL to clipboard: ${error}`, true);
this.notify.error("Failed to copy URL to clipboard.");
}
} }
toastQRCodeHelp() { toastQRCodeHelp() {
this.notify.info(NOTIFY_QR_CODE_HELP.message, QR_TIMEOUT_LONG); this.notify.info(NOTIFY_QR_CODE_HELP.message, QR_TIMEOUT_LONG);
} }
onCopyDidToClipboard() { async onCopyDidToClipboard() {
//this.onScanDetect([{ rawValue: this.qrValue }]); // good for testing //this.onScanDetect([{ rawValue: this.qrValue }]); // good for testing
useClipboard() try {
.copy(this.activeDid) const { copyToClipboard } = await import("../services/ClipboardService");
.then(() => { await copyToClipboard(this.activeDid);
this.notify.info(NOTIFY_QR_DID_COPIED.message, QR_TIMEOUT_LONG); this.notify.info(NOTIFY_QR_DID_COPIED.message, QR_TIMEOUT_LONG);
}); } catch (error) {
this.$logAndConsole(`Error copying DID to clipboard: ${error}`, true);
this.notify.error("Failed to copy DID to clipboard.");
}
} }
openUserNameDialog() { openUserNameDialog() {

16
src/views/ContactsView.vue

@ -126,10 +126,10 @@ import { JWTPayload } from "did-jwt";
import * as R from "ramda"; import * as R from "ramda";
import { Component, Vue } from "vue-facing-decorator"; import { Component, Vue } from "vue-facing-decorator";
import { RouteLocationNormalizedLoaded, Router } from "vue-router"; import { RouteLocationNormalizedLoaded, Router } from "vue-router";
import { useClipboard } from "@vueuse/core";
import { Capacitor } from "@capacitor/core"; import { Capacitor } from "@capacitor/core";
import QuickNav from "../components/QuickNav.vue"; import QuickNav from "../components/QuickNav.vue";
import { copyToClipboard } from "../services/ClipboardService";
import EntityIcon from "../components/EntityIcon.vue"; import EntityIcon from "../components/EntityIcon.vue";
import GiftedDialog from "../components/GiftedDialog.vue"; import GiftedDialog from "../components/GiftedDialog.vue";
import OfferDialog from "../components/OfferDialog.vue"; import OfferDialog from "../components/OfferDialog.vue";
@ -1172,12 +1172,14 @@ export default class ContactsView extends Vue {
}); });
// Use production URL for sharing to avoid localhost issues in development // Use production URL for sharing to avoid localhost issues in development
const contactsJwtUrl = `${APP_SERVER}/deep-link/contact-import/${contactsJwt}`; const contactsJwtUrl = `${APP_SERVER}/deep-link/contact-import/${contactsJwt}`;
useClipboard() try {
.copy(contactsJwtUrl) await copyToClipboard(contactsJwtUrl);
.then(() => { // Use notification helper
// Use notification helper this.notify.copied(NOTIFY_CONTACT_LINK_COPIED.message);
this.notify.copied(NOTIFY_CONTACT_LINK_COPIED.message); } catch (error) {
}); this.$logAndConsole(`Error copying to clipboard: ${error}`, true);
this.notify.error("Failed to copy to clipboard. Please try again.");
}
} }
private showCopySelectionsInfo() { private showCopySelectionsInfo() {

4
src/views/ShareMyContactInfoView.vue

@ -150,8 +150,8 @@ export default class ShareMyContactInfoView extends Vue {
* Copy the contact message to clipboard * Copy the contact message to clipboard
*/ */
private async copyToClipboard(message: string): Promise<void> { private async copyToClipboard(message: string): Promise<void> {
const { useClipboard } = await import("@vueuse/core"); const { copyToClipboard } = await import("../services/ClipboardService");
await useClipboard().copy(message); await copyToClipboard(message);
} }
/** /**

Loading…
Cancel
Save