forked from trent_larson/crowd-funder-for-time-pwa
Many fixes -- especially and endorserServer
This commit is contained in:
@@ -1,47 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div v-bind:class="computedAlertClassNames()">
|
|
||||||
<button
|
|
||||||
class="close-button bg-amber-400 w-8 leading-loose rounded-full absolute top-2 right-2"
|
|
||||||
@click="onClickClose()"
|
|
||||||
>
|
|
||||||
<fa icon="xmark"></fa>
|
|
||||||
</button>
|
|
||||||
<h4 class="font-bold pr-5">{{ alertTitle }}</h4>
|
|
||||||
<p>{{ alertMessage }}</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { Component, Prop, Vue } from "vue-facing-decorator";
|
|
||||||
|
|
||||||
@Component
|
|
||||||
export default class AlertMessage extends Vue {
|
|
||||||
@Prop alertTitle = "";
|
|
||||||
@Prop alertMessage = "";
|
|
||||||
isAlertVisible = this.alertMessage;
|
|
||||||
|
|
||||||
public onClickClose() {
|
|
||||||
this.isAlertVisible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public computedAlertClassNames() {
|
|
||||||
return {
|
|
||||||
hidden: !this.isAlertVisible,
|
|
||||||
"dismissable-alert": true,
|
|
||||||
"bg-amber-200": true,
|
|
||||||
"p-5": true,
|
|
||||||
rounded: true,
|
|
||||||
"drop-shadow-lg": true,
|
|
||||||
fixed: true,
|
|
||||||
"top-3": true,
|
|
||||||
"inset-x-3": true,
|
|
||||||
"transition-transform": true,
|
|
||||||
"ease-in": true,
|
|
||||||
"duration-300": true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped></style>
|
|
||||||
@@ -8,7 +8,7 @@ import { toSvg } from "jdenticon";
|
|||||||
@Component
|
@Component
|
||||||
export default class EntityIcon extends Vue {
|
export default class EntityIcon extends Vue {
|
||||||
@Prop entityId = "";
|
@Prop entityId = "";
|
||||||
@Prop iconSize = "";
|
@Prop iconSize = 0;
|
||||||
|
|
||||||
generateIdenticon() {
|
generateIdenticon() {
|
||||||
const svgString = toSvg(this.entityId, this.iconSize);
|
const svgString = toSvg(this.entityId, this.iconSize);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export interface InternalError {
|
|||||||
// See https://github.com/trentlarson/endorser-ch/blob/0cb626f803028e7d9c67f095858a9fc8542e3dbd/server/api/services/util.js#L6
|
// See https://github.com/trentlarson/endorser-ch/blob/0cb626f803028e7d9c67f095858a9fc8542e3dbd/server/api/services/util.js#L6
|
||||||
const HIDDEN_DID = "did:none:HIDDEN";
|
const HIDDEN_DID = "did:none:HIDDEN";
|
||||||
|
|
||||||
export function isHiddenDid(did) {
|
export function isHiddenDid(did: string) {
|
||||||
return did === HIDDEN_DID;
|
return did === HIDDEN_DID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ export function didInfo(
|
|||||||
allMyDids: Array<string>,
|
allMyDids: Array<string>,
|
||||||
contacts: Array<Contact>,
|
contacts: Array<Contact>,
|
||||||
): string {
|
): string {
|
||||||
const myId: string | undefined = R.find(R.equals(did), allMyDids, did);
|
const myId: string | undefined = R.find(R.equals(did), allMyDids);
|
||||||
if (myId) {
|
if (myId) {
|
||||||
return "You" + (myId !== activeDid ? " (Alt ID)" : "");
|
return "You" + (myId !== activeDid ? " (Alt ID)" : "");
|
||||||
} else {
|
} else {
|
||||||
@@ -105,6 +105,18 @@ export function didInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SuccessResult {
|
||||||
|
type: "success";
|
||||||
|
response: AxiosResponse<ClaimResult>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ErrorResult {
|
||||||
|
type: "error";
|
||||||
|
error: InternalError;
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateAndSubmitGiveResult = SuccessResult | ErrorResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For result, see https://api.endorser.ch/api-docs/#/claims/post_api_v2_claim
|
* For result, see https://api.endorser.ch/api-docs/#/claims/post_api_v2_claim
|
||||||
*
|
*
|
||||||
@@ -123,71 +135,108 @@ export async function createAndSubmitGive(
|
|||||||
description: string,
|
description: string,
|
||||||
hours: number,
|
hours: number,
|
||||||
fulfillsProjectHandleId?: string,
|
fulfillsProjectHandleId?: string,
|
||||||
): Promise<AxiosResponse<ClaimResult> | InternalError> {
|
): Promise<CreateAndSubmitGiveResult> {
|
||||||
// Make a claim
|
try {
|
||||||
const vcClaim: GiveVerifiableCredential = {
|
// Make a claim
|
||||||
"@context": "https://schema.org",
|
const vcClaim: GiveVerifiableCredential = {
|
||||||
"@type": "GiveAction",
|
"@context": "https://schema.org",
|
||||||
recipient: { identifier: toDid },
|
"@type": "GiveAction",
|
||||||
};
|
recipient: { identifier: toDid },
|
||||||
if (fromDid) {
|
};
|
||||||
vcClaim.agent = { identifier: fromDid };
|
if (fromDid) {
|
||||||
}
|
vcClaim.agent = { identifier: fromDid };
|
||||||
if (description) {
|
}
|
||||||
vcClaim.description = description;
|
if (description) {
|
||||||
}
|
vcClaim.description = description;
|
||||||
if (hours) {
|
}
|
||||||
vcClaim.object = { amountOfThisGood: hours, unitCode: "HUR" };
|
if (hours) {
|
||||||
}
|
vcClaim.object = { amountOfThisGood: hours, unitCode: "HUR" };
|
||||||
if (fulfillsProjectHandleId) {
|
}
|
||||||
vcClaim.fulfills = {
|
if (fulfillsProjectHandleId) {
|
||||||
"@type": "PlanAction",
|
vcClaim.fulfills = {
|
||||||
identifier: fulfillsProjectHandleId,
|
"@type": "PlanAction",
|
||||||
|
identifier: fulfillsProjectHandleId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// Make a payload for the claim
|
||||||
|
const vcPayload = {
|
||||||
|
vc: {
|
||||||
|
"@context": ["https://www.w3.org/2018/credentials/v1"],
|
||||||
|
type: ["VerifiableCredential"],
|
||||||
|
credentialSubject: vcClaim,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a signature using private key of identity
|
||||||
|
const firstKey = identity.keys[0];
|
||||||
|
if (!firstKey || !firstKey.privateKeyHex) {
|
||||||
|
throw {
|
||||||
|
error: "No private key",
|
||||||
|
message: `Your identifier ${identity.did} is not configured correctly. Use a different identifier.`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const privateKeyHex = firstKey.privateKeyHex;
|
||||||
|
|
||||||
|
if (!privateKeyHex) {
|
||||||
|
throw {
|
||||||
|
error: "No private key",
|
||||||
|
message: `Your identifier ${identity.did} is not configured correctly. Use a different identifier.`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const signer = await SimpleSigner(privateKeyHex);
|
||||||
|
const alg = undefined;
|
||||||
|
|
||||||
|
// Create a JWT for the request
|
||||||
|
|
||||||
|
const vcJwt: string = await didJwt.createJWT(vcPayload, {
|
||||||
|
alg: alg,
|
||||||
|
issuer: identity.did,
|
||||||
|
signer: signer,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make the xhr request payload
|
||||||
|
|
||||||
|
const payload = JSON.stringify({ jwtEncoded: vcJwt });
|
||||||
|
const url = apiServer + "/api/v2/claim";
|
||||||
|
const token = await accessToken(identity);
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: "Bearer " + token,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await axios.post(url, payload, { headers });
|
||||||
|
return {
|
||||||
|
type: "success",
|
||||||
|
response,
|
||||||
|
};
|
||||||
|
} catch (error: unknown) {
|
||||||
|
let errorMessage: string;
|
||||||
|
|
||||||
|
if (error instanceof Error) {
|
||||||
|
// If it's a JavaScript Error object
|
||||||
|
errorMessage = error.message;
|
||||||
|
} else if (
|
||||||
|
typeof error === "object" &&
|
||||||
|
error !== null &&
|
||||||
|
"message" in error
|
||||||
|
) {
|
||||||
|
// If it's an object that has a 'message' property
|
||||||
|
errorMessage = (error as { message: string }).message;
|
||||||
|
} else {
|
||||||
|
// Unknown error shape, default message
|
||||||
|
errorMessage = "Unknown error";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "error",
|
||||||
|
error: {
|
||||||
|
error: errorMessage,
|
||||||
|
userMessage: "Failed to create and submit the claim",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Make a payload for the claim
|
|
||||||
const vcPayload = {
|
|
||||||
vc: {
|
|
||||||
"@context": ["https://www.w3.org/2018/credentials/v1"],
|
|
||||||
type: ["VerifiableCredential"],
|
|
||||||
credentialSubject: vcClaim,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
// Create a signature using private key of identity
|
|
||||||
if (identity.keys[0].privateKeyHex == null) {
|
|
||||||
return new Promise<InternalError>((resolve, reject) => {
|
|
||||||
reject({
|
|
||||||
error: "No private key",
|
|
||||||
message:
|
|
||||||
"Your identifier " +
|
|
||||||
identity.did +
|
|
||||||
" is not configured correctly. Use a different identifier.",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
const privateKeyHex: string = identity.keys[0].privateKeyHex!;
|
|
||||||
const signer = await SimpleSigner(privateKeyHex);
|
|
||||||
const alg = undefined;
|
|
||||||
// Create a JWT for the request
|
|
||||||
const vcJwt: string = await didJwt.createJWT(vcPayload, {
|
|
||||||
alg: alg,
|
|
||||||
issuer: identity.did,
|
|
||||||
signer: signer,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make the xhr request payload
|
|
||||||
|
|
||||||
const payload = JSON.stringify({ jwtEncoded: vcJwt });
|
|
||||||
const url = apiServer + "/api/v2/claim";
|
|
||||||
const token = await accessToken(identity);
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: "Bearer " + token,
|
|
||||||
};
|
|
||||||
|
|
||||||
return axios.post(url, payload, { headers });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// from https://stackoverflow.com/a/175787/845494
|
// from https://stackoverflow.com/a/175787/845494
|
||||||
|
|||||||
@@ -286,10 +286,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -303,15 +299,23 @@ import { db, accountsDB } from "@/db";
|
|||||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
import { accessToken } from "@/libs/crypto";
|
import { accessToken } from "@/libs/crypto";
|
||||||
import { AxiosError } from "axios/index";
|
import { AxiosError } from "axios/index";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
import { IIdentifier } from "@veramo/core";
|
import { IIdentifier } from "@veramo/core";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const Buffer = require("buffer/").Buffer;
|
const Buffer = require("buffer/").Buffer;
|
||||||
|
|
||||||
@Component({ components: { AlertMessage, QuickNav } })
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({ components: { QuickNav } })
|
||||||
export default class AccountViewView extends Vue {
|
export default class AccountViewView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
Constants = AppString;
|
Constants = AppString;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
|
|||||||
@@ -90,10 +90,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -113,17 +109,23 @@ import {
|
|||||||
} from "@/libs/endorserServer";
|
} from "@/libs/endorserServer";
|
||||||
import * as didJwt from "did-jwt";
|
import * as didJwt from "did-jwt";
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
|
|
||||||
@Component({ components: { AlertMessage, QuickNav } })
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({ components: { QuickNav } })
|
||||||
export default class ContactsView extends Vue {
|
export default class ContactsView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
apiServer = "";
|
apiServer = "";
|
||||||
contact: Contact | null = null;
|
contact: Contact | null = null;
|
||||||
giveRecords: Array<GiveServerRecord> = [];
|
giveRecords: Array<GiveServerRecord> = [];
|
||||||
alertTitle = "";
|
|
||||||
alertMessage = "";
|
|
||||||
numAccounts = 0;
|
numAccounts = 0;
|
||||||
|
|
||||||
async beforeCreate() {
|
async beforeCreate() {
|
||||||
|
|||||||
@@ -76,10 +76,6 @@
|
|||||||
message="Received from"
|
message="Received from"
|
||||||
>
|
>
|
||||||
</GiftedDialog>
|
</GiftedDialog>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -93,21 +89,27 @@ import { accessToken } from "@/libs/crypto";
|
|||||||
import { createAndSubmitGive } from "@/libs/endorserServer";
|
import { createAndSubmitGive } from "@/libs/endorserServer";
|
||||||
import { Account } from "@/db/tables/accounts";
|
import { Account } from "@/db/tables/accounts";
|
||||||
import { Contact } from "@/db/tables/contacts";
|
import { Contact } from "@/db/tables/contacts";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
import EntityIcon from "@/components/EntityIcon";
|
import EntityIcon from "@/components/EntityIcon";
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: { GiftedDialog, AlertMessage, QuickNav, EntityIcon },
|
components: { GiftedDialog, QuickNav, EntityIcon },
|
||||||
})
|
})
|
||||||
export default class HomeView extends Vue {
|
export default class HomeView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
allAccounts: Array<Account> = [];
|
allAccounts: Array<Account> = [];
|
||||||
allContacts: Array<Contact> = [];
|
allContacts: Array<Contact> = [];
|
||||||
apiServer = "";
|
apiServer = "";
|
||||||
isHiddenSpinner = true;
|
isHiddenSpinner = true;
|
||||||
alertTitle = "";
|
|
||||||
alertMessage = "";
|
|
||||||
accounts: AccountsSchema;
|
accounts: AccountsSchema;
|
||||||
numAccounts = 0;
|
numAccounts = 0;
|
||||||
|
|
||||||
@@ -289,11 +291,6 @@ export default class HomeView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setAlert(title, message) {
|
|
||||||
this.alertTitle = title;
|
|
||||||
this.alertMessage = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions for readability
|
// Helper functions for readability
|
||||||
|
|
||||||
isGiveCreationError(result) {
|
isGiveCreationError(result) {
|
||||||
|
|||||||
@@ -34,6 +34,13 @@ import { Account } from "@/db/tables/accounts";
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const Buffer = require("buffer/").Buffer;
|
const Buffer = require("buffer/").Buffer;
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
QRCodeVue3,
|
QRCodeVue3,
|
||||||
@@ -41,6 +48,8 @@ const Buffer = require("buffer/").Buffer;
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class ContactQRScanShow extends Vue {
|
export default class ContactQRScanShow extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
apiServer = "";
|
apiServer = "";
|
||||||
qrValue = "";
|
qrValue = "";
|
||||||
|
|||||||
@@ -202,10 +202,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p v-else>This identity has no contacts.</p>
|
<p v-else>This identity has no contacts.</p>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -224,17 +220,25 @@ import {
|
|||||||
SERVICE_ID,
|
SERVICE_ID,
|
||||||
} from "@/libs/endorserServer";
|
} from "@/libs/endorserServer";
|
||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
import EntityIcon from "@/components/EntityIcon";
|
import EntityIcon from "@/components/EntityIcon";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const Buffer = require("buffer/").Buffer;
|
const Buffer = require("buffer/").Buffer;
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: { AlertMessage, QuickNav, EntityIcon },
|
components: { QuickNav, EntityIcon },
|
||||||
})
|
})
|
||||||
export default class ContactsView extends Vue {
|
export default class ContactsView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
apiServer = "";
|
apiServer = "";
|
||||||
contacts: Array<Contact> = [];
|
contacts: Array<Contact> = [];
|
||||||
@@ -256,8 +260,6 @@ export default class ContactsView extends Vue {
|
|||||||
showGiveNumbers = false;
|
showGiveNumbers = false;
|
||||||
showGiveTotals = true;
|
showGiveTotals = true;
|
||||||
showGiveConfirmed = true;
|
showGiveConfirmed = true;
|
||||||
alertTitle = "";
|
|
||||||
alertMessage = "";
|
|
||||||
|
|
||||||
async created() {
|
async created() {
|
||||||
await db.open();
|
await db.open();
|
||||||
|
|||||||
@@ -181,8 +181,6 @@
|
|||||||
/>
|
/>
|
||||||
</l-map>
|
</l-map>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<AlertMessage :alertTitle="alertTitle" :alertMessage="alertMessage" />
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -201,7 +199,6 @@ import { Contact } from "@/db/tables/contacts";
|
|||||||
import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
import { accessToken } from "@/libs/crypto";
|
import { accessToken } from "@/libs/crypto";
|
||||||
import { didInfo, ProjectData } from "@/libs/endorserServer";
|
import { didInfo, ProjectData } from "@/libs/endorserServer";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||||
import EntityIcon from "@/components/EntityIcon";
|
import EntityIcon from "@/components/EntityIcon";
|
||||||
@@ -210,10 +207,16 @@ const DEFAULT_LAT_LONG_DIFF = 0.01;
|
|||||||
const WORLD_ZOOM = 2;
|
const WORLD_ZOOM = 2;
|
||||||
const DEFAULT_ZOOM = 2;
|
const DEFAULT_ZOOM = 2;
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
LRectangle,
|
LRectangle,
|
||||||
AlertMessage,
|
|
||||||
QuickNav,
|
QuickNav,
|
||||||
InfiniteScroll,
|
InfiniteScroll,
|
||||||
EntityIcon,
|
EntityIcon,
|
||||||
@@ -223,13 +226,13 @@ const DEFAULT_ZOOM = 2;
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class DiscoverView extends Vue {
|
export default class DiscoverView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
allContacts: Array<Contact> = [];
|
allContacts: Array<Contact> = [];
|
||||||
allMyDids: Array<string> = [];
|
allMyDids: Array<string> = [];
|
||||||
apiServer = "";
|
apiServer = "";
|
||||||
searchTerms = "";
|
searchTerms = "";
|
||||||
alertMessage = "";
|
|
||||||
alertTitle = "";
|
|
||||||
projects: ProjectData[] = [];
|
projects: ProjectData[] = [];
|
||||||
isChoosingSearchBox = false;
|
isChoosingSearchBox = false;
|
||||||
isLocalActive = true;
|
isLocalActive = true;
|
||||||
|
|||||||
@@ -196,10 +196,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -211,14 +207,22 @@ import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
|||||||
import { accessToken } from "@/libs/crypto";
|
import { accessToken } from "@/libs/crypto";
|
||||||
import { createAndSubmitGive, didInfo } from "@/libs/endorserServer";
|
import { createAndSubmitGive, didInfo } from "@/libs/endorserServer";
|
||||||
import { Contact } from "@/db/tables/contacts";
|
import { Contact } from "@/db/tables/contacts";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
import EntityIcon from "@/components/EntityIcon";
|
import EntityIcon from "@/components/EntityIcon";
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: { GiftedDialog, AlertMessage, QuickNav, EntityIcon },
|
components: { GiftedDialog, QuickNav, EntityIcon },
|
||||||
})
|
})
|
||||||
export default class HomeView extends Vue {
|
export default class HomeView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
allContacts: Array<Contact> = [];
|
allContacts: Array<Contact> = [];
|
||||||
allMyDids: Array<string> = [];
|
allMyDids: Array<string> = [];
|
||||||
@@ -228,8 +232,6 @@ export default class HomeView extends Vue {
|
|||||||
feedPreviousOldestId = null;
|
feedPreviousOldestId = null;
|
||||||
feedLastViewedId = null;
|
feedLastViewedId = null;
|
||||||
isHiddenSpinner = true;
|
isHiddenSpinner = true;
|
||||||
alertTitle = "";
|
|
||||||
alertMessage = "";
|
|
||||||
numAccounts = 0;
|
numAccounts = 0;
|
||||||
|
|
||||||
async beforeCreate() {
|
async beforeCreate() {
|
||||||
@@ -509,11 +511,6 @@ export default class HomeView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setAlert(title, message) {
|
|
||||||
this.alertTitle = title;
|
|
||||||
this.alertMessage = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions for readability
|
// Helper functions for readability
|
||||||
|
|
||||||
isGiveCreationError(result) {
|
isGiveCreationError(result) {
|
||||||
|
|||||||
@@ -62,11 +62,6 @@
|
|||||||
>
|
>
|
||||||
No Identity
|
No Identity
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -75,18 +70,24 @@ import { AppString } from "@/constants/app";
|
|||||||
import { db, accountsDB } from "@/db";
|
import { db, accountsDB } from "@/db";
|
||||||
import { AccountsSchema } from "@/db/tables/accounts";
|
import { AccountsSchema } from "@/db/tables/accounts";
|
||||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
|
|
||||||
@Component({ components: { AlertMessage, QuickNav } })
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({ components: { QuickNav } })
|
||||||
export default class IdentitySwitcherView extends Vue {
|
export default class IdentitySwitcherView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
Constants = AppString;
|
Constants = AppString;
|
||||||
public accounts: AccountsSchema;
|
public accounts: AccountsSchema;
|
||||||
public activeDid;
|
public activeDid;
|
||||||
public firstName;
|
public firstName;
|
||||||
public lastName;
|
public lastName;
|
||||||
public alertTitle;
|
|
||||||
public alertMessage;
|
|
||||||
public otherIdentities = [];
|
public otherIdentities = [];
|
||||||
|
|
||||||
public async getIdentity(activeDid) {
|
public async getIdentity(activeDid) {
|
||||||
|
|||||||
@@ -97,10 +97,6 @@
|
|||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -116,15 +112,21 @@ import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
|||||||
import { accessToken, SimpleSigner } from "@/libs/crypto";
|
import { accessToken, SimpleSigner } from "@/libs/crypto";
|
||||||
import { useAppStore } from "@/store/app";
|
import { useAppStore } from "@/store/app";
|
||||||
import { IIdentifier } from "@veramo/core";
|
import { IIdentifier } from "@veramo/core";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: { AlertMessage, LMap, LMarker, LTileLayer },
|
components: { LMap, LMarker, LTileLayer },
|
||||||
})
|
})
|
||||||
export default class NewEditProjectView extends Vue {
|
export default class NewEditProjectView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
alertTitle = "";
|
|
||||||
alertMessage = "";
|
|
||||||
apiServer = "";
|
apiServer = "";
|
||||||
description = "";
|
description = "";
|
||||||
errorMessage = "";
|
errorMessage = "";
|
||||||
@@ -270,8 +272,7 @@ export default class NewEditProjectView extends Vue {
|
|||||||
// version shows up here: https://api.endorser.ch/api-docs/
|
// version shows up here: https://api.endorser.ch/api-docs/
|
||||||
if (resp.data?.success?.handleId || resp.data?.success?.fullIri) {
|
if (resp.data?.success?.handleId || resp.data?.success?.fullIri) {
|
||||||
this.errorMessage = "";
|
this.errorMessage = "";
|
||||||
this.alertTitle = "";
|
|
||||||
this.alertMessage = "";
|
|
||||||
// handleId is new in server v release-1.6.0; remove fullIri when that
|
// handleId is new in server v release-1.6.0; remove fullIri when that
|
||||||
// version shows up here: https://api.endorser.ch/api-docs/
|
// version shows up here: https://api.endorser.ch/api-docs/
|
||||||
useAppStore().setProjectId(
|
useAppStore().setProjectId(
|
||||||
|
|||||||
@@ -200,10 +200,6 @@
|
|||||||
message="Received from"
|
message="Received from"
|
||||||
>
|
>
|
||||||
</GiftedDialog>
|
</GiftedDialog>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -226,10 +222,19 @@ import {
|
|||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
import EntityIcon from "@/components/EntityIcon";
|
import EntityIcon from "@/components/EntityIcon";
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: { GiftedDialog, QuickNav, EntityIcon },
|
components: { GiftedDialog, QuickNav, EntityIcon },
|
||||||
})
|
})
|
||||||
export default class ProjectViewView extends Vue {
|
export default class ProjectViewView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
activeDid = "";
|
activeDid = "";
|
||||||
allMyDids: Array<string> = [];
|
allMyDids: Array<string> = [];
|
||||||
allContacts: Array<Contact> = [];
|
allContacts: Array<Contact> = [];
|
||||||
@@ -339,7 +344,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
this.longitude = resp.data.claim?.location?.geo?.longitude || 0;
|
this.longitude = resp.data.claim?.location?.geo?.longitude || 0;
|
||||||
} else if (resp.status === 404) {
|
} else if (resp.status === 404) {
|
||||||
// actually, axios throws an error so we never get here
|
// actually, axios throws an error so we never get here
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -352,7 +357,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
if (serverError.response?.status === 404) {
|
if (serverError.response?.status === 404) {
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -362,7 +367,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -384,7 +389,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
if (resp.status === 200 && resp.data.data) {
|
if (resp.status === 200 && resp.data.data) {
|
||||||
this.givesToThis = resp.data.data;
|
this.givesToThis = resp.data.data;
|
||||||
} else {
|
} else {
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -396,7 +401,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -420,7 +425,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
if (resp.status === 200 && resp.data.data) {
|
if (resp.status === 200 && resp.data.data) {
|
||||||
this.givesByThis = resp.data.data;
|
this.givesByThis = resp.data.data;
|
||||||
} else {
|
} else {
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -432,7 +437,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -485,7 +490,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
*/
|
*/
|
||||||
async recordGive(giverDid, description: string, hours: number) {
|
async recordGive(giverDid, description: string, hours: number) {
|
||||||
if (!this.activeDid) {
|
if (!this.activeDid) {
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -498,7 +503,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!description && !hours) {
|
if (!description && !hours) {
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -507,10 +512,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
},
|
},
|
||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const identity = await this.getIdentity(this.activeDid);
|
const identity = await this.getIdentity(this.activeDid);
|
||||||
const result = await createAndSubmitGive(
|
const result = await createAndSubmitGive(
|
||||||
this.axios,
|
this.axios,
|
||||||
@@ -522,22 +524,23 @@ export default class ProjectViewView extends Vue {
|
|||||||
hours,
|
hours,
|
||||||
this.projectId,
|
this.projectId,
|
||||||
);
|
);
|
||||||
|
if (result.type == "success") {
|
||||||
if (result.status !== 201 || result.data?.error) {
|
|
||||||
console.log("Error with give result:", result);
|
console.log("Error with give result:", result);
|
||||||
(this as any).$notify(
|
if ("data" in result) {
|
||||||
{
|
this.$notify(
|
||||||
group: "alert",
|
{
|
||||||
type: "danger",
|
group: "alert",
|
||||||
title: "Error",
|
type: "danger",
|
||||||
text:
|
title: "Error",
|
||||||
result.data?.error?.message ||
|
text:
|
||||||
"There was an error recording the give.",
|
result.data?.error?.message ||
|
||||||
},
|
"There was an error recording the give.",
|
||||||
-1,
|
},
|
||||||
);
|
-1,
|
||||||
} else {
|
);
|
||||||
(this as any).$notify(
|
}
|
||||||
|
} else if (result.type == "error") {
|
||||||
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "success",
|
type: "success",
|
||||||
@@ -547,20 +550,6 @@ export default class ProjectViewView extends Vue {
|
|||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
console.log("Error with give caught:", e);
|
|
||||||
(this as any).$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text:
|
|
||||||
e?.userMessage ||
|
|
||||||
e?.response?.data?.error?.message ||
|
|
||||||
"There was an error recording the give.",
|
|
||||||
},
|
|
||||||
-1,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,10 +67,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</InfiniteScroll>
|
</InfiniteScroll>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -81,14 +77,22 @@ import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
|||||||
import { accessToken } from "@/libs/crypto";
|
import { accessToken } from "@/libs/crypto";
|
||||||
import { IIdentifier } from "@veramo/core";
|
import { IIdentifier } from "@veramo/core";
|
||||||
import InfiniteScroll from "@/components/InfiniteScroll";
|
import InfiniteScroll from "@/components/InfiniteScroll";
|
||||||
import AlertMessage from "@/components/AlertMessage";
|
|
||||||
import QuickNav from "@/components/QuickNav";
|
import QuickNav from "@/components/QuickNav";
|
||||||
import EntityIcon from "@/components/EntityIcon";
|
import EntityIcon from "@/components/EntityIcon";
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: { InfiniteScroll, AlertMessage, QuickNav, EntityIcon },
|
components: { InfiniteScroll, QuickNav, EntityIcon },
|
||||||
})
|
})
|
||||||
export default class ProjectsView extends Vue {
|
export default class ProjectsView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
apiServer = "";
|
apiServer = "";
|
||||||
projects: ProjectData[] = [];
|
projects: ProjectData[] = [];
|
||||||
current: IIdentifier;
|
current: IIdentifier;
|
||||||
|
|||||||
@@ -50,10 +50,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>You do not have an active identity.</div>
|
<div v-else>You do not have an active identity.</div>
|
||||||
<AlertMessage
|
|
||||||
:alertTitle="alertTitle"
|
|
||||||
:alertMessage="alertMessage"
|
|
||||||
></AlertMessage>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -64,9 +60,22 @@ import * as R from "ramda";
|
|||||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
import QuickNav from "@/components/QuickNav.vue";
|
import QuickNav from "@/components/QuickNav.vue";
|
||||||
|
|
||||||
|
interface Account {
|
||||||
|
mnemonic: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({ components: { QuickNav } })
|
@Component({ components: { QuickNav } })
|
||||||
export default class SeedBackupView extends Vue {
|
export default class SeedBackupView extends Vue {
|
||||||
activeAccount = null;
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
|
activeAccount: Account | null | undefined = null;
|
||||||
numAccounts = 0;
|
numAccounts = 0;
|
||||||
showSeed = false;
|
showSeed = false;
|
||||||
|
|
||||||
@@ -83,7 +92,7 @@ export default class SeedBackupView extends Vue {
|
|||||||
this.activeAccount = R.find((acc) => acc.did === activeDid, accounts);
|
this.activeAccount = R.find((acc) => acc.did === activeDid, accounts);
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
console.error("Got an error loading an identity:", err);
|
console.error("Got an error loading an identity:", err);
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { SVGRenderer } from "three/addons/renderers/SVGRenderer.js";
|
import { SVGRenderer } from "three/addons/renderers/SVGRenderer.js";
|
||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
import { World } from "components/World/World.js";
|
import { World } from "@/components/World/World.js";
|
||||||
import QuickNav from "@/components/QuickNav.vue";
|
import QuickNav from "@/components/QuickNav.vue";
|
||||||
|
|
||||||
interface RendererSVGType {
|
interface RendererSVGType {
|
||||||
@@ -50,8 +50,17 @@ interface Dictionary<T> {
|
|||||||
[key: string]: T;
|
[key: string]: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Notification {
|
||||||
|
group: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({ components: { World, QuickNav } })
|
@Component({ components: { World, QuickNav } })
|
||||||
export default class StatisticsView extends Vue {
|
export default class StatisticsView extends Vue {
|
||||||
|
$notify!: (notification: Notification, timeout?: number) => void;
|
||||||
|
|
||||||
world: World;
|
world: World;
|
||||||
worldProperties: Dictionary<number> = {};
|
worldProperties: Dictionary<number> = {};
|
||||||
|
|
||||||
@@ -61,9 +70,9 @@ export default class StatisticsView extends Vue {
|
|||||||
const newWorld = new World(container, this);
|
const newWorld = new World(container, this);
|
||||||
newWorld.start();
|
newWorld.start();
|
||||||
this.world = newWorld;
|
this.world = newWorld;
|
||||||
} catch (err : unknown) {
|
} catch (err: unknown) {
|
||||||
const error = err as Error;
|
const error = err as Error;
|
||||||
(this as any).$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
@@ -91,7 +100,6 @@ export default class StatisticsView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function ExportToSVG(rendererSVG: RendererSVGType, filename: string) {
|
function ExportToSVG(rendererSVG: RendererSVGType, filename: string) {
|
||||||
const XMLS = new XMLSerializer();
|
const XMLS = new XMLSerializer();
|
||||||
const svgfile = XMLS.serializeToString(rendererSVG.domElement);
|
const svgfile = XMLS.serializeToString(rendererSVG.domElement);
|
||||||
|
|||||||
@@ -1,41 +1,43 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "esnext",
|
"allowJs": true,
|
||||||
"module": "esnext",
|
"target": "esnext",
|
||||||
"strict": true,
|
"module": "esnext",
|
||||||
"jsx": "preserve",
|
"strict": true,
|
||||||
"moduleResolution": "node",
|
"strictPropertyInitialization": false,
|
||||||
"experimentalDecorators": true,
|
"jsx": "preserve",
|
||||||
"skipLibCheck": true,
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"experimentalDecorators": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"skipLibCheck": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"esModuleInterop": true,
|
||||||
"useDefineForClassFields": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"sourceMap": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"baseUrl": ".",
|
"useDefineForClassFields": true,
|
||||||
"types": [
|
"sourceMap": true,
|
||||||
"webpack-env"
|
"baseUrl": ".",
|
||||||
],
|
"types": [
|
||||||
"paths": {
|
"webpack-env"
|
||||||
"@/*": [
|
],
|
||||||
"src/*"
|
"paths": {
|
||||||
]
|
"@/*": [
|
||||||
|
"src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"lib": [
|
"include": [
|
||||||
"esnext",
|
"src/**/*.ts",
|
||||||
"dom",
|
"src/**/*.tsx",
|
||||||
"dom.iterable",
|
"src/**/*.vue",
|
||||||
"scripthost"
|
"tests/**/*.ts",
|
||||||
|
"tests/**/*.tsx"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src/**/*.ts",
|
|
||||||
"src/**/*.tsx",
|
|
||||||
"src/**/*.vue",
|
|
||||||
"tests/**/*.ts",
|
|
||||||
"tests/**/*.tsx"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user