diff --git a/project.task.yaml b/project.task.yaml index 897517c5..5e8936f3 100644 --- a/project.task.yaml +++ b/project.task.yaml @@ -4,6 +4,7 @@ - add infinite scroll assignee:matthew blocks: ref:https://raw.githubusercontent.com/trentlarson/lives-of-gifts/master/project.yaml#kickstarter%20for%20time +- allow type annotations in World.js & landmarks.js (since we get this error: "Types are not supported by current JavaScript version") - replace user-affecting console.log & console.error with error messages (eg. catches) - stats v1 : diff --git a/src/components/World/World.js b/src/components/World/World.js index dca75c13..a3e8e6f4 100644 --- a/src/components/World/World.js +++ b/src/components/World/World.js @@ -24,6 +24,8 @@ class World { this.update = this.update.bind(this); + this.vue = vue; + // Instances of camera, scene, and renderer this.camera = createCamera(); this.scene = createScene(COLOR2); @@ -99,6 +101,10 @@ class World { stop() { this.loop.stop(); } + + setExposedWorldProperties(key, value) { + this.vue.setWorldProperty(key, value); + } } export { World }; diff --git a/src/components/World/components/objects/landmarks.js b/src/components/World/components/objects/landmarks.js index 9937d9cf..3c6dbfaf 100644 --- a/src/components/World/components/objects/landmarks.js +++ b/src/components/World/components/objects/landmarks.js @@ -12,6 +12,8 @@ const ANIMATION_DURATION_SECS = 10; const ENDORSER_ENTITY_PREFIX = "https://endorser.ch/entity/"; export async function loadLandmarks(vue, world, scene, loop) { + vue.setWorldProperty("animationDurationSeconds", ANIMATION_DURATION_SECS); + try { await db.open(); const settings = await db.settings.get(MASTER_SETTINGS_KEY); @@ -31,8 +33,13 @@ export async function loadLandmarks(vue, world, scene, loop) { const resp = await axios.get(url, { headers: headers }); if (resp.status === 200) { const landmarks = resp.data.data; + const minDate = landmarks[landmarks.length - 1].issuedAt; const maxDate = landmarks[0].issuedAt; + + world.setExposedWorldProperties("startTime", minDate.replace("T", " ")); + world.setExposedWorldProperties("endTime", maxDate.replace("T", " ")); + const minTimeMillis = new Date(minDate).getTime(); const fullTimeMillis = maxDate > minDate ? new Date(maxDate).getTime() - minTimeMillis : 1; // avoid divide by zero diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts index 2fefe738..227577fe 100644 --- a/src/libs/endorserServer.ts +++ b/src/libs/endorserServer.ts @@ -1,6 +1,15 @@ export const SCHEMA_ORG_CONTEXT = "https://schema.org"; export const SERVICE_ID = "endorser.ch"; +export interface GenericClaim { + "@context": string; + "@type": string; + issuedAt: string; + // "any" because arbitrary objects can be subject of agreement + // eslint-disable-next-line @typescript-eslint/no-explicit-any + claim: Record; +} + export interface AgreeVerifiableCredential { "@context": string; "@type": string; diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue index fe5e4f2c..dd4c412b 100644 --- a/src/views/AccountViewView.vue +++ b/src/views/AccountViewView.vue @@ -294,7 +294,7 @@ :to="{ name: 'statistics' }" class="block text-center py-3 px-1" > - See Your Statistics + See Achievements & Statistics diff --git a/src/views/StatisticsView.vue b/src/views/StatisticsView.vue index 6cbb763a..1b32a14c 100644 --- a/src/views/StatisticsView.vue +++ b/src/views/StatisticsView.vue @@ -51,9 +51,35 @@

- Your Statistics + Achievements & Statistics

+
+ Here is a view of the activity you can see. +
    +
  • Each identity and claim has a unique position.
  • + +
  • Each will show at their time of appearance relative to all others.
  • +
  • Note that the ones on the left and right edges are randomized + because not all their positional data is visible to you. +
  • + +
+
+ +
+
+ + {{ worldProperties.startTime }} + - + {{ worldProperties.endTime }} +
+
+ + {{ worldProperties.animationDurationSeconds }} seconds +
+
+ @@ -77,9 +103,15 @@ import { SVGRenderer } from "three/addons/renderers/SVGRenderer.js"; import { Component, Vue } from "vue-facing-decorator"; import { World } from "@/components/World/World.js"; +interface WorldProperties { + startTime?: string; + endTime?: string; +} + @Component export default class StatisticsView extends Vue { world: World; + worldProperties: WorldProperties = {}; mounted() { const container = document.querySelector("#scene-container"); @@ -158,6 +190,10 @@ export default class StatisticsView extends Vue { ExportToSVG(rendererSVG, "test.svg"); } + public setWorldProperty(propertyName, propertyValue) { + this.worldProperties[propertyName] = propertyValue; + } + alertTitle = ""; alertMessage = ""; isAlertVisible = false;