forked from trent_larson/crowd-funder-for-time-pwa
add functions for visibility to contacts
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
- contacts v1 :
|
- contacts v1 :
|
||||||
- remove 'copy' until it works
|
- remove 'copy' until it works
|
||||||
|
- switch to prod server
|
||||||
- 01 show gives with confirmations
|
- 01 show gives with confirmations
|
||||||
- .5 Add page to show seed.
|
- .5 Add page to show seed.
|
||||||
- 01 Provide a way to import the non-sensitive data.
|
- 01 Provide a way to import the non-sensitive data.
|
||||||
|
|||||||
54
src/main.ts
54
src/main.ts
@@ -10,46 +10,52 @@ import "./assets/styles/tailwind.css";
|
|||||||
|
|
||||||
import { library } from "@fortawesome/fontawesome-svg-core";
|
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||||
import {
|
import {
|
||||||
|
faCalendar,
|
||||||
faChevronLeft,
|
faChevronLeft,
|
||||||
faHouseChimney,
|
faCircleCheck,
|
||||||
faMagnifyingGlass,
|
|
||||||
faFolderOpen,
|
|
||||||
faHand,
|
|
||||||
faCircleUser,
|
faCircleUser,
|
||||||
faCopy,
|
faCopy,
|
||||||
faShareNodes,
|
faEllipsisVertical,
|
||||||
faQrcode,
|
faEye,
|
||||||
faUser,
|
faEyeSlash,
|
||||||
faUsers,
|
faFolderOpen,
|
||||||
|
faHand,
|
||||||
|
faHouseChimney,
|
||||||
|
faMagnifyingGlass,
|
||||||
faPen,
|
faPen,
|
||||||
faPlus,
|
faPlus,
|
||||||
faTrashCan,
|
faQrcode,
|
||||||
faCalendar,
|
faRotate,
|
||||||
faEllipsisVertical,
|
faShareNodes,
|
||||||
faSpinner,
|
faSpinner,
|
||||||
faCircleCheck,
|
faTrashCan,
|
||||||
|
faUser,
|
||||||
|
faUsers,
|
||||||
faXmark,
|
faXmark,
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
|
faCalendar,
|
||||||
faChevronLeft,
|
faChevronLeft,
|
||||||
faHouseChimney,
|
faCircleCheck,
|
||||||
faMagnifyingGlass,
|
|
||||||
faFolderOpen,
|
|
||||||
faHand,
|
|
||||||
faCircleUser,
|
faCircleUser,
|
||||||
faCopy,
|
faCopy,
|
||||||
faShareNodes,
|
faEllipsisVertical,
|
||||||
faQrcode,
|
faEye,
|
||||||
faUser,
|
faEyeSlash,
|
||||||
faUsers,
|
faFolderOpen,
|
||||||
|
faHand,
|
||||||
|
faHouseChimney,
|
||||||
|
faMagnifyingGlass,
|
||||||
faPen,
|
faPen,
|
||||||
faPlus,
|
faPlus,
|
||||||
faTrashCan,
|
faQrcode,
|
||||||
faCalendar,
|
faRotate,
|
||||||
faEllipsisVertical,
|
faShareNodes,
|
||||||
faSpinner,
|
faSpinner,
|
||||||
faCircleCheck,
|
faTrashCan,
|
||||||
|
faUser,
|
||||||
|
faUsers,
|
||||||
faXmark
|
faXmark
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -99,8 +99,26 @@
|
|||||||
<div class="text-sm truncate" v-if="contact.publicKeyBase64">
|
<div class="text-sm truncate" v-if="contact.publicKeyBase64">
|
||||||
Public Key (base 64): {{ contact.publicKeyBase64 }}
|
Public Key (base 64): {{ contact.publicKeyBase64 }}
|
||||||
</div>
|
</div>
|
||||||
<button @click="deleteContact(contact)">
|
|
||||||
<fa icon="trash-can" class="text-slate-900 fa-fw ml-1" />
|
<button
|
||||||
|
v-if="contact.seesMe"
|
||||||
|
class="tooltip"
|
||||||
|
@click="setVisibility(contact, false)"
|
||||||
|
>
|
||||||
|
<fa icon="eye" class="text-slate-900 fa-fw ml-1" />
|
||||||
|
<span class="tooltiptext">Can see you</span>
|
||||||
|
</button>
|
||||||
|
<button v-else class="tooltip" @click="setVisibility(contact, true)">
|
||||||
|
<span class="tooltiptext">Cannot see you</span>
|
||||||
|
<fa icon="eye-slash" class="text-slate-900 fa-fw ml-1" />
|
||||||
|
</button>
|
||||||
|
<button class="tooltip" @click="checkVisibility(contact)">
|
||||||
|
<span class="tooltiptext">Check Visibility</span>
|
||||||
|
<fa icon="rotate" class="text-slate-900 fa-fw ml-1" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button @click="deleteContact(contact)" class="px-9">
|
||||||
|
<fa icon="trash-can" class="text-red-600 fa-fw ml-1" />
|
||||||
</button>
|
</button>
|
||||||
<div v-if="showGiveTotals" class="float-right">
|
<div v-if="showGiveTotals" class="float-right">
|
||||||
<div class="float-right">
|
<div class="float-right">
|
||||||
@@ -310,6 +328,89 @@ export default class ContactsView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setVisibility(contact: Contact, visibility: boolean) {
|
||||||
|
const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER;
|
||||||
|
const url =
|
||||||
|
endorserApiServer +
|
||||||
|
"/api/report/" +
|
||||||
|
(visibility ? "canSeeMe" : "cannotSeeMe");
|
||||||
|
await accountsDB.open();
|
||||||
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
|
const identity = JSON.parse(accounts[0].identity);
|
||||||
|
const token = await accessToken(identity);
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: "Bearer " + token,
|
||||||
|
};
|
||||||
|
const payload = JSON.stringify({ did: contact.did });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp = await this.axios.post(url, payload, { headers });
|
||||||
|
if (resp.status === 200) {
|
||||||
|
contact.seesMe = visibility;
|
||||||
|
db.contacts.update(contact.did, { seesMe: visibility });
|
||||||
|
} else {
|
||||||
|
this.alertTitle = "Error from Server";
|
||||||
|
console.log("Bad response setting visibility: ", resp.data);
|
||||||
|
if (resp.data.error?.message) {
|
||||||
|
this.alertMessage = resp.data.error?.message;
|
||||||
|
} else {
|
||||||
|
this.alertMessage = "Bad server response of " + resp.status;
|
||||||
|
}
|
||||||
|
this.isAlertVisible = true;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.alertTitle = "Error from Server";
|
||||||
|
this.alertMessage = err as string;
|
||||||
|
this.isAlertVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkVisibility(contact: Contact) {
|
||||||
|
const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER;
|
||||||
|
const url =
|
||||||
|
endorserApiServer +
|
||||||
|
"/api/report/canDidExplicitlySeeMe?did=" +
|
||||||
|
encodeURIComponent(contact.did);
|
||||||
|
await accountsDB.open();
|
||||||
|
const accounts = await accountsDB.accounts.toArray();
|
||||||
|
const identity = JSON.parse(accounts[0].identity);
|
||||||
|
const token = await accessToken(identity);
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: "Bearer " + token,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp = await this.axios.get(url, { headers });
|
||||||
|
if (resp.status === 200) {
|
||||||
|
const visibility = resp.data;
|
||||||
|
contact.seesMe = visibility;
|
||||||
|
db.contacts.update(contact.did, { seesMe: visibility });
|
||||||
|
this.alertTitle = "Refreshed";
|
||||||
|
this.alertMessage =
|
||||||
|
this.nameForContact(contact, true) +
|
||||||
|
" can " +
|
||||||
|
(visibility ? "" : "not ") +
|
||||||
|
"see your activity.";
|
||||||
|
this.isAlertVisible = true;
|
||||||
|
} else {
|
||||||
|
this.alertTitle = "Error from Server";
|
||||||
|
console.log("Bad response checking visibility: ", resp.data);
|
||||||
|
if (resp.data.error?.message) {
|
||||||
|
this.alertMessage = resp.data.error?.message;
|
||||||
|
} else {
|
||||||
|
this.alertMessage = "Bad server response of " + resp.status;
|
||||||
|
}
|
||||||
|
this.isAlertVisible = true;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.alertTitle = "Error from Server";
|
||||||
|
this.alertMessage = err as string;
|
||||||
|
this.isAlertVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// from https://stackoverflow.com/a/175787/845494
|
// from https://stackoverflow.com/a/175787/845494
|
||||||
//
|
//
|
||||||
private isNumeric(str: string): boolean {
|
private isNumeric(str: string): boolean {
|
||||||
@@ -318,7 +419,11 @@ export default class ContactsView extends Vue {
|
|||||||
|
|
||||||
private nameForDid(contacts: Array<Contact>, did: string): string {
|
private nameForDid(contacts: Array<Contact>, did: string): string {
|
||||||
const contact = R.find((con) => con.did == did, contacts);
|
const contact = R.find((con) => con.did == did, contacts);
|
||||||
return contact?.name || "this unnamed user";
|
return this.nameForContact(contact);
|
||||||
|
}
|
||||||
|
|
||||||
|
private nameForContact(contact?: Contact, capitalize?: boolean): string {
|
||||||
|
return contact?.name || (capitalize ? "T" : "t") + "this unnamed user";
|
||||||
}
|
}
|
||||||
|
|
||||||
async onClickAddGive(fromDid: string, toDid: string): Promise<void> {
|
async onClickAddGive(fromDid: string, toDid: string): Promise<void> {
|
||||||
@@ -479,3 +584,32 @@ export default class ContactsView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 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 the tooltip text - see examples below! */
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show the tooltip text when you mouse over the tooltip container */
|
||||||
|
.tooltip:hover .tooltiptext {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user