Browse Source

Merge branch 'master' into misc2

misc2
Trent Larson 1 year ago
parent
commit
7490cfc557
  1. 2
      CHANGELOG.md
  2. 4
      package-lock.json
  3. 2
      package.json
  4. 2
      src/main.ts
  5. 4
      src/views/AccountViewView.vue
  6. 70
      src/views/ContactsView.vue
  7. 15
      src/views/HelpView.vue
  8. 38
      src/views/HomeView.vue
  9. 2
      src/views/IdentitySwitcherView.vue
  10. 2
      src/views/ImportAccountView.vue
  11. 3
      src/views/StartView.vue

2
CHANGELOG.md

@ -9,6 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.1.1] - 2023.10.31
## [0.1.2] - 2023.11.01
### Added
- Basics: create ID, record a give, declare a project, search, and get notifications.

4
package-lock.json

@ -1,12 +1,12 @@
{
"name": "kickstart-for-time-pwa",
"version": "0.1.1",
"version": "0.1.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "kickstart-for-time-pwa",
"version": "0.1.1",
"version": "0.1.2",
"dependencies": {
"@ethersproject/hdnode": "^5.7.0",
"@fortawesome/fontawesome-svg-core": "^6.4.0",

2
package.json

@ -1,6 +1,6 @@
{
"name": "kickstart-for-time-pwa",
"version": "0.1.1",
"version": "0.1.2",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",

2
src/main.ts

@ -13,6 +13,7 @@ import { library } from "@fortawesome/fontawesome-svg-core";
import {
faArrowLeft,
faArrowRight,
faBan,
faBurst,
faCalendar,
faChevronLeft,
@ -59,6 +60,7 @@ import {
library.add(
faArrowLeft,
faArrowRight,
faBan,
faBurst,
faCalendar,
faChevronLeft,

4
src/views/AccountViewView.vue

@ -244,7 +244,9 @@
</div>
</div>
<!-- id used by puppeteer test script -->
<h3
id="advanced"
class="text-sm uppercase font-semibold mb-3"
@click="showAdvanced = !showAdvanced"
>
@ -277,7 +279,9 @@
</label>
<div class="flex py-2">
<!-- id used by puppeteer test script -->
<router-link
id="switch-identity-link"
:to="{ name: 'identity-switcher' }"
class="block text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-2"
>

70
src/views/ContactsView.vue

@ -93,6 +93,16 @@
class="inline-block align-text-bottom border border-slate-300 rounded"
></EntityIcon>
{{ contact.name || "(no name)" }}
<button
class="text-sm uppercase bg-slate-500 text-white px-1 rounded-md"
@click="
contactEdit = contact;
contactNewName = contact.name;
"
title="Edit"
>
<fa icon="pen" class="fa-fw" />
</button>
</h2>
<div class="text-sm truncate">{{ contact.did }}</div>
<div class="text-sm truncate" v-if="contact.publicKeyBase64">
@ -209,6 +219,31 @@
</li>
</ul>
<p v-else>This identity has no contacts.</p>
<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"
/>
<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>
</section>
</template>
@ -251,6 +286,8 @@ export default class ContactsView extends Vue {
contacts: Array<Contact> = [];
contactEndorserUrl = localStorage.getItem("contactEndorserUrl") || "";
contactInput = "";
contactEdit: Contact | null = null;
contactNewName = "";
// { "did:...": concatenated-descriptions } entry for each contact
givenByMeDescriptions: Record<string, string> = {};
// { "did:...": amount } entry for each contact
@ -961,6 +998,18 @@ export default class ContactsView extends Vue {
}
}
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 toggleShowGiveTotals() {
if (this.showGiveTotals) {
this.showGiveTotals = false;
@ -985,6 +1034,26 @@ 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 from https://www.w3schools.com/css/css_tooltip.asp */
/* Tooltip container */
.tooltip {
@ -992,7 +1061,6 @@ export default class ContactsView extends Vue {
display: inline-block;
border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;

15
src/views/HelpView.vue

@ -41,14 +41,15 @@
You need someone to register you -- usually the person who told you
about this app, on the Contacts
<fa icon="circle-user" class="fa-fw" /> page. After they register you,
and after you have contacts, you can select any contact on the home page
and record your appreciation for... whatever. That is a claim recorded
you can select any contact on the home page (or "anonymous") and record
your appreciation for... whatever. The main goal is to record what
people have given you, to grow gifting economies. Each claim is recorded
on a custom ledger. The day after being registered, you'll be able to
register others; later, you can create projects, too.
able to register others; later, you can create projects, too.
</p>
<p>
Note that there are limits to how many each person can register, so you
may have to wait.
Note that there are limits to how many others each person can register,
so you may have to wait.
</p>
<h2 class="text-xl font-semibold">How do I backup all my data?</h2>
@ -130,7 +131,9 @@
<h2 class="text-xl font-semibold">How do I create another identity?</h2>
<p>
Go
Before doing this, note that it is an advanced feature that affects
functionality (eg. the words "Alt ID" next to results, backup features)
so beware if you think that may cause confusion. You can
<router-link to="start" class="text-blue-500">
create another identity here.
</router-link>

38
src/views/HomeView.vue

@ -294,9 +294,18 @@ export default class HomeView extends Vue {
this.allMyDids,
this.allContacts,
);
const gaveAmount = claim.object?.amountOfThisGood
let gaveAmount = claim.object?.amountOfThisGood
? this.displayAmount(claim.object.unitCode, claim.object.amountOfThisGood)
: claim.description || "something without description";
: "";
if (claim.description) {
if (gaveAmount) {
gaveAmount = gaveAmount + ", and also: ";
}
gaveAmount = gaveAmount + claim.description;
}
if (!gaveAmount) {
gaveAmount = "something not described";
}
// recipient.did is for legacy data, before March 2023
const gaveRecipientId =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -390,15 +399,18 @@ export default class HomeView extends Vue {
hours,
);
if (this.isGiveCreationError(result)) {
if (
result.type === "error" ||
this.isGiveCreationError(result.response)
) {
const errorMessage = this.getGiveCreationErrorMessage(result);
console.log("Error with give result:", result);
console.log("Error with give creation result:", result);
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text: errorMessage || "There was an error recording the give.",
text: errorMessage || "There was an error creating the give.",
},
-1,
);
@ -415,7 +427,7 @@ export default class HomeView extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.log("Error with give caught:", error);
console.log("Error with give recordation caught:", error);
const message =
error.userMessage ||
error.response?.data?.error?.message ||
@ -434,14 +446,26 @@ export default class HomeView extends Vue {
// Helper functions for readability
/**
* @param result response "data" from the server
* @returns true if the result indicates an error
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
isGiveCreationError(result: any) {
return result.status !== 201 || result.data?.error;
}
/**
* @param result direct response eg. ErrorResult or SuccessResult (potentially with embedded "data")
* @returns best guess at an error message
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getGiveCreationErrorMessage(result: any) {
return result.data?.error?.message;
return (
result.error?.userMessage ||
result.error?.error ||
result.response?.data?.error?.message
);
}
}
</script>

2
src/views/IdentitySwitcherView.vue

@ -49,7 +49,9 @@
</ul>
<!-- Actions -->
<!-- id used by puppeteer test script -->
<router-link
id="start-link"
:to="{ name: 'start' }"
class="block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-2"
>

2
src/views/ImportAccountView.vue

@ -17,7 +17,9 @@
<p class="text-center text-xl mb-4 font-light">
Enter your seed phrase below to import your identity on this device.
</p>
<!-- id used by puppeteer test script -->
<input
id="seed-input"
type="text"
placeholder="Seed Phrase"
class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"

3
src/views/StartView.vue

@ -8,7 +8,8 @@
Start Here
</h1>
<div class="mt-8">
<!-- id used by puppeteer test script -->
<div id="start-question" class="mt-8">
<p class="text-center text-xl mb-4 font-light">
Do you have an identity to import?
</p>

Loading…
Cancel
Save