forked from jsnbuchanan/crowd-funder-for-time-pwa
move contact actions into the details page (prepping for checkboxes)
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
class="px-4 rounded-r bg-slate-200 border border-l-0 border-slate-400"
|
||||
@click="onClickNewContact()"
|
||||
>
|
||||
<fa icon="plus" class="fa-fw"></fa>
|
||||
<fa icon="plus" class="fa-fw" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -82,10 +82,10 @@
|
||||
<ul
|
||||
id="listContacts"
|
||||
v-if="contacts.length > 0"
|
||||
class="border-t border-slate-300"
|
||||
class="border-t border-slate-300 mt-1"
|
||||
>
|
||||
<li
|
||||
class="border-b border-slate-300 pt-2.5 pb-4"
|
||||
class="border-b border-slate-300 pt-1 pb-1"
|
||||
v-for="contact in contacts"
|
||||
:key="contact.did"
|
||||
>
|
||||
@@ -98,131 +98,16 @@
|
||||
@click="showLargeIdenticon = contact"
|
||||
/>
|
||||
{{ contact.name || AppString.NO_CONTACT_NAME }}
|
||||
<button
|
||||
@click="
|
||||
contactEdit = contact;
|
||||
contactNewName = contact.name || '';
|
||||
"
|
||||
title="Edit"
|
||||
>
|
||||
<fa icon="pen" class="text-sm text-blue-500 ml-2 mb-1"></fa>
|
||||
</button>
|
||||
<router-link
|
||||
:to="{
|
||||
path: '/did/' + encodeURIComponent(contact.did),
|
||||
}"
|
||||
title="See more about this DID"
|
||||
title="See more about this person"
|
||||
>
|
||||
<fa icon="circle-info" class="text-blue-500 ml-4" />
|
||||
</router-link>
|
||||
</h2>
|
||||
<div class="text-sm truncate">
|
||||
Identifier:
|
||||
<button
|
||||
@click="
|
||||
libsUtil.doCopyTwoSecRedo(
|
||||
contact.did,
|
||||
() => (showDidCopy = !showDidCopy),
|
||||
)
|
||||
"
|
||||
>
|
||||
<fa icon="copy" class="text-slate-400 fa-fw"></fa>
|
||||
</button>
|
||||
<span v-show="showDidCopy" class="text-green-500">Copied DID</span>
|
||||
{{ contact.did }}
|
||||
</div>
|
||||
<div class="text-sm truncate" v-if="contact.publicKeyBase64">
|
||||
Public Key (base 64):
|
||||
<button
|
||||
@click="
|
||||
libsUtil.doCopyTwoSecRedo(
|
||||
contact.publicKeyBase64,
|
||||
() => (showPubKeyCopy = !showPubKeyCopy),
|
||||
)
|
||||
"
|
||||
>
|
||||
<fa icon="copy" class="text-slate-400 fa-fw"></fa>
|
||||
</button>
|
||||
<span v-show="showPubKeyCopy" class="text-green-500"
|
||||
>Copied Key</span
|
||||
>
|
||||
{{ contact.publicKeyBase64 }}
|
||||
</div>
|
||||
<div class="text-sm truncate" v-if="contact.nextPubKeyHashB64">
|
||||
Next Public Key Hash (base 64):
|
||||
<button
|
||||
@click="
|
||||
libsUtil.doCopyTwoSecRedo(
|
||||
contact.nextPubKeyHashB64,
|
||||
() => (showPubKeyHashCopy = !showPubKeyHashCopy),
|
||||
)
|
||||
"
|
||||
>
|
||||
<fa icon="copy" class="text-slate-400 fa-fw"></fa>
|
||||
</button>
|
||||
<span v-show="showPubKeyHashCopy" class="text-green-500"
|
||||
>Copied Hash</span
|
||||
>
|
||||
{{ contact.nextPubKeyHashB64 }}
|
||||
</div>
|
||||
|
||||
<div id="ContactActions" class="flex gap-1.5 mt-2">
|
||||
<div v-if="activeDid">
|
||||
<button
|
||||
v-if="contact.seesMe && contact.did !== activeDid"
|
||||
class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
|
||||
@click="confirmSetVisibility(contact, false)"
|
||||
title="They can see you"
|
||||
>
|
||||
<fa icon="eye" class="fa-fw" />
|
||||
</button>
|
||||
<button
|
||||
v-else-if="!contact.seesMe && contact.did !== activeDid"
|
||||
class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
|
||||
@click="confirmSetVisibility(contact, true)"
|
||||
title="They cannot see you"
|
||||
>
|
||||
<fa icon="eye-slash" class="fa-fw" />
|
||||
</button>
|
||||
<!-- otherwise it's this user so hide it -->
|
||||
<fa v-else icon="eye" class="text-white mx-2.5" />
|
||||
|
||||
<button
|
||||
class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
|
||||
@click="checkVisibility(contact)"
|
||||
title="Check Visibility"
|
||||
v-if="contact.did !== activeDid"
|
||||
>
|
||||
<fa icon="rotate" class="fa-fw" />
|
||||
</button>
|
||||
<!-- otherwise it's this user so hide it -->
|
||||
<fa v-else icon="rotate" class="text-white mx-2.5" />
|
||||
|
||||
<button
|
||||
@click="confirmRegister(contact)"
|
||||
class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-6 px-2 py-1.5 rounded-md"
|
||||
v-if="contact.did !== activeDid"
|
||||
title="Registration"
|
||||
>
|
||||
<fa
|
||||
v-if="contact.registered"
|
||||
icon="person-circle-check"
|
||||
class="fa-fw"
|
||||
/>
|
||||
<fa v-else icon="person-circle-question" class="fa-fw" />
|
||||
</button>
|
||||
<!-- otherwise it's this user so hide it -->
|
||||
<fa v-else icon="rotate" class="text-white ml-6 px-2.5" />
|
||||
</div>
|
||||
|
||||
<button
|
||||
@click="confirmDeleteContact(contact)"
|
||||
class="text-sm uppercase bg-gradient-to-b from-rose-500 to-rose-800 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-6 px-2 py-1.5 rounded-md"
|
||||
title="Delete"
|
||||
>
|
||||
<fa icon="trash-can" class="fa-fw" />
|
||||
</button>
|
||||
|
||||
<div
|
||||
v-if="showGiveNumbers && contact.did != activeDid"
|
||||
class="ml-auto flex gap-1.5"
|
||||
@@ -308,33 +193,6 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="contactEdit !== null" class="dialog-overlay">
|
||||
<div class="dialog">
|
||||
<h1 class="text-xl font-bold text-center mb-4">Edit Name</h1>
|
||||
<input
|
||||
type="text"
|
||||
class="block w-full rounded border border-slate-400 mb-2 px-3 py-2"
|
||||
placeholder="Name"
|
||||
v-model="contactNewName"
|
||||
/>
|
||||
<div class="flex justify-between">
|
||||
<button
|
||||
class="text-sm bg-blue-600 text-white px-2 py-1.5 rounded -ml-1.5 border-l border-blue-400"
|
||||
@click="onClickSaveName(contactEdit, contactNewName)"
|
||||
>
|
||||
<fa icon="save" />
|
||||
</button>
|
||||
<span class="inline-block w-2" />
|
||||
<button
|
||||
class="text-sm bg-blue-600 text-white px-2 py-1.5 rounded -ml-1.5 border-l border-blue-400"
|
||||
@click="onClickCancelName()"
|
||||
>
|
||||
<fa icon="ban" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -782,55 +640,29 @@ export default class ContactsView extends Vue {
|
||||
});
|
||||
}
|
||||
|
||||
// prompt with confirmation if they want to delete a contact
|
||||
confirmDeleteContact(contact: Contact) {
|
||||
// note that this is also in DIDView.vue
|
||||
async confirmSetVisibility(contact: Contact, visibility: boolean) {
|
||||
const visibilityPrompt = visibility
|
||||
? "Are you sure you want to make your activity visible to them?"
|
||||
: "Are you sure you want to hide all your activity from them?";
|
||||
this.$notify(
|
||||
{
|
||||
group: "modal",
|
||||
type: "confirm",
|
||||
title: "Delete",
|
||||
text:
|
||||
"Are you sure you want to remove " +
|
||||
this.nameForDid(this.contacts, contact.did) +
|
||||
" with DID " +
|
||||
contact.did +
|
||||
" from your contact list?",
|
||||
title: "Set Visibility",
|
||||
text: visibilityPrompt,
|
||||
onYes: async () => {
|
||||
await this.deleteContact(contact);
|
||||
},
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
|
||||
async deleteContact(contact: Contact) {
|
||||
await db.open();
|
||||
await db.contacts.delete(contact.did);
|
||||
this.contacts = R.without([contact], this.contacts);
|
||||
}
|
||||
|
||||
// confirm to register a new contact
|
||||
async confirmRegister(contact: Contact) {
|
||||
this.$notify(
|
||||
{
|
||||
group: "modal",
|
||||
type: "confirm",
|
||||
title: "Register",
|
||||
text:
|
||||
"Are you sure you want to register " +
|
||||
this.nameForDid(this.contacts, contact.did) +
|
||||
(contact.registered
|
||||
? " -- especially since they are already marked as registered"
|
||||
: "") +
|
||||
"?",
|
||||
onYes: async () => {
|
||||
await this.register(contact);
|
||||
const success = await this.setVisibility(contact, visibility, true);
|
||||
if (success) {
|
||||
contact.seesMe = visibility; // didn't work inside setVisibility
|
||||
}
|
||||
},
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
|
||||
// note that this is also in DIDView.vue
|
||||
async register(contact: Contact) {
|
||||
this.$notify({ group: "alert", type: "toast", title: "Sent..." }, 1000);
|
||||
|
||||
@@ -896,27 +728,7 @@ export default class ContactsView extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
async confirmSetVisibility(contact: Contact, visibility: boolean) {
|
||||
const visibilityPrompt = visibility
|
||||
? "Are you sure you want to make your activity visible to them?"
|
||||
: "Are you sure you want to hide all your activity from them?";
|
||||
this.$notify(
|
||||
{
|
||||
group: "modal",
|
||||
type: "confirm",
|
||||
title: "Set Visibility",
|
||||
text: visibilityPrompt,
|
||||
onYes: async () => {
|
||||
const success = await this.setVisibility(contact, visibility, true);
|
||||
if (success) {
|
||||
contact.seesMe = visibility; // didn't work inside setVisibility
|
||||
}
|
||||
},
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
|
||||
// note that this is also in DIDView.vue
|
||||
async setVisibility(
|
||||
contact: Contact,
|
||||
visibility: boolean,
|
||||
@@ -966,6 +778,7 @@ export default class ContactsView extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
// note that this is also in DIDView.vue
|
||||
async checkVisibility(contact: Contact) {
|
||||
const url =
|
||||
this.apiServer +
|
||||
@@ -999,7 +812,7 @@ export default class ContactsView extends Vue {
|
||||
type: "info",
|
||||
title: "Visibility Refreshed",
|
||||
text:
|
||||
this.nameForContact(contact, true) +
|
||||
libsUtil.nameForContact(contact, true) +
|
||||
" can " +
|
||||
(visibility ? "" : "not ") +
|
||||
"see your activity.",
|
||||
@@ -1033,21 +846,6 @@ export default class ContactsView extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
private nameForDid(contacts: Array<Contact>, did: string): string {
|
||||
if (did === this.activeDid) {
|
||||
return "you";
|
||||
}
|
||||
const contact = R.find((con) => con.did == did, contacts);
|
||||
return this.nameForContact(contact);
|
||||
}
|
||||
|
||||
private nameForContact(contact?: Contact, capitalize?: boolean): string {
|
||||
return (
|
||||
(contact?.name as string) ||
|
||||
(capitalize ? "This" : "this") + " unnamed user"
|
||||
);
|
||||
}
|
||||
|
||||
confirmShowGiftedDialog(giverDid: string, recipientDid: string) {
|
||||
// if they have unconfirmed amounts, ask to confirm those
|
||||
if (
|
||||
@@ -1093,13 +891,13 @@ export default class ContactsView extends Vue {
|
||||
if (giverDid) {
|
||||
giver = {
|
||||
did: giverDid,
|
||||
name: this.nameForDid(this.contacts, giverDid),
|
||||
name: libsUtil.nameForDid(this.activeDid, this.contacts, giverDid),
|
||||
};
|
||||
}
|
||||
if (recipientDid) {
|
||||
receiver = {
|
||||
did: recipientDid,
|
||||
name: this.nameForDid(this.contacts, recipientDid),
|
||||
name: libsUtil.nameForDid(this.activeDid, this.contacts, recipientDid),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1131,25 +929,13 @@ export default class ContactsView extends Vue {
|
||||
);
|
||||
}
|
||||
|
||||
openOfferDialog(recipientDid: string, recipientName: string) {
|
||||
openOfferDialog(recipientDid: string, recipientName?: string) {
|
||||
(this.$refs.customOfferDialog as OfferDialog).open(
|
||||
recipientDid,
|
||||
recipientName,
|
||||
);
|
||||
}
|
||||
|
||||
private async onClickCancelName() {
|
||||
this.contactEdit = null;
|
||||
this.contactNewName = "";
|
||||
}
|
||||
|
||||
private async onClickSaveName(contact: Contact, newName: string) {
|
||||
contact.name = newName;
|
||||
return db.contacts
|
||||
.update(contact.did, { name: newName })
|
||||
.then(() => (this.contactEdit = null));
|
||||
}
|
||||
|
||||
public async toggleShowContactAmounts() {
|
||||
const newShowValue = !this.showGiveNumbers;
|
||||
try {
|
||||
@@ -1211,74 +997,3 @@ export default class ContactsView extends Vue {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
.dialog {
|
||||
background-color: white;
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
/*
|
||||
Tooltip, generated on "title" attributes on "fa" icons
|
||||
Kudos to https://www.w3schools.com/css/css_tooltip.asp
|
||||
*/
|
||||
/* Tooltip container */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
|
||||
}
|
||||
/* Tooltip text */
|
||||
.tooltip .tooltiptext {
|
||||
visibility: hidden;
|
||||
width: 200px;
|
||||
background-color: black;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 5px 0;
|
||||
border-radius: 6px;
|
||||
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
/* How do we share with the above so code isn't duplicated? */
|
||||
.tooltip .tooltiptext-left {
|
||||
visibility: hidden;
|
||||
width: 200px;
|
||||
background-color: black;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 5px 0;
|
||||
border-radius: 6px;
|
||||
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
bottom: 0%;
|
||||
right: 105%;
|
||||
margin-left: -60px;
|
||||
}
|
||||
|
||||
/* Show the tooltip text when you mouse over the tooltip container */
|
||||
.tooltip:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
.tooltip:hover .tooltiptext-left {
|
||||
visibility: visible;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user