feat: add contacts DB & page
This commit is contained in:
@@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
- replace user-affecting console.logs with error messages (eg. catches)
|
- replace user-affecting console.logs with error messages (eg. catches)
|
||||||
|
|
||||||
- contacts
|
- contacts v1:
|
||||||
|
- parse input correctly (with CSV lib and not commas)
|
||||||
|
|
||||||
- commit screen
|
- commit screen
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import BaseDexie from "dexie";
|
import BaseDexie, { Table } from "dexie";
|
||||||
import { encrypted, Encryption } from "@pvermeer/dexie-encrypted-addon";
|
import { encrypted, Encryption } from "@pvermeer/dexie-encrypted-addon";
|
||||||
import { accountsSchema, AccountsTable } from "./tables/accounts";
|
import { accountsSchema, Account } from "./tables/accounts";
|
||||||
|
import { contactsSchema, Contact } from "./tables/contacts";
|
||||||
|
|
||||||
|
type AllTables = {
|
||||||
|
accounts: Table<Account>;
|
||||||
|
contacts: Table<Contact>;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In order to make the next line be acceptable, the program needs to have its linter suppress a rule:
|
* In order to make the next line be acceptable, the program needs to have its linter suppress a rule:
|
||||||
@@ -10,10 +16,9 @@ import { accountsSchema, AccountsTable } from "./tables/accounts";
|
|||||||
*
|
*
|
||||||
* https://9to5answer.com/how-to-bypass-warning-unexpected-any-specify-a-different-type-typescript-eslint-no-explicit-any
|
* https://9to5answer.com/how-to-bypass-warning-unexpected-any-specify-a-different-type-typescript-eslint-no-explicit-any
|
||||||
*/
|
*/
|
||||||
type DexieTables = AccountsTable;
|
type DexieTables = AllTables;
|
||||||
export type Dexie<T extends unknown = DexieTables> = BaseDexie & T;
|
export type Dexie<T extends unknown = DexieTables> = BaseDexie & T;
|
||||||
export const db = new BaseDexie("kickStarter") as Dexie;
|
export const db = new BaseDexie("kickStarter") as Dexie;
|
||||||
const schema = Object.assign({}, accountsSchema);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Needed to enable a special webpack setting to allow *await* below:
|
* Needed to enable a special webpack setting to allow *await* below:
|
||||||
@@ -27,6 +32,7 @@ const secret =
|
|||||||
if (localStorage.getItem("secret") == null) {
|
if (localStorage.getItem("secret") == null) {
|
||||||
localStorage.setItem("secret", secret);
|
localStorage.setItem("secret", secret);
|
||||||
}
|
}
|
||||||
console.log(secret);
|
console.log("DB encryption secretKey:", secret);
|
||||||
encrypted(db, { secretKey: secret });
|
encrypted(db, { secretKey: secret });
|
||||||
db.version(1).stores(schema);
|
db.version(1).stores(accountsSchema);
|
||||||
|
db.version(2).stores(contactsSchema);
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Table } from "dexie";
|
|
||||||
|
|
||||||
export type Account = {
|
export type Account = {
|
||||||
id?: number;
|
id?: number;
|
||||||
publicKey: string;
|
publicKey: string;
|
||||||
@@ -8,10 +6,6 @@ export type Account = {
|
|||||||
dateCreated: number;
|
dateCreated: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AccountsTable = {
|
|
||||||
accounts: Table<Account>;
|
|
||||||
};
|
|
||||||
|
|
||||||
// mark encrypted field by starting with a $ character
|
// mark encrypted field by starting with a $ character
|
||||||
export const accountsSchema = {
|
export const accountsSchema = {
|
||||||
accounts: "++id, publicKey, $mnemonic, $identity, dateCreated",
|
accounts: "++id, publicKey, $mnemonic, $identity, dateCreated",
|
||||||
|
|||||||
12
src/db/tables/contacts.ts
Normal file
12
src/db/tables/contacts.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
export interface Contact {
|
||||||
|
did: string;
|
||||||
|
name?: string;
|
||||||
|
publicKeyBase64?: string;
|
||||||
|
seesMe?: boolean;
|
||||||
|
registered?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark encrypted field by starting with a $ character
|
||||||
|
export const contactsSchema = {
|
||||||
|
contacts: "++did, name, publicKeyBase64, seesMe, registered",
|
||||||
|
};
|
||||||
@@ -43,6 +43,12 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
/* webpackChunkName: "confirm-contact" */ "../views/ConfirmContactView.vue"
|
/* webpackChunkName: "confirm-contact" */ "../views/ConfirmContactView.vue"
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/contacts",
|
||||||
|
name: "contacts",
|
||||||
|
component: () =>
|
||||||
|
import(/* webpackChunkName: "contacts" */ "../views/ContactsView.vue"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/scan-contact",
|
path: "/scan-contact",
|
||||||
name: "scan-contact",
|
name: "scan-contact",
|
||||||
|
|||||||
121
src/views/ContactsView.vue
Normal file
121
src/views/ContactsView.vue
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<!-- QUICK NAV -->
|
||||||
|
<nav id="QuickNav" class="fixed bottom-0 left-0 right-0 bg-slate-200">
|
||||||
|
<ul class="flex text-2xl p-2 gap-2">
|
||||||
|
<!-- Home Feed -->
|
||||||
|
<li class="basis-1/5 rounded-md text-slate-500">
|
||||||
|
<router-link :to="{ name: 'home' }" class="block text-center py-3 px-1"
|
||||||
|
><fa icon="house-chimney" class="fa-fw"></fa
|
||||||
|
></router-link>
|
||||||
|
</li>
|
||||||
|
<!-- Search -->
|
||||||
|
<li class="basis-1/5 rounded-md bg-slate-400 text-white">
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'discover' }"
|
||||||
|
class="block text-center py-3 px-1"
|
||||||
|
><fa icon="magnifying-glass" class="fa-fw"></fa
|
||||||
|
></router-link>
|
||||||
|
</li>
|
||||||
|
<!-- Contacts -->
|
||||||
|
<li class="basis-1/5 rounded-md text-slate-500">
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'contacts' }"
|
||||||
|
class="block text-center py-3 px-1"
|
||||||
|
><fa icon="folder-open" class="fa-fw"></fa
|
||||||
|
></router-link>
|
||||||
|
</li>
|
||||||
|
<!-- Commitments -->
|
||||||
|
<li class="basis-1/5 rounded-md text-slate-500">
|
||||||
|
<router-link :to="{ name: '' }" class="block text-center py-3 px-1"
|
||||||
|
><fa icon="hand" class="fa-fw"></fa
|
||||||
|
></router-link>
|
||||||
|
</li>
|
||||||
|
<!-- Profile -->
|
||||||
|
<li class="basis-1/5 rounded-md text-slate-500">
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'account' }"
|
||||||
|
class="block text-center py-3 px-1"
|
||||||
|
><fa icon="circle-user" class="fa-fw"></fa
|
||||||
|
></router-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<section id="Content" class="p-6 pb-24">
|
||||||
|
<!-- Heading -->
|
||||||
|
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
|
||||||
|
My Contacts
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<!-- New Contact -->
|
||||||
|
<div class="mb-4 flex">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="DID, Name, Public Key"
|
||||||
|
class="block w-full rounded-l border border-r-0 border-slate-400 px-3 py-2"
|
||||||
|
v-model="contactInput"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
class="px-4 rounded-r bg-slate-200 border border-l-0 border-slate-400"
|
||||||
|
@click="onClickNewContact()"
|
||||||
|
>
|
||||||
|
<fa icon="plus" class="fa-fw"></fa>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Results List -->
|
||||||
|
<ul class="">
|
||||||
|
<li
|
||||||
|
class="border-b border-slate-300"
|
||||||
|
v-for="contact in contacts"
|
||||||
|
:key="contact.did"
|
||||||
|
>
|
||||||
|
<div class="grow overflow-hidden">
|
||||||
|
<h2 class="text-base font-semibold">
|
||||||
|
{{ contact.name || "(no name)" }}
|
||||||
|
</h2>
|
||||||
|
<div class="text-sm truncate">{{ contact.did }}</div>
|
||||||
|
<div class="text-sm truncate">{{ contact.publicKeyBase64 }}</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Options, Vue } from "vue-class-component";
|
||||||
|
import { db } from "../db";
|
||||||
|
import { Contact } from "../db/tables/contacts.ts";
|
||||||
|
|
||||||
|
@Options({
|
||||||
|
components: {},
|
||||||
|
})
|
||||||
|
export default class ContactsView extends Vue {
|
||||||
|
contactInput = "";
|
||||||
|
|
||||||
|
contacts: Contact[] = [];
|
||||||
|
|
||||||
|
// 'created' hook runs when the Vue instance is first created
|
||||||
|
async created() {
|
||||||
|
await db.open();
|
||||||
|
this.contacts = await db.contacts.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
async onClickNewContact(): void {
|
||||||
|
let did = this.contactInput;
|
||||||
|
let name, publicKeyBase64;
|
||||||
|
const commaPos1 = this.contactInput.indexOf(",");
|
||||||
|
if (commaPos1 > -1) {
|
||||||
|
did = this.contactInput.substring(0, commaPos1).trim();
|
||||||
|
name = this.contactInput.substring(commaPos1 + 1).trim();
|
||||||
|
const commaPos2 = this.contactInput.indexOf(",", commaPos1 + 1);
|
||||||
|
if (commaPos2 > -1) {
|
||||||
|
name = this.contactInput.substring(commaPos1 + 1, commaPos2).trim();
|
||||||
|
publicKeyBase64 = this.contactInput.substring(commaPos2 + 1).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const newContact = { did, name, publicKeyBase64 };
|
||||||
|
await db.contacts.add(newContact);
|
||||||
|
this.contacts = this.contacts.concat([newContact]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -107,6 +107,7 @@ export default class NewEditProjectView extends Vue {
|
|||||||
isHiddenSave = false;
|
isHiddenSave = false;
|
||||||
isHiddenSpinner = true;
|
isHiddenSpinner = true;
|
||||||
|
|
||||||
|
// 'created' hook runs when the Vue instance is first created
|
||||||
async created() {
|
async created() {
|
||||||
if (this.projectId === "") {
|
if (this.projectId === "") {
|
||||||
console.log("This is a new project");
|
console.log("This is a new project");
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 'created' hook runs when the Vue instance is first created
|
||||||
async created() {
|
async created() {
|
||||||
await db.open();
|
await db.open();
|
||||||
const num_accounts = await db.accounts.count();
|
const num_accounts = await db.accounts.count();
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ export default class ProjectsView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 'created' hook runs when the Vue instance is first created
|
||||||
async created() {
|
async created() {
|
||||||
await db.open();
|
await db.open();
|
||||||
const num_accounts = await db.accounts.count();
|
const num_accounts = await db.accounts.count();
|
||||||
|
|||||||
Reference in New Issue
Block a user