From 78c8d976bdcd5f4136332d18d7eec20c44f3309c Mon Sep 17 00:00:00 2001 From: Adophilus Date: Thu, 4 Jan 2024 08:32:10 +0000 Subject: [PATCH 001/120] inpmenented some bits of the connect page --- tauri-app/src/pages/connect.tsx | 64 +++++++++++++++++-- tauri-app/src/pages/medic.tsx | 23 +++++-- tauri-app/src/stores/useDocuments.ts | 61 +++++++++++++++++- tauri-app/src/stores/useWeb5Store.ts | 7 +- .../src/utils/protocols/medical-conditions.ts | 30 +++++++++ 5 files changed, 171 insertions(+), 14 deletions(-) create mode 100644 tauri-app/src/utils/protocols/medical-conditions.ts diff --git a/tauri-app/src/pages/connect.tsx b/tauri-app/src/pages/connect.tsx index 650cec8..e6f9ec4 100644 --- a/tauri-app/src/pages/connect.tsx +++ b/tauri-app/src/pages/connect.tsx @@ -1,9 +1,65 @@ -// import React from "react"; +import useWeb5Store, { schemaOrgProtocolDefinition } from "@/stores/useWeb5Store"; +import { useDocuments } from "@/stores/useDocuments"; +import { useEffect, useState } from "react"; + +function Connect() { + const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })) + const { fetchDocumentsWithCondition } = useDocuments(web5, did) + const [similarConditions, setSimilarConditions] = useState<{ did: string, condition: string }[]>([]) + const [form, setForm] = useState<{ + condition: string + }>({ + condition: "" + }) + + useEffect(() => { + fetchDocumentsWithCondition("cancer") + }, []) + + const connectCondition = async () => { + const res = await fetchDocumentsWithCondition(form.condition) + console.log(res) + if (res) + setSimilarConditions(res) + } + -function Connect (){ return ( -
+ <> +
+
{ + e.preventDefault() + connectCondition() + }}> + { + setForm({ ...form, condition: e.target.value }) + }} + placeholder="Condition" /> + +
+
+
+
+ People with similar conditions: +
+
+ {similarConditions.map((condition, index) => ( +
+
+ {condition.did} +
+
+ {condition.condition} +
+
+ ))} +
+
+ ) } -export default Connect; \ No newline at end of file +export default Connect; diff --git a/tauri-app/src/pages/medic.tsx b/tauri-app/src/pages/medic.tsx index 58fa9b5..40ed80e 100644 --- a/tauri-app/src/pages/medic.tsx +++ b/tauri-app/src/pages/medic.tsx @@ -3,8 +3,8 @@ import useWeb5Store, { schemaOrgProtocolDefinition } from "@/stores/useWeb5Store import { useDocuments } from "@/stores/useDocuments"; const MedicPage: FunctionComponent = () => { - const { web5, connect } = useWeb5Store((state) => ({ web5: state.web5!, connect: state.connect })); - const { fetchDocuments, documents, createDocument, getDocumentFile } = useDocuments(web5) + const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })) + const { fetchDocuments, documents, createDocument, getDocumentFile } = useDocuments(web5, did) const [docsWithImageUrls, setDocsWithImageUrls] = useState<{ document: typeof documents[0], url: string @@ -12,10 +12,12 @@ const MedicPage: FunctionComponent = () => { const [form, setForm] = useState<{ name: string - doc: File + doc: File, + condition: string }>({ name: "", - doc: new File([], "") + doc: new File([], ""), + condition: "" }) useEffect(() => { @@ -47,7 +49,7 @@ const MedicPage: FunctionComponent = () => { }, [documents]) const saveMedicalRecord = async () => { - const res = await createDocument({ name: form.name ? form.name : undefined, file: form.doc }) + const res = await createDocument({ name: form.name ? form.name : undefined, file: form.doc, condition: form.condition }) // console.log(res) if (res) { @@ -90,6 +92,17 @@ const MedicPage: FunctionComponent = () => { }} placeholder="Document" /> +
+ { + setForm({ + ...form, + condition: e.target.value.toLowerCase() + }) + }} + placeholder="Condition" /> +
diff --git a/tauri-app/src/stores/useDocuments.ts b/tauri-app/src/stores/useDocuments.ts index 9227b2d..599cdd4 100644 --- a/tauri-app/src/stores/useDocuments.ts +++ b/tauri-app/src/stores/useDocuments.ts @@ -1,6 +1,7 @@ import { Web5, Record as Web5Record } from '@web5/api'; import { useState, useEffect } from 'react'; import { schemaOrgProtocolDefinition } from './useWeb5Store'; +import MedicalConditionsProtocol, { did as MedicalConditionsProtocolDID } from '@/utils/protocols/medical-conditions'; import _ from "lodash" export type DigitalDocument = { @@ -24,7 +25,7 @@ type Document = { data: DigitalDocument } -export function useDocuments(web5: Web5) { +export function useDocuments(web5: Web5, did: string) { const [documents, setDocuments] = useState([]); async function fetchDocuments() { @@ -51,6 +52,40 @@ export function useDocuments(web5: Web5) { setDocuments(docs); } + async function fetchDocumentsWithCondition(condition: string) { + + const res = await web5.dwn.records.query({ + from: MedicalConditionsProtocolDID, + message: { + filter: { + protocolPath: 'medicalCondition', + schema: MedicalConditionsProtocol.types.medicalCondition.schema, + }, + }, + }); + console.log(res) + console.log(res.records) + + return [] + const { records } = await web5.dwn.records.query({ + from: MedicalConditionsProtocolDID, + message: { + filter: { + protocolPath: 'medicalCondition', + schema: MedicalConditionsProtocol.types.medicalCondition.schema, + }, + dateSort: "createdAscending", + }, + }); + if (!records) return false + + const fetchedRecords = await Promise.allSettled(records.map(record => record.data.json())) + .then(results => results + .filter(result => result.status === 'fulfilled') + .map(result => result.value)) + return fetchedRecords + } + async function createDocument({ name, file, condition }: { name: string | undefined, file: File, condition: string }): Promise { const { record: uploadedFileResponse } = await web5.dwn.records.create({ data: new Blob([file], { type: file.type }), @@ -83,6 +118,28 @@ export function useDocuments(web5: Web5) { if (!record) return false; + const { record: medicalConditionRecord, status } = await web5.dwn.records.create({ + data: { + condition, + did + }, + message: { + protocol: MedicalConditionsProtocol.protocol, + protocolPath: 'medicalCondition', + schema: MedicalConditionsProtocol.types.medicalCondition.schema, + dataFormat: MedicalConditionsProtocol.types.medicalCondition.dataFormats[0], + } + }) + + console.log(status) + console.log(medicalConditionRecord) + if (!medicalConditionRecord) return false + + await medicalConditionRecord.send(MedicalConditionsProtocolDID) + console.log('sent to pulsepal dwn') + await medicalConditionRecord.send(did) + console.log('sent to user dwn') + const data = await record.data.json(); const doc = { record, data, id: record.id }; @@ -158,5 +215,5 @@ export function useDocuments(web5: Web5) { return file; } - return { documents, createDocument, updateDocument, deleteDocument, getDocumentFile, fetchDocuments }; + return { documents, createDocument, updateDocument, deleteDocument, getDocumentFile, fetchDocuments, fetchDocumentsWithCondition }; } diff --git a/tauri-app/src/stores/useWeb5Store.ts b/tauri-app/src/stores/useWeb5Store.ts index 637f0f3..0dcdf84 100644 --- a/tauri-app/src/stores/useWeb5Store.ts +++ b/tauri-app/src/stores/useWeb5Store.ts @@ -1,5 +1,6 @@ import { Web5 } from "@web5/api/browser"; import { create } from "zustand"; +import MedicalConditionsProtocol from "@/utils/protocols/medical-conditions"; interface Web5State { web5: Web5 | null; @@ -56,9 +57,9 @@ const useWeb5Store = create((set, get) => ({ return; } - // protocol already exists if (protocols.length > 0) { - // console.log("protocol already exists"); + console.log("protocol already exists:", await protocols[0]) + continue } // configure protocol on local DWN @@ -190,4 +191,4 @@ export const schemaOrgProtocolDefinition = { }, }; -const protocols = [schemaOrgProtocolDefinition]; +const protocols = [schemaOrgProtocolDefinition, MedicalConditionsProtocol]; diff --git a/tauri-app/src/utils/protocols/medical-conditions.ts b/tauri-app/src/utils/protocols/medical-conditions.ts new file mode 100644 index 0000000..6cb4ee9 --- /dev/null +++ b/tauri-app/src/utils/protocols/medical-conditions.ts @@ -0,0 +1,30 @@ +const MedicalConditionsProtocol = { + protocol: "https://pulsepal.com/medical-conditions", + published: true, + types: { + medicalCondition: { + schema: "https://pulsepal.com/medical-conditions/schemas/medical-condition.json", + dataFormats: [ + "application/json" + ] + } + }, + structure: { + medicalCondition: { + $actions: [ + { + who: "anyone", + can: "read" + }, + { + who: "anyone", + can: "write" + } + ] + } + } +} + +export const did = "did:ion:EiAx_twrw3f0yLOv3Pe6pk4gWG4miV9SVXiHe_Q4lMn8Ow:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJkd24tc2lnIiwicHVibGljS2V5SndrIjp7ImNydiI6IkVkMjU1MTkiLCJrdHkiOiJPS1AiLCJ4IjoiV1M1QXFqeDA1V2Z0YWMwYUhYRnpGNV9wZjM2eTVPQ0N0Qy1tM1lCTFo4WSJ9LCJwdXJwb3NlcyI6WyJhdXRoZW50aWNhdGlvbiJdLCJ0eXBlIjoiSnNvbldlYktleTIwMjAifSx7ImlkIjoiZHduLWVuYyIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJpSnpYYkljR0FHdm1QMzd2Z2VfTjB1M3FadllmLWpteGdyM2RTaDUtOE5vIiwieSI6InBBc1BuQ1hLcXlXRWhiS1ZDWjFJejhrWkljVVRXQXBNS2NOS3VtQ3R4T2cifSwicHVycG9zZXMiOlsia2V5QWdyZWVtZW50Il0sInR5cGUiOiJKc29uV2ViS2V5MjAyMCJ9XSwic2VydmljZXMiOlt7ImlkIjoiZHduIiwic2VydmljZUVuZHBvaW50Ijp7ImVuY3J5cHRpb25LZXlzIjpbIiNkd24tZW5jIl0sIm5vZGVzIjpbImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduNSIsImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduMyJdLCJzaWduaW5nS2V5cyI6WyIjZHduLXNpZyJdfSwidHlwZSI6IkRlY2VudHJhbGl6ZWRXZWJOb2RlIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlBSVIyQWFjQXZFVi16ODgwWHl2eHB4bWMzWDJkbDdYVmcwRHdWTGtfTms0QSJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpRGlvWktVc3cyZ0gzU29Nb0V5T0duVE9NQkZURFhZZ1hFX3Z6am5RU0M5aUEiLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUQzU0JIaEtXXzduUF9QamV1WDcybDRjcXVTMWVPVTBCUk1EcW1vdnFpVGxnIn19" + +export default MedicalConditionsProtocol From 78db4cd9035583a80cabfba8f7950704b03fd2b5 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Thu, 4 Jan 2024 08:54:25 +0000 Subject: [PATCH 002/120] removing some strict checks --- tauri-app/src/stores/useDocuments.ts | 35 ++++++++++++++-------------- tauri-app/src/stores/useRemedy.ts | 1 + tauri-app/src/stores/useWeb5Store.ts | 7 +++--- tauri-app/tsconfig.json | 4 ++-- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/tauri-app/src/stores/useDocuments.ts b/tauri-app/src/stores/useDocuments.ts index 599cdd4..5a8ab1c 100644 --- a/tauri-app/src/stores/useDocuments.ts +++ b/tauri-app/src/stores/useDocuments.ts @@ -34,6 +34,7 @@ export function useDocuments(web5: Web5, did: string) { filter: { schema: "https://schema.org/DigitalDocument", }, + // @ts-ignore dateSort: "createdAscending", }, }); @@ -67,23 +68,23 @@ export function useDocuments(web5: Web5, did: string) { console.log(res.records) return [] - const { records } = await web5.dwn.records.query({ - from: MedicalConditionsProtocolDID, - message: { - filter: { - protocolPath: 'medicalCondition', - schema: MedicalConditionsProtocol.types.medicalCondition.schema, - }, - dateSort: "createdAscending", - }, - }); - if (!records) return false - - const fetchedRecords = await Promise.allSettled(records.map(record => record.data.json())) - .then(results => results - .filter(result => result.status === 'fulfilled') - .map(result => result.value)) - return fetchedRecords + // const { records } = await web5.dwn.records.query({ + // from: MedicalConditionsProtocolDID, + // message: { + // filter: { + // protocolPath: 'medicalCondition', + // schema: MedicalConditionsProtocol.types.medicalCondition.schema, + // }, + // dateSort: "createdAscending", + // }, + // }); + // if (!records) return false + // + // const fetchedRecords = await Promise.allSettled(records.map(record => record.data.json())) + // .then(results => results + // .filter(result => result.status === 'fulfilled') + // .map(result => result.value)) + // return fetchedRecords } async function createDocument({ name, file, condition }: { name: string | undefined, file: File, condition: string }): Promise { diff --git a/tauri-app/src/stores/useRemedy.ts b/tauri-app/src/stores/useRemedy.ts index 852cebd..3c4b4f5 100644 --- a/tauri-app/src/stores/useRemedy.ts +++ b/tauri-app/src/stores/useRemedy.ts @@ -35,6 +35,7 @@ export function useRemedies(web5: Web5) { filter: { schema: "https://schema.org/Collection", }, + // @ts-ignore dateSort: "createdAscending", }, }); diff --git a/tauri-app/src/stores/useWeb5Store.ts b/tauri-app/src/stores/useWeb5Store.ts index 0dcdf84..f7da3bd 100644 --- a/tauri-app/src/stores/useWeb5Store.ts +++ b/tauri-app/src/stores/useWeb5Store.ts @@ -21,10 +21,11 @@ const useWeb5Store = create((set, get) => ({ try { // Connect to Web5 const { web5, did } = await Web5.connect({ - techPreview: { - dwnEndpoints: [], - }, + // techPreview: { + // dwnEndpoints: [], + // }, // sync: "1000", + sync: "5s", }); // Set the Web5 instance and DID diff --git a/tauri-app/tsconfig.json b/tauri-app/tsconfig.json index 4a83aa7..22b1db8 100644 --- a/tauri-app/tsconfig.json +++ b/tauri-app/tsconfig.json @@ -16,8 +16,8 @@ /* Linting */ "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, + // "noUnusedLocals": true, + // "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "baseUrl": ".", From bf21238d725de95278b8858976cb08ebf85fe589 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Thu, 4 Jan 2024 11:42:12 +0000 Subject: [PATCH 003/120] added a bit more logs --- tauri-app/src/stores/useDocuments.ts | 62 ++++++++----------- tauri-app/src/stores/useWeb5Store.ts | 22 +++++-- .../{medical-conditions.ts => conditions.ts} | 12 ++-- 3 files changed, 47 insertions(+), 49 deletions(-) rename tauri-app/src/utils/protocols/{medical-conditions.ts => conditions.ts} (85%) diff --git a/tauri-app/src/stores/useDocuments.ts b/tauri-app/src/stores/useDocuments.ts index 5a8ab1c..3864381 100644 --- a/tauri-app/src/stores/useDocuments.ts +++ b/tauri-app/src/stores/useDocuments.ts @@ -1,7 +1,7 @@ import { Web5, Record as Web5Record } from '@web5/api'; import { useState, useEffect } from 'react'; import { schemaOrgProtocolDefinition } from './useWeb5Store'; -import MedicalConditionsProtocol, { did as MedicalConditionsProtocolDID } from '@/utils/protocols/medical-conditions'; +import ConditionsProtocol, { did as ConditionsProtocolDID } from '@/utils/protocols/conditions'; import _ from "lodash" export type DigitalDocument = { @@ -54,37 +54,24 @@ export function useDocuments(web5: Web5, did: string) { } async function fetchDocumentsWithCondition(condition: string) { - - const res = await web5.dwn.records.query({ - from: MedicalConditionsProtocolDID, + const { records } = await web5.dwn.records.query({ + from: ConditionsProtocolDID, message: { filter: { - protocolPath: 'medicalCondition', - schema: MedicalConditionsProtocol.types.medicalCondition.schema, + protocolPath: 'condition', + schema: ConditionsProtocol.types.condition.schema, }, + dateSort: "createdAscending", }, }); - console.log(res) - console.log(res.records) - - return [] - // const { records } = await web5.dwn.records.query({ - // from: MedicalConditionsProtocolDID, - // message: { - // filter: { - // protocolPath: 'medicalCondition', - // schema: MedicalConditionsProtocol.types.medicalCondition.schema, - // }, - // dateSort: "createdAscending", - // }, - // }); - // if (!records) return false - // - // const fetchedRecords = await Promise.allSettled(records.map(record => record.data.json())) - // .then(results => results - // .filter(result => result.status === 'fulfilled') - // .map(result => result.value)) - // return fetchedRecords + if (!records) return false + + const fetchedRecords = await Promise.allSettled(records.map(record => record.data.json())) + .then(results => results + .filter(result => result.status === 'fulfilled') + .map(result => result.value)) + + return fetchedRecords } async function createDocument({ name, file, condition }: { name: string | undefined, file: File, condition: string }): Promise { @@ -119,27 +106,28 @@ export function useDocuments(web5: Web5, did: string) { if (!record) return false; - const { record: medicalConditionRecord, status } = await web5.dwn.records.create({ + const { record: conditionRecord, status } = await web5.dwn.records.create({ data: { condition, did }, message: { - protocol: MedicalConditionsProtocol.protocol, - protocolPath: 'medicalCondition', - schema: MedicalConditionsProtocol.types.medicalCondition.schema, - dataFormat: MedicalConditionsProtocol.types.medicalCondition.dataFormats[0], + protocol: ConditionsProtocol.protocol, + protocolPath: 'condition', + schema: ConditionsProtocol.types.condition.schema, + dataFormat: ConditionsProtocol.types.condition.dataFormats[0], } }) console.log(status) - console.log(medicalConditionRecord) - if (!medicalConditionRecord) return false + console.log(conditionRecord) + if (!conditionRecord) return false - await medicalConditionRecord.send(MedicalConditionsProtocolDID) + await conditionRecord.send(ConditionsProtocolDID) console.log('sent to pulsepal dwn') - await medicalConditionRecord.send(did) - console.log('sent to user dwn') + + // await conditionRecord.send(did) + // console.log('sent to user dwn') const data = await record.data.json(); const doc = { record, data, id: record.id }; diff --git a/tauri-app/src/stores/useWeb5Store.ts b/tauri-app/src/stores/useWeb5Store.ts index f7da3bd..9f0a7a9 100644 --- a/tauri-app/src/stores/useWeb5Store.ts +++ b/tauri-app/src/stores/useWeb5Store.ts @@ -1,6 +1,6 @@ import { Web5 } from "@web5/api/browser"; import { create } from "zustand"; -import MedicalConditionsProtocol from "@/utils/protocols/medical-conditions"; +import ConditionsProtocol from "@/utils/protocols/conditions"; interface Web5State { web5: Web5 | null; @@ -27,6 +27,7 @@ const useWeb5Store = create((set, get) => ({ // sync: "1000", sync: "5s", }); + console.log("did:", did) // Set the Web5 instance and DID set({ web5, did }); @@ -59,20 +60,29 @@ const useWeb5Store = create((set, get) => ({ } if (protocols.length > 0) { - console.log("protocol already exists:", await protocols[0]) + console.log("protocol already exists:", p.protocol) continue } + console.log("Configuring protocol:", p.protocol) // configure protocol on local DWN - const { protocol } = await web5.dwn.protocols.configure({ + const { protocol, status: protocolConfigurationStatus } = await web5.dwn.protocols.configure({ message: { definition: p, }, }); - // console.log("configure protocol local status", configureStatus); + if (!protocol) { + console.log("Failed to configure protocol:", p.protocol) + console.log(protocolConfigurationStatus) + continue + } + + console.log("configured protocol:", protocol); // configure protocol on remote DWN, because sync may not have occured yet - await protocol!.send(did); + console.log("sending protocol to remote DWN...") + const protocolSendStatus = await protocol.send(did); + console.log("sent protocol to remote DWN:", protocolSendStatus); // console.log("configure protocol remote status", remoteConfigureStatus); } }, @@ -192,4 +202,4 @@ export const schemaOrgProtocolDefinition = { }, }; -const protocols = [schemaOrgProtocolDefinition, MedicalConditionsProtocol]; +const protocols = [schemaOrgProtocolDefinition, ConditionsProtocol]; diff --git a/tauri-app/src/utils/protocols/medical-conditions.ts b/tauri-app/src/utils/protocols/conditions.ts similarity index 85% rename from tauri-app/src/utils/protocols/medical-conditions.ts rename to tauri-app/src/utils/protocols/conditions.ts index 6cb4ee9..d1a41d4 100644 --- a/tauri-app/src/utils/protocols/medical-conditions.ts +++ b/tauri-app/src/utils/protocols/conditions.ts @@ -1,16 +1,16 @@ -const MedicalConditionsProtocol = { - protocol: "https://pulsepal.com/medical-conditions", +const ConditionsProtocol = { + protocol: "https://dschema.org/conditions", published: true, types: { - medicalCondition: { - schema: "https://pulsepal.com/medical-conditions/schemas/medical-condition.json", + condition: { + schema: "https://schema.org/conditions/schemas/condition.json", dataFormats: [ "application/json" ] } }, structure: { - medicalCondition: { + condition: { $actions: [ { who: "anyone", @@ -27,4 +27,4 @@ const MedicalConditionsProtocol = { export const did = "did:ion:EiAx_twrw3f0yLOv3Pe6pk4gWG4miV9SVXiHe_Q4lMn8Ow:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJkd24tc2lnIiwicHVibGljS2V5SndrIjp7ImNydiI6IkVkMjU1MTkiLCJrdHkiOiJPS1AiLCJ4IjoiV1M1QXFqeDA1V2Z0YWMwYUhYRnpGNV9wZjM2eTVPQ0N0Qy1tM1lCTFo4WSJ9LCJwdXJwb3NlcyI6WyJhdXRoZW50aWNhdGlvbiJdLCJ0eXBlIjoiSnNvbldlYktleTIwMjAifSx7ImlkIjoiZHduLWVuYyIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJpSnpYYkljR0FHdm1QMzd2Z2VfTjB1M3FadllmLWpteGdyM2RTaDUtOE5vIiwieSI6InBBc1BuQ1hLcXlXRWhiS1ZDWjFJejhrWkljVVRXQXBNS2NOS3VtQ3R4T2cifSwicHVycG9zZXMiOlsia2V5QWdyZWVtZW50Il0sInR5cGUiOiJKc29uV2ViS2V5MjAyMCJ9XSwic2VydmljZXMiOlt7ImlkIjoiZHduIiwic2VydmljZUVuZHBvaW50Ijp7ImVuY3J5cHRpb25LZXlzIjpbIiNkd24tZW5jIl0sIm5vZGVzIjpbImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduNSIsImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduMyJdLCJzaWduaW5nS2V5cyI6WyIjZHduLXNpZyJdfSwidHlwZSI6IkRlY2VudHJhbGl6ZWRXZWJOb2RlIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlBSVIyQWFjQXZFVi16ODgwWHl2eHB4bWMzWDJkbDdYVmcwRHdWTGtfTms0QSJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpRGlvWktVc3cyZ0gzU29Nb0V5T0duVE9NQkZURFhZZ1hFX3Z6am5RU0M5aUEiLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUQzU0JIaEtXXzduUF9QamV1WDcybDRjcXVTMWVPVTBCUk1EcW1vdnFpVGxnIn19" -export default MedicalConditionsProtocol +export default ConditionsProtocol From 7045a72a826a515252cc56cbaf4a0608df9410ec Mon Sep 17 00:00:00 2001 From: Adophilus Date: Thu, 4 Jan 2024 12:08:27 +0000 Subject: [PATCH 004/120] set some dummy conditions --- tauri-app/src/pages/medic.tsx | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tauri-app/src/pages/medic.tsx b/tauri-app/src/pages/medic.tsx index 40ed80e..0d8e9e2 100644 --- a/tauri-app/src/pages/medic.tsx +++ b/tauri-app/src/pages/medic.tsx @@ -2,6 +2,15 @@ import { FunctionComponent, useEffect, useRef, useState } from "react"; import useWeb5Store, { schemaOrgProtocolDefinition } from "@/stores/useWeb5Store"; import { useDocuments } from "@/stores/useDocuments"; +const possibleConditions = [ + "Cancer", + "Diabetes", + "Heart Disease", + "High Blood Pressure", + "High Cholesterol", + "Mental Illness", +] + const MedicPage: FunctionComponent = () => { const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })) const { fetchDocuments, documents, createDocument, getDocumentFile } = useDocuments(web5, did) @@ -51,7 +60,6 @@ const MedicPage: FunctionComponent = () => { const saveMedicalRecord = async () => { const res = await createDocument({ name: form.name ? form.name : undefined, file: form.doc, condition: form.condition }) - // console.log(res) if (res) { alert(`Medical record saved: ${res}`) } @@ -93,15 +101,18 @@ const MedicPage: FunctionComponent = () => { placeholder="Document" />
- { setForm({ ...form, - condition: e.target.value.toLowerCase() + condition: e.target.value }) - }} - placeholder="Condition" /> + }}> + {possibleConditions.map((condition) => ( + + ))} +
+

+ *ensure inputted information are correct as once saved it cannot be + deleted/edited +

+ + + ); +}; + +export default index; diff --git a/tauri-app/src/components/MobileNavbar/index.tsx b/tauri-app/src/components/MobileNavbar/index.tsx index 5fd1e7a..8fd49dd 100644 --- a/tauri-app/src/components/MobileNavbar/index.tsx +++ b/tauri-app/src/components/MobileNavbar/index.tsx @@ -17,11 +17,13 @@ const index = () => { 35 -
- - 28 -

Chats

-
+ +
+ + 28 +

Chats

+
+
diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index e7b716a..306f248 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -22,11 +22,13 @@ const index = () => { 28
-
- -

Chats

- 5 -
+ +
+ +

Chats

+ 5 +
+
diff --git a/tauri-app/src/index.css b/tauri-app/src/index.css index de785d5..0b0b566 100644 --- a/tauri-app/src/index.css +++ b/tauri-app/src/index.css @@ -6,7 +6,7 @@ --color-blue: #0ea5e9; --box-shadow-blue: 0 5px 12px rgba(14, 165, 233, 0.3); --box-shadow-black: 0 3px 12px rgba(0, 0, 0, 0.2); - + --color-slate-accent: #f1f5f9; --color-white: #fff; --color-black: #000; --color-slate: #e2e8f0; diff --git a/tauri-app/src/pages/Chat/FindFriends/index.css b/tauri-app/src/pages/Chat/FindFriends/index.css new file mode 100644 index 0000000..e69de29 diff --git a/tauri-app/src/pages/Chat/FindFriends/index.tsx b/tauri-app/src/pages/Chat/FindFriends/index.tsx new file mode 100644 index 0000000..e69de29 diff --git a/tauri-app/src/pages/Chat/index.css b/tauri-app/src/pages/Chat/index.css new file mode 100644 index 0000000..e69de29 diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx new file mode 100644 index 0000000..7a3fff2 --- /dev/null +++ b/tauri-app/src/pages/Chat/index.tsx @@ -0,0 +1,12 @@ +import "./index.css"; +import { FC } from "react"; + +const index: FC = () => { + return ( +
+

Chat Page

+
+ ); +}; + +export default index; diff --git a/tauri-app/src/pages/Records/index.tsx b/tauri-app/src/pages/Records/index.tsx index b2e39a2..9a61790 100644 --- a/tauri-app/src/pages/Records/index.tsx +++ b/tauri-app/src/pages/Records/index.tsx @@ -64,7 +64,6 @@ const index = () => {

Records

-
{ const [remedies, setRemedies] = useState([ { @@ -52,7 +54,6 @@ const index = () => { const [isRated, setIsRated] = useState(false); const Rate = () => { - console.log(activeRemedy); if (!isRated) { setActiveRemedy({ ...activeRemedy, @@ -65,12 +66,24 @@ const index = () => { }); } setIsRated(!isRated); - console.log(activeRemedy); }; + const [isAddRemedyActive, setIsAddRemedyActive] = useState(false); + return (
-

Get a quick fix!

+
+

Get a quick Fix!

+
setIsAddRemedyActive(!isAddRemedyActive)} + > + +
+
+
{remedies.map((remedy) => { return ( @@ -142,6 +155,15 @@ const index = () => {
)} + + {isAddRemedyActive && ( +
+ +
+ )}
); }; From 0738b6ca886d618801c684d4f28be42ab2f32e1c Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Fri, 5 Jan 2024 00:18:09 +0100 Subject: [PATCH 011/120] contact page added --- tauri-app/src/App.tsx | 2 + tauri-app/src/pages/Chat/index.tsx | 3 +- tauri-app/src/pages/Contact/index.css | 83 ++++++++++++++++++++++++++ tauri-app/src/pages/Contact/index.tsx | 79 ++++++++++++++++++++++++ tauri-app/src/pages/Remedies/index.css | 2 +- 5 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 tauri-app/src/pages/Contact/index.css create mode 100644 tauri-app/src/pages/Contact/index.tsx diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 07c359f..043b4b3 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -11,6 +11,7 @@ import SharedLayout from "./pages/SharedLayout/"; import Records from "./pages/Records"; import Remedies from "./pages/Remedies"; import Chat from "./pages/Chat/"; +import Contact from "./pages/Contact/"; const router = createHashRouter([ { @@ -25,6 +26,7 @@ const router = createHashRouter([ { path: "/medic", element: }, { path: "/nearbyDoctors", element: }, { path: "/chat", element: }, + { path: "/contact", element: }, ], }, ]); diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index 7a3fff2..ab8d90e 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -1,7 +1,6 @@ import "./index.css"; -import { FC } from "react"; -const index: FC = () => { +const index= () => { return (

Chat Page

diff --git a/tauri-app/src/pages/Contact/index.css b/tauri-app/src/pages/Contact/index.css new file mode 100644 index 0000000..32b3cf2 --- /dev/null +++ b/tauri-app/src/pages/Contact/index.css @@ -0,0 +1,83 @@ +.row-container { + display: flex; + justify-content: space-between; + align-items: center; + width: 70%; + + box-shadow: var(--box-shadow-black); + border-radius: 8px; + margin: 20px auto; + font-family: "Open Sans"; +} + +.row-container div { + padding: 10px 14px; + width: 100px; + border-radius: 15px; + margin: 10px; + text-align: center; +} + +.row-container div:nth-child(2) { + background: var(--color-green); + color: var(--color-white); + box-shadow: var(--box-shadow-green); +} + +.row-container div:nth-child(4) { + background: var(--color-red); + color: var(--color-white); + box-shadow: var(--box-shadow-red); +} + +.locate-container { + padding: var(--padding-desktop); +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.header h1 { + font-family: "Pacifico"; + margin: auto 0; +} + +.header button { + width: 150px; + border-radius: 50px; + background: var(--color-blue); + color: var(--color-white); + border: none; + outline: none; + font-size: 28px; + font-family: "Pacifico"; + padding: 8px 20px; + box-shadow: var(--box-shadow-blue); +} + +@media (max-width: 750px) { + .locate-container { + padding: var(--padding-mobile); + } + + .header { + flex-direction: column; + justify-content: center; + } + + .header button { + margin-top: 20px; + } + + .row-container { + width: 100%; + flex-direction: column; + } + + .row-container div { + width: 80%; + } +} diff --git a/tauri-app/src/pages/Contact/index.tsx b/tauri-app/src/pages/Contact/index.tsx new file mode 100644 index 0000000..ca84645 --- /dev/null +++ b/tauri-app/src/pages/Contact/index.tsx @@ -0,0 +1,79 @@ +import "./index.css"; +import React, { FC, useState } from "react"; + +interface RowProp { + name: String; + address: String; + city: String; + distance: Number; +} + +const RowComponent: FC = ({ name, address, city, distance }) => { + return ( +
+
+

{name}

+
+
+

{address}

+
+
+

{city}

+
+
+

{distance}

+
+
+ ); +}; + +const index: FC = () => { + const [fetchedLocations, setFetchedLocations] = useState([ + { + name: "Hopsital", + address: "No 4 Dress road", + city: "Kumkubaga", + distance: 47, + }, + { + name: "Hopsital", + address: "No 4 Dress road", + city: "Kumkubaga", + distance: 47, + }, + { + name: "Hopsital", + address: "No 4 Dress road", + city: "Kumkubaga", + distance: 47, + }, + ]); + return ( +
+
+

Find Hospitals/Drs. Near You.

+ +
+
+ + {fetchedLocations.map((location) => { + return ( + + ); + })} +
+
+ ); +}; + +export default index; diff --git a/tauri-app/src/pages/Remedies/index.css b/tauri-app/src/pages/Remedies/index.css index 229b2ca..62df5a5 100644 --- a/tauri-app/src/pages/Remedies/index.css +++ b/tauri-app/src/pages/Remedies/index.css @@ -138,7 +138,7 @@ } .remedy-main-info-container { - height: 300px; + min-height: 300px; overflow-y: scroll; padding: 5px; border-radius: 5px; From 606f81b25bcd17a8076c0c39f9947c672985d324 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 02:30:22 +0000 Subject: [PATCH 012/120] added the server --- server/.gitignore | 146 +++++++++++++++++++++++++++++++++++++++ server/package.json | 18 +++++ server/server.ts | 9 +++ server/src/app.ts | 31 +++++++++ server/src/middleware.ts | 22 ++++++ server/src/utils.ts | 84 ++++++++++++++++++++++ server/tsconfig.json | 19 +++++ 7 files changed, 329 insertions(+) create mode 100644 server/.gitignore create mode 100644 server/package.json create mode 100644 server/server.ts create mode 100644 server/src/app.ts create mode 100644 server/src/middleware.ts create mode 100644 server/src/utils.ts create mode 100644 server/tsconfig.json diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..5b81ddf --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,146 @@ +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/node + +DATA/ diff --git a/server/package.json b/server/package.json new file mode 100644 index 0000000..ce20a8d --- /dev/null +++ b/server/package.json @@ -0,0 +1,18 @@ +{ + "scripts": { + "dev": "tsx --watch server.ts" + }, + "dependencies": { + "@hono/node-server": "^1.4.0", + "@hono/zod-validator": "^0.1.11", + "@web5/api": "^0.8.3", + "hono": "^3.12.0", + "true-myth": "5", + "tsconfig-paths": "^4.2.0", + "zod": "^3.22.4" + }, + "devDependencies": { + "tsx": "^4.7.0", + "typescript": "^5.3.3" + } +} diff --git a/server/server.ts b/server/server.ts new file mode 100644 index 0000000..f321b00 --- /dev/null +++ b/server/server.ts @@ -0,0 +1,9 @@ +import app from "./src/app"; +import { serve } from '@hono/node-server' + +serve({ + fetch: app.fetch, + port: process.env.PORT || 5000, +}, (addr) => { + console.log("Server running on port:", addr.port) +}) diff --git a/server/src/app.ts b/server/src/app.ts new file mode 100644 index 0000000..82f695f --- /dev/null +++ b/server/src/app.ts @@ -0,0 +1,31 @@ +import { Hono } from "hono"; +import { fetchConditions } from "./utils"; +import { agentMiddleware } from "./middleware"; +import { zValidator } from '@hono/zod-validator' +import { z } from 'zod' +import { logger } from "hono/logger" +import { cors } from 'hono/cors' + +const app = new Hono() + .basePath("/api") + .use("*", cors()) + .use("*", logger()) + .get("/conditions", + zValidator( + 'query', + z.object({ + condition: z.string() + })), + agentMiddleware, async (c) => { + const { condition } = c.req.valid("query") + const res = await fetchConditions(c.get("agent")) + if (res.isErr) + return c.json({ error: res.error }) + + const conditions = res.value.filter(record => record.condition === condition) + return c.json(conditions) + }) + +export type App = typeof app + +export default app diff --git a/server/src/middleware.ts b/server/src/middleware.ts new file mode 100644 index 0000000..e6503bc --- /dev/null +++ b/server/src/middleware.ts @@ -0,0 +1,22 @@ +import { type Agent, configureProtocol, setupAgent } from "./utils"; +import { MiddlewareHandler } from "hono" + +let agent: Agent + +export const agentMiddleware: MiddlewareHandler<{ + Variables: { + agent: Agent + } +}> = async (c, next) => { + if (!agent) + agent = await setupAgent() + + const connectionResult = await configureProtocol(agent) + if (connectionResult.isErr) { + console.log(connectionResult.error) + process.exit() + } + + c.set('agent', agent) + await next() +} diff --git a/server/src/utils.ts b/server/src/utils.ts new file mode 100644 index 0000000..6460426 --- /dev/null +++ b/server/src/utils.ts @@ -0,0 +1,84 @@ +import { Web5 } from "@web5/api"; +import ConditionsProtocol, { type Record, did as ConditionsProtocolDID } from "@frontend/utils/protocols/conditions" +import Result, { ok, err } from "true-myth/result" + +export type Agent = { + web5: Web5, + did: string +} + +export type Status = { + code: number, + detail: string, +} + +export async function configureProtocol(agent: Agent): Promise> { + const { protocols } = await agent.web5.dwn.protocols.query({ + message: { + filter: { + protocol: ConditionsProtocol.protocol, + } + } + }) + + if (protocols.length > 0) + return ok(undefined) + + const { protocol, status: localProtocolConfigurationStatus } = await agent.web5.dwn.protocols.configure({ + message: { + definition: ConditionsProtocol, + } + }); + + if (!protocol) + return err({ + type: "LOCAL_PROTOCOL_CONFIGURATION_FAILED", + status: localProtocolConfigurationStatus, + }) + + const { status: remoteProtocolConfigurationStatus } = await protocol.send(ConditionsProtocolDID) + + if (remoteProtocolConfigurationStatus.code !== 202) + return err({ + type: "REMOTE_PROTOCOL_CONFIGURATION_FAILED", + status: remoteProtocolConfigurationStatus, + }) + + return ok(undefined) +} + +export async function fetchConditions(agent: Agent): Promise> { + const { records, status } = await agent.web5.dwn.records.query({ + from: ConditionsProtocolDID, + message: { + filter: { + protocolPath: 'condition', + schema: ConditionsProtocol.types.condition.schema, + protocol: ConditionsProtocol.protocol, + }, + dateSort: "createdAscending", + } + }) + + if (!records) { + if (status.code !== 200) + return err(status) + + return ok([]) + } + + const conditions: Record.Condition[] = [] + for (const record of records) { + conditions.push(await record.data.json()) + } + + return ok(conditions) +} + +export async function setupAgent(): Promise { + const { web5, did } = await Web5.connect({ + sync: "5s", + }); + + return { web5, did } +} diff --git a/server/tsconfig.json b/server/tsconfig.json new file mode 100644 index 0000000..3cb9101 --- /dev/null +++ b/server/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "composite": true, + "noEmit": true + }, + "include": [ + "server.ts", + "./src/**/*.ts" + ], + "exclude": [ + "node_modules" + ], + "references": [ + { + "path": "../tsconfig.json" + } + ], + "extends": "../tsconfig.json" +} From 6e48466e369f6cf3b9d2db22ebfe971d269e2aed Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 02:31:23 +0000 Subject: [PATCH 013/120] updated the types to work with the backend --- .gitignore | 2 + tauri-app/package.json | 1 + tauri-app/src/pages/connect.tsx | 133 +++++++++++--------- tauri-app/src/pages/medic.tsx | 5 +- tauri-app/src/utils/protocols/conditions.ts | 7 ++ tauri-app/tsconfig.json | 29 +++-- tauri-app/vite.config.ts | 3 + tsconfig.json | 42 +++++++ 8 files changed, 154 insertions(+), 68 deletions(-) create mode 100644 .gitignore create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..649ac14 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +pnpm-lock.yaml +*.tsbuildinfo diff --git a/tauri-app/package.json b/tauri-app/package.json index 7b4e845..be51e78 100644 --- a/tauri-app/package.json +++ b/tauri-app/package.json @@ -21,6 +21,7 @@ "axios": "^1.6.3", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", + "hono": "^3.12.0", "lodash": "^4.17.21", "lucide-react": "^0.298.0", "react": "^18.2.0", diff --git a/tauri-app/src/pages/connect.tsx b/tauri-app/src/pages/connect.tsx index e6f9ec4..31b8dc9 100644 --- a/tauri-app/src/pages/connect.tsx +++ b/tauri-app/src/pages/connect.tsx @@ -1,65 +1,86 @@ -import useWeb5Store, { schemaOrgProtocolDefinition } from "@/stores/useWeb5Store"; -import { useDocuments } from "@/stores/useDocuments"; -import { useEffect, useState } from "react"; +import useWeb5Store from "@/stores/useWeb5Store"; +import { useState } from "react"; +import { hc } from "hono/client" +import { App } from "@backend/app" -function Connect() { - const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })) - const { fetchDocumentsWithCondition } = useDocuments(web5, did) - const [similarConditions, setSimilarConditions] = useState<{ did: string, condition: string }[]>([]) - const [form, setForm] = useState<{ - condition: string - }>({ - condition: "" - }) +const backendClient = hc("/") + +const possibleConditions = [ + "Cancer", + "Diabetes", + "Heart Disease", + "High Blood Pressure", + "High Cholesterol", + "Mental Illness", +] - useEffect(() => { - fetchDocumentsWithCondition("cancer") - }, []) +function Connect() { + const [similarConditions, setSimilarConditions] = useState<{ did: string, condition: string }[]>([]) + const [form, setForm] = useState({ condition: "" }) - const connectCondition = async () => { - const res = await fetchDocumentsWithCondition(form.condition) - console.log(res) - if (res) - setSimilarConditions(res) - } + const fetchDocumentsWithCondition = async (condition: string) => { + const maybeConditions = await backendClient.api.conditions.$get({ + query: { + condition + } + }) + .then(res => res.json()) + if (!Array.isArray(maybeConditions)) + return [] + const conditions = maybeConditions + return conditions + } + const connectCondition = async () => { + const res = await fetchDocumentsWithCondition(form.condition) + setSimilarConditions(res) + } - return ( - <> -
-
{ - e.preventDefault() - connectCondition() - }}> - { - setForm({ ...form, condition: e.target.value }) - }} - placeholder="Condition" /> - -
-
-
-
- People with similar conditions: -
-
- {similarConditions.map((condition, index) => ( -
-
- {condition.did} -
-
- {condition.condition} -
-
- ))} -
+ return ( + <> +
+
{ + e.preventDefault() + connectCondition() + }}> +
+ +
+ +
+
+
+
+ People with similar conditions: +
+
+ {similarConditions.map((condition, index) => ( +
+
+ {condition.did} +
+
+ {condition.condition} +
- - ) + ))} +
+
+ + ) } export default Connect; diff --git a/tauri-app/src/pages/medic.tsx b/tauri-app/src/pages/medic.tsx index 0d8e9e2..9ae13ff 100644 --- a/tauri-app/src/pages/medic.tsx +++ b/tauri-app/src/pages/medic.tsx @@ -1,5 +1,5 @@ -import { FunctionComponent, useEffect, useRef, useState } from "react"; -import useWeb5Store, { schemaOrgProtocolDefinition } from "@/stores/useWeb5Store"; +import { FunctionComponent, useEffect, useState } from "react"; +import useWeb5Store from "@/stores/useWeb5Store"; import { useDocuments } from "@/stores/useDocuments"; const possibleConditions = [ @@ -58,6 +58,7 @@ const MedicPage: FunctionComponent = () => { }, [documents]) const saveMedicalRecord = async () => { + console.log(form) const res = await createDocument({ name: form.name ? form.name : undefined, file: form.doc, condition: form.condition }) if (res) { diff --git a/tauri-app/src/utils/protocols/conditions.ts b/tauri-app/src/utils/protocols/conditions.ts index d1a41d4..5ffae94 100644 --- a/tauri-app/src/utils/protocols/conditions.ts +++ b/tauri-app/src/utils/protocols/conditions.ts @@ -25,6 +25,13 @@ const ConditionsProtocol = { } } +export namespace Record { + export type Condition = { + did: string + condition: string + } +} + export const did = "did:ion:EiAx_twrw3f0yLOv3Pe6pk4gWG4miV9SVXiHe_Q4lMn8Ow:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJkd24tc2lnIiwicHVibGljS2V5SndrIjp7ImNydiI6IkVkMjU1MTkiLCJrdHkiOiJPS1AiLCJ4IjoiV1M1QXFqeDA1V2Z0YWMwYUhYRnpGNV9wZjM2eTVPQ0N0Qy1tM1lCTFo4WSJ9LCJwdXJwb3NlcyI6WyJhdXRoZW50aWNhdGlvbiJdLCJ0eXBlIjoiSnNvbldlYktleTIwMjAifSx7ImlkIjoiZHduLWVuYyIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJpSnpYYkljR0FHdm1QMzd2Z2VfTjB1M3FadllmLWpteGdyM2RTaDUtOE5vIiwieSI6InBBc1BuQ1hLcXlXRWhiS1ZDWjFJejhrWkljVVRXQXBNS2NOS3VtQ3R4T2cifSwicHVycG9zZXMiOlsia2V5QWdyZWVtZW50Il0sInR5cGUiOiJKc29uV2ViS2V5MjAyMCJ9XSwic2VydmljZXMiOlt7ImlkIjoiZHduIiwic2VydmljZUVuZHBvaW50Ijp7ImVuY3J5cHRpb25LZXlzIjpbIiNkd24tZW5jIl0sIm5vZGVzIjpbImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduNSIsImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduMyJdLCJzaWduaW5nS2V5cyI6WyIjZHduLXNpZyJdfSwidHlwZSI6IkRlY2VudHJhbGl6ZWRXZWJOb2RlIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlBSVIyQWFjQXZFVi16ODgwWHl2eHB4bWMzWDJkbDdYVmcwRHdWTGtfTms0QSJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpRGlvWktVc3cyZ0gzU29Nb0V5T0duVE9NQkZURFhZZ1hFX3Z6am5RU0M5aUEiLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUQzU0JIaEtXXzduUF9QamV1WDcybDRjcXVTMWVPVTBCUk1EcW1vdnFpVGxnIn19" export default ConditionsProtocol diff --git a/tauri-app/tsconfig.json b/tauri-app/tsconfig.json index 22b1db8..27ffeda 100644 --- a/tauri-app/tsconfig.json +++ b/tauri-app/tsconfig.json @@ -1,11 +1,15 @@ { "compilerOptions": { + "composite": true, "target": "ES2020", "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": [ + "ES2020", + "DOM", + "DOM.Iterable" + ], "module": "ESNext", "skipLibCheck": true, - /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, @@ -13,18 +17,23 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", - /* Linting */ "strict": true, // "noUnusedLocals": true, // "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"] - } + "outDir": "./build" }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + "include": [ + "./src/**/*.ts" + ], + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "../tsconfig.json" + } + ], + "extends": "../tsconfig.json" } diff --git a/tauri-app/vite.config.ts b/tauri-app/vite.config.ts index d54908f..4cb61b7 100644 --- a/tauri-app/vite.config.ts +++ b/tauri-app/vite.config.ts @@ -19,6 +19,9 @@ export default defineConfig(async () => ({ server: { port: 1420, strictPort: true, + proxy: { + "/api": "http://127.0.0.1:5000/" + }, watch: { // 3. tell vite to ignore watching `src-tauri` ignored: ["**/src-tauri/**"], diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6b70144 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,42 @@ +{ + "compilerOptions": { + "composite": true, + "baseUrl": ".", + "paths": { + "@frontend/*": [ + "./tauri-app/src/*" + ], + "@backend/*": [ + "./server/src/*" + ], + "@/*": [ + "./tauri-app/src/*" + ] + }, + // "noUnusedLocals": true, + // "noUnusedParameters": true, + // "strictFunctionTypes": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "allowUnreachableCode": false, + "target": "ES2020", + "useDefineForClassFields": true, + "lib": [ + "ES2020", + "DOM", + "DOM.Iterable" + ], + "module": "ESNext", + "skipLibCheck": true, + /* Bundler mode */ + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + /* Linting */ + "strict": true, + "noFallthroughCasesInSwitch": true, + "outDir": "./build", + "rootDir": "." + } +} From 99cf8162b299ecf38c32d0f1316045e54831aa12 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 02:36:47 +0000 Subject: [PATCH 014/120] updated protocol --- tauri-app/src/utils/protocols/conditions.ts | 4 +- tauri-app/src/utils/protocols/user-details.ts | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 tauri-app/src/utils/protocols/user-details.ts diff --git a/tauri-app/src/utils/protocols/conditions.ts b/tauri-app/src/utils/protocols/conditions.ts index 5ffae94..e513310 100644 --- a/tauri-app/src/utils/protocols/conditions.ts +++ b/tauri-app/src/utils/protocols/conditions.ts @@ -1,9 +1,9 @@ const ConditionsProtocol = { - protocol: "https://dschema.org/conditions", + protocol: "https://dschema.org/protocols/conditions", published: true, types: { condition: { - schema: "https://schema.org/conditions/schemas/condition.json", + schema: "https://dschema.org/protocols/conditions/schemas/condition.json", dataFormats: [ "application/json" ] diff --git a/tauri-app/src/utils/protocols/user-details.ts b/tauri-app/src/utils/protocols/user-details.ts new file mode 100644 index 0000000..c047683 --- /dev/null +++ b/tauri-app/src/utils/protocols/user-details.ts @@ -0,0 +1,38 @@ +const UserDetailsProtocol = { + protocol: "https://dschema.org/protocols/user", + published: true, + types: { + details: { + schema: "https://dschema.org/protocols/user/schemas/details.json", + dataFormats: [ + "application/json" + ] + } + }, + structure: { + details: { + $actions: [ + { + who: "author", + can: "read" + }, + { + who: "anyone", + can: "write" + } + ] + } + } +} + +export namespace Record { + export type UserDetails = { + firstName: string + lastName: string + profilePictureUrl: string + } +} + +export const did = "did:ion:EiAx_twrw3f0yLOv3Pe6pk4gWG4miV9SVXiHe_Q4lMn8Ow:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJkd24tc2lnIiwicHVibGljS2V5SndrIjp7ImNydiI6IkVkMjU1MTkiLCJrdHkiOiJPS1AiLCJ4IjoiV1M1QXFqeDA1V2Z0YWMwYUhYRnpGNV9wZjM2eTVPQ0N0Qy1tM1lCTFo4WSJ9LCJwdXJwb3NlcyI6WyJhdXRoZW50aWNhdGlvbiJdLCJ0eXBlIjoiSnNvbldlYktleTIwMjAifSx7ImlkIjoiZHduLWVuYyIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJpSnpYYkljR0FHdm1QMzd2Z2VfTjB1M3FadllmLWpteGdyM2RTaDUtOE5vIiwieSI6InBBc1BuQ1hLcXlXRWhiS1ZDWjFJejhrWkljVVRXQXBNS2NOS3VtQ3R4T2cifSwicHVycG9zZXMiOlsia2V5QWdyZWVtZW50Il0sInR5cGUiOiJKc29uV2ViS2V5MjAyMCJ9XSwic2VydmljZXMiOlt7ImlkIjoiZHduIiwic2VydmljZUVuZHBvaW50Ijp7ImVuY3J5cHRpb25LZXlzIjpbIiNkd24tZW5jIl0sIm5vZGVzIjpbImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduNSIsImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduMyJdLCJzaWduaW5nS2V5cyI6WyIjZHduLXNpZyJdfSwidHlwZSI6IkRlY2VudHJhbGl6ZWRXZWJOb2RlIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlBSVIyQWFjQXZFVi16ODgwWHl2eHB4bWMzWDJkbDdYVmcwRHdWTGtfTms0QSJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpRGlvWktVc3cyZ0gzU29Nb0V5T0duVE9NQkZURFhZZ1hFX3Z6am5RU0M5aUEiLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUQzU0JIaEtXXzduUF9QamV1WDcybDRjcXVTMWVPVTBCUk1EcW1vdnFpVGxnIn19" + +export default UserDetailsProtocol From c1c27d70ac8c34dbb7db24d79732aa56e3b58807 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 02:38:20 +0000 Subject: [PATCH 015/120] updated import --- tauri-app/src/stores/useWeb5Store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/stores/useWeb5Store.ts b/tauri-app/src/stores/useWeb5Store.ts index 9f0a7a9..ad26103 100644 --- a/tauri-app/src/stores/useWeb5Store.ts +++ b/tauri-app/src/stores/useWeb5Store.ts @@ -1,4 +1,4 @@ -import { Web5 } from "@web5/api/browser"; +import { Web5 } from "@web5/api"; import { create } from "zustand"; import ConditionsProtocol from "@/utils/protocols/conditions"; From eed78b1fb43e010a7eedea2e7a54e5ad9de041b0 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 02:39:10 +0000 Subject: [PATCH 016/120] renamed protocol file --- tauri-app/src/utils/protocols/{user-details.ts => user.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tauri-app/src/utils/protocols/{user-details.ts => user.ts} (100%) diff --git a/tauri-app/src/utils/protocols/user-details.ts b/tauri-app/src/utils/protocols/user.ts similarity index 100% rename from tauri-app/src/utils/protocols/user-details.ts rename to tauri-app/src/utils/protocols/user.ts From 5814cfb877c905d5012a3cc81d7fc5a9c53b44a8 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 03:06:57 +0000 Subject: [PATCH 017/120] updated tsconfigs --- server/tsconfig.json | 20 +++++----- tauri-app/src/utils/document.ts | 0 tauri-app/src/utils/protocols/conditions.ts | 4 +- tauri-app/tsconfig.json | 31 ++++++--------- tsconfig.json | 42 --------------------- 5 files changed, 25 insertions(+), 72 deletions(-) create mode 100644 tauri-app/src/utils/document.ts delete mode 100644 tsconfig.json diff --git a/server/tsconfig.json b/server/tsconfig.json index 3cb9101..b77ecc0 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -1,7 +1,15 @@ { "compilerOptions": { - "composite": true, - "noEmit": true + "noEmit": true, + "strict": false, + "noImplicitAny": true, + "noFallthroughCasesInSwitch": true, + "module": "CommonJS", + "baseUrl": ".", + "paths": { + "@backend/*": ["./src/*"], + "@frontend/*": ["../tauri-app/src/*"] + } }, "include": [ "server.ts", @@ -9,11 +17,5 @@ ], "exclude": [ "node_modules" - ], - "references": [ - { - "path": "../tsconfig.json" - } - ], - "extends": "../tsconfig.json" + ] } diff --git a/tauri-app/src/utils/document.ts b/tauri-app/src/utils/document.ts new file mode 100644 index 0000000..e69de29 diff --git a/tauri-app/src/utils/protocols/conditions.ts b/tauri-app/src/utils/protocols/conditions.ts index e513310..aaf5811 100644 --- a/tauri-app/src/utils/protocols/conditions.ts +++ b/tauri-app/src/utils/protocols/conditions.ts @@ -1,9 +1,9 @@ const ConditionsProtocol = { - protocol: "https://dschema.org/protocols/conditions", + protocol: "https://dschema.org/protocols/condition", published: true, types: { condition: { - schema: "https://dschema.org/protocols/conditions/schemas/condition.json", + schema: "https://dschema.org/protocols/condition/schemas/condition.json", dataFormats: [ "application/json" ] diff --git a/tauri-app/tsconfig.json b/tauri-app/tsconfig.json index 27ffeda..36ff4af 100644 --- a/tauri-app/tsconfig.json +++ b/tauri-app/tsconfig.json @@ -1,15 +1,11 @@ { "compilerOptions": { - "composite": true, "target": "ES2020", "useDefineForClassFields": true, - "lib": [ - "ES2020", - "DOM", - "DOM.Iterable" - ], + "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, + /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, @@ -17,23 +13,20 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", + /* Linting */ "strict": true, // "noUnusedLocals": true, // "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "outDir": "./build" - }, - "include": [ - "./src/**/*.ts" - ], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "../tsconfig.json" + + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"], + "@backend/*": ["../server/src/*"], + "@frontend/*": ["./src/*"] } - ], - "extends": "../tsconfig.json" + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 6b70144..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "baseUrl": ".", - "paths": { - "@frontend/*": [ - "./tauri-app/src/*" - ], - "@backend/*": [ - "./server/src/*" - ], - "@/*": [ - "./tauri-app/src/*" - ] - }, - // "noUnusedLocals": true, - // "noUnusedParameters": true, - // "strictFunctionTypes": true, - "esModuleInterop": true, - "experimentalDecorators": true, - "allowUnreachableCode": false, - "target": "ES2020", - "useDefineForClassFields": true, - "lib": [ - "ES2020", - "DOM", - "DOM.Iterable" - ], - "module": "ESNext", - "skipLibCheck": true, - /* Bundler mode */ - "moduleResolution": "Node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "react-jsx", - /* Linting */ - "strict": true, - "noFallthroughCasesInSwitch": true, - "outDir": "./build", - "rootDir": "." - } -} From e2b754949fa6365da19bad5333c5acc5d83bf4e2 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 03:07:10 +0000 Subject: [PATCH 018/120] updated web5 import --- tauri-app/src/stores/useWeb5Store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/stores/useWeb5Store.ts b/tauri-app/src/stores/useWeb5Store.ts index ad26103..9f0a7a9 100644 --- a/tauri-app/src/stores/useWeb5Store.ts +++ b/tauri-app/src/stores/useWeb5Store.ts @@ -1,4 +1,4 @@ -import { Web5 } from "@web5/api"; +import { Web5 } from "@web5/api/browser"; import { create } from "zustand"; import ConditionsProtocol from "@/utils/protocols/conditions"; From 3b585e511dbc517f6b2c413c9acb2eaf147df3e3 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 03:07:18 +0000 Subject: [PATCH 019/120] defined document protocol --- tauri-app/src/utils/protocols/document.ts | 63 +++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tauri-app/src/utils/protocols/document.ts diff --git a/tauri-app/src/utils/protocols/document.ts b/tauri-app/src/utils/protocols/document.ts new file mode 100644 index 0000000..e4a148b --- /dev/null +++ b/tauri-app/src/utils/protocols/document.ts @@ -0,0 +1,63 @@ +const DocumentProtocol = { + protocol: "https://dschema.org/protocols/document", + published: true, + types: { + document: { + schema: "https://schema.org/protocols/document/schemas/document.json", + dataFormats: [ + "application/json" + ] + }, + blob: { + schema: "https://dschema.org/protocols/document/schemas/blob.json", + dataFormats: [ + "application/json" + ] + } + }, + structure: { + document: { + $actions: [ + { + who: "anyone", + can: "read" + }, + { + who: "author", + can: "write" + } + ] + }, + blob: { + $actions: [ + { + who: "anyone", + can: "read" + }, + { + who: "author", + of: "parentId", + can: "write" + } + ] + } + } +} + +export namespace Record { + export type File = Blob + + export type Document = { + name: string + encodingFormat: string + size: number + url: string + condition: string + dateCreated?: string + dateModified?: string + }; +} + +export const did = "did:ion:EiAx_twrw3f0yLOv3Pe6pk4gWG4miV9SVXiHe_Q4lMn8Ow:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJkd24tc2lnIiwicHVibGljS2V5SndrIjp7ImNydiI6IkVkMjU1MTkiLCJrdHkiOiJPS1AiLCJ4IjoiV1M1QXFqeDA1V2Z0YWMwYUhYRnpGNV9wZjM2eTVPQ0N0Qy1tM1lCTFo4WSJ9LCJwdXJwb3NlcyI6WyJhdXRoZW50aWNhdGlvbiJdLCJ0eXBlIjoiSnNvbldlYktleTIwMjAifSx7ImlkIjoiZHduLWVuYyIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJpSnpYYkljR0FHdm1QMzd2Z2VfTjB1M3FadllmLWpteGdyM2RTaDUtOE5vIiwieSI6InBBc1BuQ1hLcXlXRWhiS1ZDWjFJejhrWkljVVRXQXBNS2NOS3VtQ3R4T2cifSwicHVycG9zZXMiOlsia2V5QWdyZWVtZW50Il0sInR5cGUiOiJKc29uV2ViS2V5MjAyMCJ9XSwic2VydmljZXMiOlt7ImlkIjoiZHduIiwic2VydmljZUVuZHBvaW50Ijp7ImVuY3J5cHRpb25LZXlzIjpbIiNkd24tZW5jIl0sIm5vZGVzIjpbImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduNSIsImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduMyJdLCJzaWduaW5nS2V5cyI6WyIjZHduLXNpZyJdfSwidHlwZSI6IkRlY2VudHJhbGl6ZWRXZWJOb2RlIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlBSVIyQWFjQXZFVi16ODgwWHl2eHB4bWMzWDJkbDdYVmcwRHdWTGtfTms0QSJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpRGlvWktVc3cyZ0gzU29Nb0V5T0duVE9NQkZURFhZZ1hFX3Z6am5RU0M5aUEiLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUQzU0JIaEtXXzduUF9QamV1WDcybDRjcXVTMWVPVTBCUk1EcW1vdnFpVGxnIn19" + +export default DocumentProtocol From 29a01403cffa9e9edae370d8b8b184ba2441143f Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 05:00:38 +0000 Subject: [PATCH 020/120] added some tsignores --- tauri-app/src/stores/useDocuments.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tauri-app/src/stores/useDocuments.ts b/tauri-app/src/stores/useDocuments.ts index 3864381..c6914f7 100644 --- a/tauri-app/src/stores/useDocuments.ts +++ b/tauri-app/src/stores/useDocuments.ts @@ -61,6 +61,7 @@ export function useDocuments(web5: Web5, did: string) { protocolPath: 'condition', schema: ConditionsProtocol.types.condition.schema, }, + // @ts-ignore dateSort: "createdAscending", }, }); @@ -69,6 +70,7 @@ export function useDocuments(web5: Web5, did: string) { const fetchedRecords = await Promise.allSettled(records.map(record => record.data.json())) .then(results => results .filter(result => result.status === 'fulfilled') + // @ts-ignore .map(result => result.value)) return fetchedRecords From 1ed113ca91e6e5f1f0646f67028494d94e1789ef Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 05:00:49 +0000 Subject: [PATCH 021/120] removed checks from package.json --- tauri-app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/package.json b/tauri-app/package.json index be51e78..39b4c47 100644 --- a/tauri-app/package.json +++ b/tauri-app/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc && vite build", + "build": "vite build", "preview": "vite preview", "tauri": "tauri" }, From a61e87658df6e1fc73c030975b229499427a77aa Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Fri, 5 Jan 2024 11:42:04 +0100 Subject: [PATCH 022/120] porting javascript to ttpescript --- .../src/components/AddCardComponent/index.tsx | 14 +++++++--- .../components/AddRemedyComponent/index.tsx | 27 ++++++++++++++----- tauri-app/src/components/Card/index.tsx | 22 ++++++++++++--- .../components/DetailCardComponent/index.tsx | 26 ++++++++++++++++-- tauri-app/src/pages/Contact/index.tsx | 21 ++++++++++----- tauri-app/src/pages/Remedies/index.css | 2 +- 6 files changed, 89 insertions(+), 23 deletions(-) diff --git a/tauri-app/src/components/AddCardComponent/index.tsx b/tauri-app/src/components/AddCardComponent/index.tsx index 66c9bb6..3da12d8 100644 --- a/tauri-app/src/components/AddCardComponent/index.tsx +++ b/tauri-app/src/components/AddCardComponent/index.tsx @@ -1,14 +1,18 @@ import "./index.css"; -import { useState } from "react"; +import React, { useState } from "react"; + +interface FileProp { + file: File | null | undefined; +} const FileUploader = () => { - const [file, setFile] = useState(null); + const [file, setFile] = useState({ file: null }); return (
{ - setFile(e.target.files[0]); + setFile({ file: e?.target?.files?.[0] }); }} type="file" accept=".jpg,.png,.jpeg,.docx,.pdf" @@ -18,7 +22,9 @@ const FileUploader = () => { }; const index = () => { - const [fileUploaders, setUploaderFile] = useState([]); + const [fileUploaders, setUploaderFile] = useState([ + , + ]); return (

Create New Record

diff --git a/tauri-app/src/components/AddRemedyComponent/index.tsx b/tauri-app/src/components/AddRemedyComponent/index.tsx index bdf446a..31d8dc4 100644 --- a/tauri-app/src/components/AddRemedyComponent/index.tsx +++ b/tauri-app/src/components/AddRemedyComponent/index.tsx @@ -1,14 +1,18 @@ import "./index.css"; -import { useState } from "react"; +import React, { FC, useState } from "react"; -const FileUploader = () => { - const [file, setFile] = useState(null); +interface FileProp { + file: File | null | undefined; +} + +const FileUploader: FC = () => { + const [file, setFile] = useState({ file: null }); return (
{ - setFile(e.target.files[0]); + setFile({ file: e?.target?.files?.[0] }); }} type="file" accept=".jpg,.png,.jpeg" @@ -17,7 +21,13 @@ const FileUploader = () => { ); }; -const StepField = ({ addStep, index }) => { +interface StepProp { + index: React.ReactNode; +} + +//add stepFunction +//to trigger when save in main form is clicked +const StepField: FC = ({ index }) => { return (

Step #{index}

@@ -27,8 +37,11 @@ const StepField = ({ addStep, index }) => { ); }; -const index = () => { - const [steps, setSteps] = useState([]); +const index: FC = () => { + const [steps, setSteps] = useState([ + , + ]); + return (

Create New Remedy

diff --git a/tauri-app/src/components/Card/index.tsx b/tauri-app/src/components/Card/index.tsx index e98d449..d61c871 100644 --- a/tauri-app/src/components/Card/index.tsx +++ b/tauri-app/src/components/Card/index.tsx @@ -1,8 +1,24 @@ import "./index.css"; -import { useState } from "react"; +import React, { FC, useState } from "react"; -const index = ({ file_name, file_extension, title, desc, date, cardUtils }) => { - const [supportedIMGExtensions, setSupportedIMG, Extensions] = useState([ +interface CardProp { + file_name: String; + file_extension: string; + title: String; + desc: String; + date: String; + cardUtils: any[]; +} + +const index: FC = ({ + file_name, + file_extension, + title, + desc, + date, + cardUtils, +}) => { + const [supportedIMGExtensions, setSupportedIMGExtensions] = useState([ "jpg", "png", "jpeg", diff --git a/tauri-app/src/components/DetailCardComponent/index.tsx b/tauri-app/src/components/DetailCardComponent/index.tsx index 393c33f..9ae854b 100644 --- a/tauri-app/src/components/DetailCardComponent/index.tsx +++ b/tauri-app/src/components/DetailCardComponent/index.tsx @@ -1,7 +1,29 @@ import "./index.css"; -import { useState } from "react"; +import React, { FC, useState } from "react"; -const index = ({ cardData, close }) => { +interface OtherFileProp { + title: String; + file_extension: string; + file_name: string; + + file_url: string; +} + +interface CardDataProps { + file_name: String; + file_extension: string; + title: String; + desc: String; + date: String; + other_files: OtherFileProp[]; +} + +interface CardProp { + cardData: CardDataProps; + close: (isCardDetailActive: boolean) => void; +} + +const index: FC = ({ cardData, close }) => { const [supportedIMGExtensions, setSupportedIMGExtensions] = useState([ "jpg", "png", diff --git a/tauri-app/src/pages/Contact/index.tsx b/tauri-app/src/pages/Contact/index.tsx index ca84645..4c07599 100644 --- a/tauri-app/src/pages/Contact/index.tsx +++ b/tauri-app/src/pages/Contact/index.tsx @@ -55,12 +55,21 @@ const index: FC = () => {
- +
+
+

Hospital/Dr. name

+
+
+

Address

+
+
+

City

+
+
+

Distance

+
+
+ {fetchedLocations.map((location) => { return ( Date: Fri, 5 Jan 2024 17:10:09 +0530 Subject: [PATCH 023/120] fixed all errors --- server/package-lock.json | 2354 +++++++++++++++++ server/src/app.ts | 1 + server/src/utils.ts | 5 + tauri-app/package-lock.json | 9 + tauri-app/src/components/RemedyCard/index.tsx | 9 + tauri-app/src/pages/Contact/index.tsx | 8 +- tauri-app/src/pages/Records/index.tsx | 3 + tauri-app/src/pages/Remedies/index.tsx | 22 +- 8 files changed, 2402 insertions(+), 9 deletions(-) create mode 100644 server/package-lock.json diff --git a/server/package-lock.json b/server/package-lock.json new file mode 100644 index 0000000..9794805 --- /dev/null +++ b/server/package-lock.json @@ -0,0 +1,2354 @@ +{ + "name": "server", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@hono/node-server": "^1.4.0", + "@hono/zod-validator": "^0.1.11", + "@web5/api": "^0.8.3", + "hono": "^3.12.0", + "true-myth": "5", + "tsconfig-paths": "^4.2.0", + "zod": "^3.22.4" + }, + "devDependencies": { + "tsx": "^4.7.0", + "typescript": "^5.3.3" + } + }, + "node_modules/@assemblyscript/loader": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.9.4.tgz", + "integrity": "sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA==" + }, + "node_modules/@decentralized-identity/ion-pow-sdk": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/@decentralized-identity/ion-pow-sdk/-/ion-pow-sdk-1.0.17.tgz", + "integrity": "sha512-vk7DTDM8aKDbFyu1ad/qkoRrGL4q+KvNeL/FNZXhkWPaDhVExBN/qGEoRLf1YSfFe+myto3+4RYTPut+riiqnw==", + "dependencies": { + "buffer": "6.0.3", + "cross-fetch": "3.1.5", + "hash-wasm": "4.9.0" + } + }, + "node_modules/@decentralized-identity/ion-pow-sdk/node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/@decentralized-identity/ion-pow-sdk/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@decentralized-identity/ion-sdk": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@decentralized-identity/ion-sdk/-/ion-sdk-1.0.1.tgz", + "integrity": "sha512-+P+DXcRSFjsEsI5KIqUmVjpzgUT28B2lWpTO+IxiBcfibAN/1Sg20NebGTO/+serz2CnSZf95N2a1OZ6eXypGQ==", + "dependencies": { + "@noble/ed25519": "^2.0.0", + "@noble/secp256k1": "^2.0.0", + "canonicalize": "^2.0.0", + "multiformats": "^12.0.1", + "multihashes": "^4.0.3", + "uri-js": "^4.4.1" + } + }, + "node_modules/@decentralized-identity/ion-sdk/node_modules/multiformats": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", + "integrity": "sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", + "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", + "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", + "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", + "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", + "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", + "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", + "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", + "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", + "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", + "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", + "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", + "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", + "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", + "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", + "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", + "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", + "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", + "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", + "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", + "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", + "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", + "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", + "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@hono/node-server": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.4.0.tgz", + "integrity": "sha512-bhDkhldW7w9VgjrX0gG1vJ2YyvTxFWd5WG9nHjSR4UauhVECQZC3qy7mVVuQ054I5NWhKttHfKzYfoPzmUzAjw==", + "engines": { + "node": ">=18.14.1" + } + }, + "node_modules/@hono/zod-validator": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@hono/zod-validator/-/zod-validator-0.1.11.tgz", + "integrity": "sha512-PQXeHUP0+36qpRt8yfeD7N2jbK3ETlGvSN6dMof/HwUC/APRokQRjpXZm4rrlG71Ft0aWE01+Bm4XejqPie5Uw==", + "peerDependencies": { + "hono": ">=3.9.0", + "zod": "^3.19.1" + } + }, + "node_modules/@ipld/dag-cbor": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-9.0.3.tgz", + "integrity": "sha512-A2UFccS0+sARK9xwXiVZIaWbLbPxLGP3UZOjBeOMWfDY04SXi8h1+t4rHBzOlKYF/yWNm3RbFLyclWO7hZcy4g==", + "dependencies": { + "cborg": "^2.0.1", + "multiformats": "^12.0.1" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@ipld/dag-cbor/node_modules/multiformats": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", + "integrity": "sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@ipld/dag-pb": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.0.7.tgz", + "integrity": "sha512-EqJtSAcELiYbp9K0Y5ckbg+W0pD5cSy5PnE/QsCrpKvoq+u0E8Vi07chNGDLaShd5AjDq0AMtnuudKUUuEuSjg==", + "dependencies": { + "multiformats": "^13.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@ipld/dag-pb/node_modules/multiformats": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.0.0.tgz", + "integrity": "sha512-xiIB0p7EKmETm3wyKedOg/xuyQ18PoWwXCzzgpZAiDxL9ktl3XTh8AqoDT5kAqRg+DU48XAGPsUJL2Rn6Bx3Lw==" + }, + "node_modules/@js-temporal/polyfill": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@js-temporal/polyfill/-/polyfill-0.4.4.tgz", + "integrity": "sha512-2X6bvghJ/JAoZO52lbgyAPFj8uCflhTo2g7nkFzEQdXd/D8rEeD4HtmTEpmtGCva260fcd66YNXBOYdnmHqSOg==", + "dependencies": { + "jsbi": "^4.3.0", + "tslib": "^2.4.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "node_modules/@multiformats/base-x": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz", + "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" + }, + "node_modules/@multiformats/murmur3": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.8.tgz", + "integrity": "sha512-6vId1C46ra3R1sbJUOFCZnsUIveR9oF20yhPmAFxPm0JfrX3/ZRCgP3YDrBzlGoEppOXnA9czHeYc0T9mB6hbA==", + "dependencies": { + "multiformats": "^13.0.0", + "murmurhash3js-revisited": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@multiformats/murmur3/node_modules/multiformats": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.0.0.tgz", + "integrity": "sha512-xiIB0p7EKmETm3wyKedOg/xuyQ18PoWwXCzzgpZAiDxL9ktl3XTh8AqoDT5kAqRg+DU48XAGPsUJL2Rn6Bx3Lw==" + }, + "node_modules/@noble/ciphers": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.1.4.tgz", + "integrity": "sha512-d3ZR8vGSpy3v/nllS+bD/OMN5UZqusWiQqkyj7AwzTnhXFH72pF5oB4Ach6DQ50g5kXxC28LdaYBEpsyv9KOUQ==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/ed25519": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-2.0.0.tgz", + "integrity": "sha512-/extjhkwFupyopDrt80OMWKdLgP429qLZj+z6sYJz90rF2Iz0gjZh2ArMKPImUl13Kx+0EXI2hN9T/KJV0/Zng==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.0.0.tgz", + "integrity": "sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@tbd54566975/dwn-sdk-js": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@tbd54566975/dwn-sdk-js/-/dwn-sdk-js-0.2.8.tgz", + "integrity": "sha512-oiKk+ekAQO94bUkt6yk+xkDY8uCGmNC+rKaYQLhAoTrhYrczeRSuDT04F5/vPBT5K6NfAoRcQsIyBmvgRCUvgA==", + "dependencies": { + "@ipld/dag-cbor": "9.0.3", + "@js-temporal/polyfill": "0.4.4", + "@noble/ed25519": "2.0.0", + "@noble/secp256k1": "2.0.0", + "abstract-level": "1.0.3", + "ajv": "8.12.0", + "blockstore-core": "4.2.0", + "cross-fetch": "4.0.0", + "eciesjs": "0.4.5", + "flat": "5.0.2", + "interface-blockstore": "5.2.3", + "interface-store": "5.1.2", + "ipfs-unixfs-exporter": "13.1.5", + "ipfs-unixfs-importer": "15.1.5", + "level": "8.0.0", + "lodash": "4.17.21", + "lru-cache": "9.1.2", + "ms": "2.1.3", + "multiformats": "11.0.2", + "randombytes": "2.1.0", + "readable-stream": "4.4.2", + "ulidx": "2.1.0", + "uuid": "8.3.2", + "varint": "6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@web5/agent": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@web5/agent/-/agent-0.2.5.tgz", + "integrity": "sha512-Z9JY/43Yrg0xKK26y/iZFdHNtVf/k9XLxw8mXP5zfYidrqfAgVR0i4LKA7qZKfUSxC7/uaD/STYYIKpNByd/cw==", + "dependencies": { + "@tbd54566975/dwn-sdk-js": "0.2.8", + "@web5/common": "0.2.2", + "@web5/crypto": "0.2.2", + "@web5/dids": "0.2.3", + "level": "8.0.0", + "readable-stream": "4.4.2", + "readable-web-to-node-stream": "3.0.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web5/api": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@web5/api/-/api-0.8.3.tgz", + "integrity": "sha512-YXQ++ZShtd5LeFRqEMGlhVqJ7Zg5P6bMequpaLl068bCGjtjCwiFFgDtM1KeL36IAzQ4pFLFyj9aTGZ/JgCXHA==", + "dependencies": { + "@tbd54566975/dwn-sdk-js": "0.2.8", + "@web5/agent": "0.2.5", + "@web5/common": "0.2.2", + "@web5/crypto": "0.2.2", + "@web5/dids": "0.2.3", + "@web5/user-agent": "0.2.5", + "level": "8.0.0", + "ms": "2.1.3", + "readable-stream": "4.4.2", + "readable-web-to-node-stream": "3.0.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web5/common": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@web5/common/-/common-0.2.2.tgz", + "integrity": "sha512-dRn6SmALExeTLMTK/W5ozGarfaddK+Lraf5OjuIGLAaLfcX1RWx3oDMoY5Hr9LjfxHJC8mGXB8DnKflbeYJRgA==", + "dependencies": { + "level": "8.0.0", + "multiformats": "11.0.2", + "readable-stream": "4.4.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web5/crypto": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@web5/crypto/-/crypto-0.2.2.tgz", + "integrity": "sha512-vHFg0wXQSQXrwuBNQyDHnmSZchfTfO6/Sv+7rDsNkvofs+6lGTE8CZ02cwUYMeIwTRMLer12c+fMfzYrXokEUQ==", + "dependencies": { + "@noble/ciphers": "0.1.4", + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@web5/common": "0.2.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web5/crypto/node_modules/@web5/common": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@web5/common/-/common-0.2.1.tgz", + "integrity": "sha512-Tt5P17HgQCx+Epw0IHnhRKqp5UU3E4xtsE8PkdghOBnvntBB0op5P6efvR1WqmJft5+VunDHt3yZAZstuqQkNg==", + "dependencies": { + "level": "8.0.0", + "multiformats": "11.0.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web5/dids": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@web5/dids/-/dids-0.2.3.tgz", + "integrity": "sha512-Y3PHOavNkSyjBxZQEpKE6XueaqemBO5w0UMOnFh4xH6+5B43ENEE4LHIqVyn2bCpfEBGLXENgDZYqyJphBu0pA==", + "dependencies": { + "@decentralized-identity/ion-pow-sdk": "1.0.17", + "@decentralized-identity/ion-sdk": "1.0.1", + "@web5/common": "0.2.2", + "@web5/crypto": "0.2.2", + "did-resolver": "4.1.0", + "dns-packet": "5.6.1", + "level": "8.0.0", + "ms": "2.1.3", + "pkarr": "1.1.1", + "z32": "1.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web5/user-agent": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@web5/user-agent/-/user-agent-0.2.5.tgz", + "integrity": "sha512-qv5M698C5HSvq30xUgLWtcsbZppjfOH5qZthpTRx4ItL5UWA/eQ9DsQiQeb4vet3uIUy3NHRDIQezclOdwYErw==", + "dependencies": { + "@web5/agent": "0.2.5", + "@web5/common": "0.2.2", + "@web5/crypto": "0.2.2", + "@web5/dids": "0.2.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-level": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", + "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bencode": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-3.1.1.tgz", + "integrity": "sha512-btsxX9201yoWh45TdqYg6+OZ5O1xTYKTYSGvJndICDFtznE/9zXgow8yjMvvhOqKKuzuL7h+iiCMpfkG8+QuBA==", + "dependencies": { + "uint8-util": "^2.1.6" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/bittorrent-dht": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-11.0.5.tgz", + "integrity": "sha512-R09D6uNaziRqsc+B/j5QzkjceTak+wH9vcNLnkmt8A52EWF9lQwBP0vvCKgSA3AJOYYl+41n3osA2KYYn/z5uQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bencode": "^4.0.0", + "debug": "^4.3.4", + "k-bucket": "^5.1.0", + "k-rpc": "^5.1.0", + "last-one-wins": "^1.0.4", + "lru": "^3.1.0", + "randombytes": "^2.1.0", + "record-cache": "^1.2.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/bittorrent-dht/node_modules/bencode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-4.0.0.tgz", + "integrity": "sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==", + "dependencies": { + "uint8-util": "^2.2.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/blake2b": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.4.tgz", + "integrity": "sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==", + "dependencies": { + "blake2b-wasm": "^2.4.0", + "nanoassert": "^2.0.0" + } + }, + "node_modules/blake2b-wasm": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", + "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", + "dependencies": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, + "node_modules/blockstore-core": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/blockstore-core/-/blockstore-core-4.2.0.tgz", + "integrity": "sha512-F8BCobc75D+9/+hUD+5cixbU6zmZA+lBgNiuBkNlJqRgmAaBBvLOQF6Ad9Jei0Nvmy2a1jaF4CiN76W1apIghA==", + "dependencies": { + "err-code": "^3.0.1", + "interface-blockstore": "^5.0.0", + "interface-store": "^5.0.0", + "multiformats": "^11.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/browser-level": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", + "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/canonicalize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.0.0.tgz", + "integrity": "sha512-ulDEYPv7asdKvqahuAY35c1selLdzDwHqugK92hfkzvlDCwXRRelDkR+Er33md/PtnpqHemgkuDPanZ4fiYZ8w==" + }, + "node_modules/catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cborg": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-2.0.5.tgz", + "integrity": "sha512-xVW1rSIw1ZXbkwl2XhJ7o/jAv0vnVoQv/QlfQxV8a7V5PlA4UU/AcIiXqmpyybwNWy/GPQU1m/aBVNIWr7/T0w==", + "bin": { + "cborg": "cli.js" + } + }, + "node_modules/chacha20-universal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chacha20-universal/-/chacha20-universal-1.0.4.tgz", + "integrity": "sha512-/IOxdWWNa7nRabfe7+oF+jVkGjlr2xUL4J8l/OvzZhj+c9RpMqoo3Dq+5nU1j/BflRV4BKnaQ4+4oH1yBpQG1Q==", + "dependencies": { + "nanoassert": "^2.0.0" + } + }, + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chrome-dgram": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/chrome-dgram/-/chrome-dgram-3.0.6.tgz", + "integrity": "sha512-bqBsUuaOiXiqxXt/zA/jukNJJ4oaOtc7ciwqJpZVEaaXwwxqgI2/ZdG02vXYWUhHGziDlvGMQWk0qObgJwVYKA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "inherits": "^2.0.4", + "run-series": "^1.1.9" + } + }, + "node_modules/chrome-dns": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chrome-dns/-/chrome-dns-1.0.1.tgz", + "integrity": "sha512-HqsYJgIc8ljJJOqOzLphjAs79EUuWSX3nzZi2LNkzlw3GIzAeZbaSektC8iT/tKvLqZq8yl1GJu5o6doA4TRbg==", + "dependencies": { + "chrome-net": "^3.3.2" + } + }, + "node_modules/chrome-net": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/chrome-net/-/chrome-net-3.3.4.tgz", + "integrity": "sha512-Jzy2EnzmE+ligqIZUsmWnck9RBXLuUy6CaKyuNMtowFG3ZvLt8d+WBJCTPEludV0DHpIKjAOlwjFmTaEdfdWCw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/classic-level": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", + "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", + "hasInstallScript": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "^2.2.2", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/did-resolver": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", + "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eciesjs": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.5.tgz", + "integrity": "sha512-2zSRIygO48LpdS95Rwt9ryIkJNO37IdbkjRsnYyAn7gx7e4WPBNimnk6jGNdx2QQYr/VJRPnSVdwQpO5bycYZw==", + "dependencies": { + "@noble/ciphers": "^0.3.0", + "@noble/curves": "^1.2.0", + "@noble/hashes": "^1.3.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/eciesjs/node_modules/@noble/ciphers": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.3.0.tgz", + "integrity": "sha512-ldbrnOjmNRwFdXcTM6uXDcxpMIFrbzAWNnpBPp4oTJTFF0XByGD6vf45WrehZGXRQTRVV+Zm8YP+EgEf+e4cWA==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/eciesjs/node_modules/@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "dependencies": { + "@noble/hashes": "1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/eciesjs/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, + "node_modules/esbuild": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", + "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/graceful-goodbye": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/graceful-goodbye/-/graceful-goodbye-1.3.0.tgz", + "integrity": "sha512-hcZOs20emYlTM7MmUE0FpuZcjlk2GPsR+UYTHDeWxtGjXcbh2CawGi8vlzqsIvspqAbot7mRv3sC/uhgtKc4hQ==", + "dependencies": { + "safety-catch": "^1.0.2" + } + }, + "node_modules/hamt-sharding": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.2.tgz", + "integrity": "sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw==", + "dependencies": { + "sparse-array": "^1.3.1", + "uint8arrays": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/hash-wasm": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.9.0.tgz", + "integrity": "sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==" + }, + "node_modules/hono": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/hono/-/hono-3.12.0.tgz", + "integrity": "sha512-UPEtZuLY7Wo7g0mqKWSOjLFdT8t7wJ60IYEcxKl3AQNU4u+R2QqU2fJMPmSu24C+/ag20Z8mOTQOErZzK4DMvA==", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/interface-blockstore": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-5.2.3.tgz", + "integrity": "sha512-15cN+ZFdcVXdXo6I/SrSzFDsuJyDTyEI52XuvXQlR/G5fe3cK8p0tvVjfu5diRQH1XqNgmJEdMPixyt0xgjtvQ==", + "dependencies": { + "interface-store": "^5.0.0", + "multiformats": "^11.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/interface-store": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-5.1.2.tgz", + "integrity": "sha512-q2sLoqC+UdaWnjwGyghsH0jwqqVk226lsG207e3QwPB8sAZYmYIWUnJwJH3JjFNNRV9e6CUTmm+gDO0Xg4KRiw==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-unixfs": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.1.2.tgz", + "integrity": "sha512-HVjrACOhU8RgMskcrfydk+FDAE9pFKr8tneKLaVYQ2f81HUKXoiSdgsAJY/jt7Ieyj4tE12TZGduIeWtNpScOw==", + "dependencies": { + "err-code": "^3.0.1", + "protons-runtime": "^5.0.0", + "uint8arraylist": "^2.4.3" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-unixfs-exporter": { + "version": "13.1.5", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-13.1.5.tgz", + "integrity": "sha512-O5aMawsHoe4DaYk5FFil2EPrNOaU3pkHC6qUR5JMnW7es93W3b/RjJoO7AyDL1rpb+M3K0oRu86Yc5wLNQQ8jg==", + "dependencies": { + "@ipld/dag-cbor": "^9.0.0", + "@ipld/dag-pb": "^4.0.0", + "@multiformats/murmur3": "^2.0.0", + "err-code": "^3.0.1", + "hamt-sharding": "^3.0.0", + "interface-blockstore": "^5.0.0", + "ipfs-unixfs": "^11.0.0", + "it-filter": "^3.0.2", + "it-last": "^3.0.2", + "it-map": "^3.0.3", + "it-parallel": "^3.0.0", + "it-pipe": "^3.0.1", + "it-pushable": "^3.1.0", + "multiformats": "^11.0.0", + "p-queue": "^7.3.0", + "progress-events": "^1.0.0", + "uint8arrays": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ipfs-unixfs-importer": { + "version": "15.1.5", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-15.1.5.tgz", + "integrity": "sha512-TXaOI0M5KNpq2+qLw8AIYd0Lnc0gWTKCBqUd9eErBUwaP3Fna4qauF+JX9Rj2UrwaOvG/1xbF8Vm+92eOcKWMA==", + "dependencies": { + "@ipld/dag-pb": "^4.0.0", + "@multiformats/murmur3": "^2.0.0", + "err-code": "^3.0.1", + "hamt-sharding": "^3.0.0", + "interface-blockstore": "^5.0.0", + "interface-store": "^5.0.1", + "ipfs-unixfs": "^11.0.0", + "it-all": "^3.0.2", + "it-batch": "^3.0.2", + "it-first": "^3.0.2", + "it-parallel-batch": "^3.0.1", + "multiformats": "^11.0.0", + "progress-events": "^1.0.0", + "rabin-wasm": "^0.1.4", + "uint8arraylist": "^2.4.3", + "uint8arrays": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/it-all": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/it-all/-/it-all-3.0.4.tgz", + "integrity": "sha512-UMiy0i9DqCHBdWvMbzdYvVGa5/w4t1cc4nchpbnjdLhklglv8mQeEYnii0gvKESJuL1zV32Cqdb33R6/GPfxpQ==" + }, + "node_modules/it-batch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-3.0.4.tgz", + "integrity": "sha512-WRu2mqOYIs+T9k7+yxSK9VJdk0UE4R0jKQsWQcti5c6vhb1FhjC2+yCB5XBrctQ9edNfCMU/wVzdDj8qSwimbA==" + }, + "node_modules/it-filter": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/it-filter/-/it-filter-3.0.4.tgz", + "integrity": "sha512-e0sz+st4sudK/zH6GZ/gRTRP8A/ADuJFCYDmRgMbZvR79y5+v4ZXav850bBZk5wL9zXaYZFxS1v/6Qi+Vjwh5g==", + "dependencies": { + "it-peekable": "^3.0.0" + } + }, + "node_modules/it-first": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/it-first/-/it-first-3.0.4.tgz", + "integrity": "sha512-FtQl84iTNxN5EItP/JgL28V2rzNMkCzTUlNoj41eVdfix2z1DBuLnBqZ0hzYhGGa1rMpbQf0M7CQSA2adlrLJg==" + }, + "node_modules/it-last": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/it-last/-/it-last-3.0.4.tgz", + "integrity": "sha512-Ns+KTsQWhs0KCvfv5X3Ck3lpoYxHcp4zUp4d+AOdmC8cXXqDuoZqAjfWhgCbxJubXyIYWdfE2nRcfWqgvZHP8Q==" + }, + "node_modules/it-map": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/it-map/-/it-map-3.0.5.tgz", + "integrity": "sha512-hB0TDXo/h4KSJJDSRLgAPmDroiXP6Fx1ck4Bzl3US9hHfZweTKsuiP0y4gXuTMcJlS6vj0bb+f70rhkD47ZA3w==", + "dependencies": { + "it-peekable": "^3.0.0" + } + }, + "node_modules/it-merge": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/it-merge/-/it-merge-3.0.3.tgz", + "integrity": "sha512-FYVU15KC5pb/GQX1Ims+lee8d4pdqGVCpWr0lkNj8o4xuNo7jY71k6GuEiWdP+T7W1bJqewSxX5yoTy5yZpRVA==", + "dependencies": { + "it-pushable": "^3.2.0" + } + }, + "node_modules/it-parallel": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/it-parallel/-/it-parallel-3.0.6.tgz", + "integrity": "sha512-i7UM7I9LTkDJw3YIqXHFAPZX6CWYzGc+X3irdNrVExI4vPazrJdI7t5OqrSVN8CONXLAunCiqaSV/zZRbQR56A==", + "dependencies": { + "p-defer": "^4.0.0" + } + }, + "node_modules/it-parallel-batch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-3.0.4.tgz", + "integrity": "sha512-O1omh8ss8+UtXiMjE+8kM5C20DT0Ma4VtKVfrSHOJU0UHZ+iWBXarabzPYEp+WiuQmrv+klDPPlTZ9KaLN9xOA==", + "dependencies": { + "it-batch": "^3.0.0" + } + }, + "node_modules/it-peekable": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/it-peekable/-/it-peekable-3.0.3.tgz", + "integrity": "sha512-Wx21JX/rMzTEl9flx3DGHuPV1KQFGOl8uoKfQtmZHgPQtGb89eQ6RyVd82h3HuP9Ghpt0WgBDlmmdWeHXqyx7w==" + }, + "node_modules/it-pipe": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-pipe/-/it-pipe-3.0.1.tgz", + "integrity": "sha512-sIoNrQl1qSRg2seYSBH/3QxWhJFn9PKYvOf/bHdtCBF0bnghey44VyASsWzn5dAx0DCDDABq1hZIuzKmtBZmKA==", + "dependencies": { + "it-merge": "^3.0.0", + "it-pushable": "^3.1.2", + "it-stream-types": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/it-pushable": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/it-pushable/-/it-pushable-3.2.3.tgz", + "integrity": "sha512-gzYnXYK8Y5t5b/BnJUr7glfQLO4U5vyb05gPx/TyTw+4Bv1zM9gFk4YsOrnulWefMewlphCjKkakFvj1y99Tcg==", + "dependencies": { + "p-defer": "^4.0.0" + } + }, + "node_modules/it-stream-types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/it-stream-types/-/it-stream-types-2.0.1.tgz", + "integrity": "sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/jsbi": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-4.3.0.tgz", + "integrity": "sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g==" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/k-bucket": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/k-bucket/-/k-bucket-5.1.0.tgz", + "integrity": "sha512-Fac7iINEovXIWU20GPnOMLUbjctiS+cnmyjC4zAUgvs3XPf1vo9akfCHkigftSic/jiKqKl+KA3a/vFcJbHyCg==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/k-rpc": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/k-rpc/-/k-rpc-5.1.0.tgz", + "integrity": "sha512-FGc+n70Hcjoa/X2JTwP+jMIOpBz+pkRffHnSl9yrYiwUxg3FIgD50+u1ePfJUOnRCnx6pbjmVk5aAeB1wIijuQ==", + "dependencies": { + "k-bucket": "^5.0.0", + "k-rpc-socket": "^1.7.2", + "randombytes": "^2.0.5" + } + }, + "node_modules/k-rpc-socket": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/k-rpc-socket/-/k-rpc-socket-1.11.1.tgz", + "integrity": "sha512-8xtA8oqbZ6v1Niryp2/g4GxW16EQh5MvrUylQoOG+zcrDff5CKttON2XUXvMwlIHq4/2zfPVFiinAccJ+WhxoA==", + "dependencies": { + "bencode": "^2.0.0", + "chrome-dgram": "^3.0.2", + "chrome-dns": "^1.0.0", + "chrome-net": "^3.3.2" + } + }, + "node_modules/k-rpc-socket/node_modules/bencode": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz", + "integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==" + }, + "node_modules/last-one-wins": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/last-one-wins/-/last-one-wins-1.0.4.tgz", + "integrity": "sha512-t+KLJFkHPQk8lfN6WBOiGkiUXoub+gnb2XTYI2P3aiISL+94xgZ1vgz1SXN/N4hthuOoLXarXfBZPUruyjQtfA==" + }, + "node_modules/layerr": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layerr/-/layerr-2.0.1.tgz", + "integrity": "sha512-z0730CwG/JO24evdORnyDkwG1Q7b7mF2Tp1qRQ0YvrMMARbt1DFG694SOv439Gm7hYKolyZyaB49YIrYIfZBdg==" + }, + "node_modules/level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", + "dependencies": { + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", + "dependencies": { + "buffer": "^6.0.3", + "module-error": "^1.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lru": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lru/-/lru-3.1.0.tgz", + "integrity": "sha512-5OUtoiVIGU4VXBOshidmtOsvBIvcQR6FD/RzWSvaeHyxCGB+PCUCu+52lqMfdc0h/2CLvHhZS4TwUmMQrrMbBQ==", + "dependencies": { + "inherits": "^2.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/lru-cache": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", + "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/module-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/multibase": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-4.0.6.tgz", + "integrity": "sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "@multiformats/base-x": "^4.0.1" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/multiformats": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", + "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/multihashes": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-4.0.3.tgz", + "integrity": "sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA==", + "dependencies": { + "multibase": "^4.0.1", + "uint8arrays": "^3.0.0", + "varint": "^5.0.2" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/multihashes/node_modules/multiformats": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" + }, + "node_modules/multihashes/node_modules/uint8arrays": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", + "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", + "dependencies": { + "multiformats": "^9.4.2" + } + }, + "node_modules/multihashes/node_modules/varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" + }, + "node_modules/murmurhash3js-revisited": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz", + "integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/nanoassert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", + "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==" + }, + "node_modules/napi-macros": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", + "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz", + "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/p-defer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.0.tgz", + "integrity": "sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.4.1.tgz", + "integrity": "sha512-vRpMXmIkYF2/1hLBKisKeVYJZ8S2tZ0zEAmIJgdVKP2nq0nh4qCdf8bgw+ZgKrkh71AOCaqzwbJJk1WtdcF3VA==", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^5.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkarr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkarr/-/pkarr-1.1.1.tgz", + "integrity": "sha512-X27LKqf83X3WuJd2Z9qdfVxkmfOu6HUbY0pm11LqeBbFmgmZRPgOxJG8bKiIsmmD6Vjc25j45KHYflF2lfodyQ==", + "dependencies": { + "bencode": "^3.0.3", + "bittorrent-dht": "^11.0.4", + "chalk": "^5.2.0", + "dns-packet": "^5.6.1", + "graceful-goodbye": "^1.3.0", + "sodium-universal": "^4.0.0", + "z32": "^1.0.0" + }, + "bin": { + "pkarr": "bin.js" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/progress-events": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.0.tgz", + "integrity": "sha512-zIB6QDrSbPfRg+33FZalluFIowkbV5Xh1xSuetjG+rlC5he6u2dc6VQJ0TbMdlN3R1RHdpOqxEFMKTnQ+itUwA==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/protons-runtime": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-5.2.1.tgz", + "integrity": "sha512-Rt4ORm1WR62ysrXX5sCV32a5jPwVoIpU90XUzrdAfMIOSNTizvqlx/7wedNpogvZjUUY/gLJp3VftpA+ebx/og==", + "dependencies": { + "uint8arraylist": "^2.4.3", + "uint8arrays": "^5.0.1" + } + }, + "node_modules/protons-runtime/node_modules/multiformats": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.0.0.tgz", + "integrity": "sha512-xiIB0p7EKmETm3wyKedOg/xuyQ18PoWwXCzzgpZAiDxL9ktl3XTh8AqoDT5kAqRg+DU48XAGPsUJL2Rn6Bx3Lw==" + }, + "node_modules/protons-runtime/node_modules/uint8arrays": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.0.1.tgz", + "integrity": "sha512-ND5RpJAnPgHmZT7hWD/2T4BwRp04j8NLKvMKC/7bhiEwEjUMkQ4kvBKiH6hOqbljd6qJ2xS8reL3vl1e33grOQ==", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/rabin-wasm": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/rabin-wasm/-/rabin-wasm-0.1.5.tgz", + "integrity": "sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA==", + "dependencies": { + "@assemblyscript/loader": "^0.9.4", + "bl": "^5.0.0", + "debug": "^4.3.1", + "minimist": "^1.2.5", + "node-fetch": "^2.6.1", + "readable-stream": "^3.6.0" + }, + "bin": { + "rabin-wasm": "cli/bin.js" + } + }, + "node_modules/rabin-wasm/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dependencies": { + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/record-cache": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/record-cache/-/record-cache-1.2.0.tgz", + "integrity": "sha512-kyy3HWCez2WrotaL3O4fTn0rsIdfRKOdQQcEJ9KpvmKmbffKVvwsloX063EgRUlpJIXHiDQFhJcTbZequ2uTZw==", + "dependencies": { + "b4a": "^1.3.1" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/run-series": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safety-catch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/safety-catch/-/safety-catch-1.0.2.tgz", + "integrity": "sha512-C1UYVZ4dtbBxEtvOcpjBaaD27nP8MlvyAQEp2fOTOEe6pfUpk1cDUxij6BR1jZup6rSyUTaBBplK7LanskrULA==" + }, + "node_modules/sha256-universal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sha256-universal/-/sha256-universal-1.2.1.tgz", + "integrity": "sha512-ghn3muhdn1ailCQqqceNxRgkOeZSVfSE13RQWEg6njB+itsFzGVSJv+O//2hvNXZuxVIRyNzrgsZ37SPDdGJJw==", + "dependencies": { + "b4a": "^1.0.1", + "sha256-wasm": "^2.2.1" + } + }, + "node_modules/sha256-wasm": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/sha256-wasm/-/sha256-wasm-2.2.2.tgz", + "integrity": "sha512-qKSGARvao+JQlFiA+sjJZhJ/61gmW/3aNLblB2rsgIxDlDxsJPHo8a1seXj12oKtuHVgJSJJ7QEGBUYQN741lQ==", + "dependencies": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, + "node_modules/sha512-universal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sha512-universal/-/sha512-universal-1.2.1.tgz", + "integrity": "sha512-kehYuigMoRkIngCv7rhgruLJNNHDnitGTBdkcYbCbooL8Cidj/bS78MDxByIjcc69M915WxcQTgZetZ1JbeQTQ==", + "dependencies": { + "b4a": "^1.0.1", + "sha512-wasm": "^2.3.1" + } + }, + "node_modules/sha512-wasm": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/sha512-wasm/-/sha512-wasm-2.3.4.tgz", + "integrity": "sha512-akWoxJPGCB3aZCrZ+fm6VIFhJ/p8idBv7AWGFng/CZIrQo51oQNsvDbTSRXWAzIiZJvpy16oIDiCCPqTe21sKg==", + "dependencies": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, + "node_modules/siphash24": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/siphash24/-/siphash24-1.3.1.tgz", + "integrity": "sha512-moemC3ZKiTzH29nbFo3Iw8fbemWWod4vNs/WgKbQ54oEs6mE6XVlguxvinYjB+UmaE0PThgyED9fUkWvirT8hA==", + "dependencies": { + "nanoassert": "^2.0.0" + } + }, + "node_modules/sodium-javascript": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/sodium-javascript/-/sodium-javascript-0.8.0.tgz", + "integrity": "sha512-rEBzR5mPxPES+UjyMDvKPIXy9ImF17KOJ32nJNi9uIquWpS/nfj+h6m05J5yLJaGXjgM72LmQoUbWZVxh/rmGg==", + "dependencies": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "xsalsa20": "^1.0.0" + } + }, + "node_modules/sodium-native": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.0.4.tgz", + "integrity": "sha512-faqOKw4WQKK7r/ybn6Lqo1F9+L5T6NlBJJYvpxbZPetpWylUVqz449mvlwIBKBqxEHbWakWuOlUt8J3Qpc4sWw==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.6.0" + } + }, + "node_modules/sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "dependencies": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + }, + "node_modules/sparse-array": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/sparse-array/-/sparse-array-1.3.2.tgz", + "integrity": "sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/true-myth": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/true-myth/-/true-myth-5.4.0.tgz", + "integrity": "sha512-MonJqkJf+VOXZ2msbpvAI1uJWoyfCN7nirR8/fNK+IlFDWYNLb9iqeAc2uhIbAQBynHtM02azZgepQDQclOwAw==", + "engines": { + "node": "12.* || 14.* || 16.* || >= 18.*" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tsx": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", + "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", + "dev": true, + "dependencies": { + "esbuild": "~0.19.10", + "get-tsconfig": "^4.7.2" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uint8-util": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/uint8-util/-/uint8-util-2.2.4.tgz", + "integrity": "sha512-uEI5lLozmKQPYEevfEhP9LY3Je5ZmrQhaWXrzTVqrLNQl36xsRh8NiAxYwB9J+2BAt99TRbmCkROQB2ZKhx4UA==", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, + "node_modules/uint8arraylist": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/uint8arraylist/-/uint8arraylist-2.4.8.tgz", + "integrity": "sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ==", + "dependencies": { + "uint8arrays": "^5.0.1" + } + }, + "node_modules/uint8arraylist/node_modules/multiformats": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.0.0.tgz", + "integrity": "sha512-xiIB0p7EKmETm3wyKedOg/xuyQ18PoWwXCzzgpZAiDxL9ktl3XTh8AqoDT5kAqRg+DU48XAGPsUJL2Rn6Bx3Lw==" + }, + "node_modules/uint8arraylist/node_modules/uint8arrays": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.0.1.tgz", + "integrity": "sha512-ND5RpJAnPgHmZT7hWD/2T4BwRp04j8NLKvMKC/7bhiEwEjUMkQ4kvBKiH6hOqbljd6qJ2xS8reL3vl1e33grOQ==", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/uint8arrays": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-4.0.10.tgz", + "integrity": "sha512-AnJNUGGDJAgFw/eWu/Xb9zrVKEGlwJJCaeInlf3BkecE/zcTobk5YXYIPNQJO1q5Hh1QZrQQHf0JvcHqz2hqoA==", + "dependencies": { + "multiformats": "^12.0.1" + } + }, + "node_modules/uint8arrays/node_modules/multiformats": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", + "integrity": "sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/ulidx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ulidx/-/ulidx-2.1.0.tgz", + "integrity": "sha512-DlMi97oP9HASI3kLCjBlOhAG1SoisUrEqC2PJ7itiFbq9q5Zo0JejupXeu2Gke99W62epNzA4MFNToNiq8A5LA==", + "dependencies": { + "layerr": "^2.0.1" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/xsalsa20": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/xsalsa20/-/xsalsa20-1.2.0.tgz", + "integrity": "sha512-FIr/DEeoHfj7ftfylnoFt3rAIRoWXpx2AoDfrT2qD2wtp7Dp+COajvs/Icb7uHqRW9m60f5iXZwdsJJO3kvb7w==" + }, + "node_modules/z32": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/z32/-/z32-1.0.1.tgz", + "integrity": "sha512-Uytfqf6VEVchHKZDw0NRdCViOARHP84uzvOw0CXCMLOwhgHZUL9XibpEPLLQN10mCVLxOlGCQWbkV7km7yNYcw==", + "dependencies": { + "b4a": "^1.5.3" + } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/server/src/app.ts b/server/src/app.ts index 82f695f..9344854 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -22,6 +22,7 @@ const app = new Hono() if (res.isErr) return c.json({ error: res.error }) + // @ts-ignore const conditions = res.value.filter(record => record.condition === condition) return c.json(conditions) }) diff --git a/server/src/utils.ts b/server/src/utils.ts index 6460426..4a9c280 100644 --- a/server/src/utils.ts +++ b/server/src/utils.ts @@ -1,5 +1,6 @@ import { Web5 } from "@web5/api"; import ConditionsProtocol, { type Record, did as ConditionsProtocolDID } from "@frontend/utils/protocols/conditions" +// @ts-ignore import Result, { ok, err } from "true-myth/result" export type Agent = { @@ -12,6 +13,7 @@ export type Status = { detail: string, } +// @ts-ignore export async function configureProtocol(agent: Agent): Promise> { const { protocols } = await agent.web5.dwn.protocols.query({ message: { @@ -47,6 +49,7 @@ export async function configureProtocol(agent: Agent): Promise> { const { records, status } = await agent.web5.dwn.records.query({ from: ConditionsProtocolDID, @@ -56,6 +59,7 @@ export async function fetchConditions(agent: Agent): Promise { const { web5, did } = await Web5.connect({ sync: "5s", diff --git a/tauri-app/package-lock.json b/tauri-app/package-lock.json index c747970..e01b1d3 100644 --- a/tauri-app/package-lock.json +++ b/tauri-app/package-lock.json @@ -19,6 +19,7 @@ "axios": "^1.6.3", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", + "hono": "^3.12.0", "lodash": "^4.17.21", "lucide-react": "^0.298.0", "react": "^18.2.0", @@ -3509,6 +3510,14 @@ "node": ">= 0.4" } }, + "node_modules/hono": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/hono/-/hono-3.12.0.tgz", + "integrity": "sha512-UPEtZuLY7Wo7g0mqKWSOjLFdT8t7wJ60IYEcxKl3AQNU4u+R2QqU2fJMPmSu24C+/ag20Z8mOTQOErZzK4DMvA==", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", diff --git a/tauri-app/src/components/RemedyCard/index.tsx b/tauri-app/src/components/RemedyCard/index.tsx index e271b75..234198c 100644 --- a/tauri-app/src/components/RemedyCard/index.tsx +++ b/tauri-app/src/components/RemedyCard/index.tsx @@ -1,5 +1,6 @@ import "./index.css"; +// @ts-ignore const Rating = ({ rating }) => { return (
@@ -42,6 +43,7 @@ const Rating = ({ rating }) => { ); }; +// @ts-ignore const createRatingsIcons = (ratings) => { const icons = []; for (let n = 0; n < ratings; n++) { @@ -51,12 +53,19 @@ const createRatingsIcons = (ratings) => { return icons; }; + const index = ({ + // @ts-ignore title, + // @ts-ignore coverIMGUrl, + // @ts-ignore desc_snippet, + // @ts-ignore created_by, + // @ts-ignore rating, + // @ts-ignore isClicked, }) => { return ( diff --git a/tauri-app/src/pages/Contact/index.tsx b/tauri-app/src/pages/Contact/index.tsx index 4c07599..d37ad95 100644 --- a/tauri-app/src/pages/Contact/index.tsx +++ b/tauri-app/src/pages/Contact/index.tsx @@ -5,7 +5,7 @@ interface RowProp { name: String; address: String; city: String; - distance: Number; + distance: string; } const RowComponent: FC = ({ name, address, city, distance }) => { @@ -33,19 +33,19 @@ const index: FC = () => { name: "Hopsital", address: "No 4 Dress road", city: "Kumkubaga", - distance: 47, + distance: '47', }, { name: "Hopsital", address: "No 4 Dress road", city: "Kumkubaga", - distance: 47, + distance: '47', }, { name: "Hopsital", address: "No 4 Dress road", city: "Kumkubaga", - distance: 47, + distance: '47', }, ]); return ( diff --git a/tauri-app/src/pages/Records/index.tsx b/tauri-app/src/pages/Records/index.tsx index 9a61790..d95d177 100644 --- a/tauri-app/src/pages/Records/index.tsx +++ b/tauri-app/src/pages/Records/index.tsx @@ -54,6 +54,7 @@ const index = () => { const [isCardDetailActive, setIsCardDetailActive] = useState(false); const [activeCard, setActiveCard] = useState(null); + // @ts-ignore const isCardClicked = (cardDetail) => { setIsCardDetailActive(!isCardDetailActive); setIsAddCardActive(false); @@ -79,6 +80,7 @@ const index = () => { { {isAddCardActive && } {isCardDetailActive && ( diff --git a/tauri-app/src/pages/Remedies/index.tsx b/tauri-app/src/pages/Remedies/index.tsx index 627b7c6..8045d24 100644 --- a/tauri-app/src/pages/Remedies/index.tsx +++ b/tauri-app/src/pages/Remedies/index.tsx @@ -1,7 +1,7 @@ import "./index.css"; import { useState } from "react"; -import Ratings from "../../../components/Ratings/"; +import Ratings from "../../components/Ratings"; import RemedyCard from "../../components/RemedyCard/"; import AddRemedyComponent from "../../components/AddRemedyComponent/"; @@ -47,6 +47,7 @@ const index = () => { const [isDetailRemedyActive, setIsDetailRemedyActive] = useState(false); const [activeRemedy, setActiveRemedy] = useState(null); + // @ts-ignore const remedyClicked = (remedyDetail) => { setActiveRemedy(remedyDetail); setIsDetailRemedyActive(true); @@ -56,12 +57,16 @@ const index = () => { const Rate = () => { if (!isRated) { setActiveRemedy({ + // @ts-ignore ...activeRemedy, + // @ts-ignore rating: activeRemedy.rating + 1, }); } else { setActiveRemedy({ + // @ts-ignore ...activeRemedy, + // @ts-ignore rating: activeRemedy.rating - 1, }); } @@ -104,6 +109,7 @@ const index = () => {
{
Rate()} className="rd-container"> - {activeRemedy.rating} + {// @ts-ignore + activeRemedy.rating}
-

{activeRemedy.title}

+

{// @ts-ignore + activeRemedy.title}

-

{activeRemedy.desc}

- {activeRemedy.steps && +

{ + // @ts-ignore + activeRemedy.desc}

+ {// @ts-ignore + activeRemedy.steps && + // @ts-ignore activeRemedy.steps.map((step, indx) => { return (
From d7908030837d856a9647912a2b6c3cef6cfcebd1 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 11:41:06 +0000 Subject: [PATCH 024/120] trying something out with the docs schema --- tauri-app/src/utils/document.ts | 58 +++++++++++++++++++++++ tauri-app/src/utils/protocols/document.ts | 5 +- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/tauri-app/src/utils/document.ts b/tauri-app/src/utils/document.ts index e69de29..58f6970 100644 --- a/tauri-app/src/utils/document.ts +++ b/tauri-app/src/utils/document.ts @@ -0,0 +1,58 @@ +import { Record, Web5 } from "@web5/api/browser" +import DocumentProtocol from "./protocols/document"; + +type Agent = { + web5: Web5 + did: string +} + +type DocumentSchema = typeof DocumentProtocol["types"][keyof typeof DocumentProtocol["types"]]["schema"] + +type FilterObj = { + schema?: DocumentSchema +} + +async function fetchDocumentRecords(agent: Agent, filter?: FilterObj) { + const { records } = await agent.web5.dwn.records.query({ + message: { + filter: { + ...filter, + protocol: DocumentProtocol.protocol, + }, + // @ts-ignore + dateSort: "createdAscending", + }, + }); + + if (!records) return false + + return records +} + +async function createRecord() { + const docs = []; + for (const record of records) { + const data = await record.data.json(); + docs.push({ + record, + data, + id: record.id + }); + } + + setDocuments(docs); +} + +async function createBlobRecord(web5: Web5, file: File) { + const { record: uploadedRecord } = await web5.dwn.records.create({ + data: new Blob([file], { type: file.type }), + message: { + schema: DocumentProtocol.types.blob.schema, + protocol: DocumentProtocol.protocol + } + }) + + if (!uploadedRecord) return false + + return uploadedRecord +} diff --git a/tauri-app/src/utils/protocols/document.ts b/tauri-app/src/utils/protocols/document.ts index e4a148b..ce134ca 100644 --- a/tauri-app/src/utils/protocols/document.ts +++ b/tauri-app/src/utils/protocols/document.ts @@ -11,7 +11,7 @@ const DocumentProtocol = { blob: { schema: "https://dschema.org/protocols/document/schemas/blob.json", dataFormats: [ - "application/json" + "application/binary" ] } }, @@ -36,13 +36,12 @@ const DocumentProtocol = { }, { who: "author", - of: "parentId", can: "write" } ] } } -} +} as const export namespace Record { export type File = Blob From 326a9e699811359549718ec0111a37c7889eb1f7 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Fri, 5 Jan 2024 13:27:32 +0100 Subject: [PATCH 025/120] added contact link to nav --- tauri-app/src/components/MobileNavbar/index.tsx | 6 ++++++ tauri-app/src/components/Navbar/index.tsx | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/tauri-app/src/components/MobileNavbar/index.tsx b/tauri-app/src/components/MobileNavbar/index.tsx index 8fd49dd..bf5ec08 100644 --- a/tauri-app/src/components/MobileNavbar/index.tsx +++ b/tauri-app/src/components/MobileNavbar/index.tsx @@ -31,6 +31,12 @@ const index = () => { 99+
+ +
+ +

Contact

+
+
); }; diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index 306f248..dbdee85 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -36,6 +36,12 @@ const index = () => { 99+
+ +
+ +

Contact

+
+

Join us!

From e1a644c57dfea7480f430c928874981282eae4be Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Fri, 5 Jan 2024 14:29:43 +0100 Subject: [PATCH 026/120] landing page ficed --- tauri-app/src/pages/Home/index.css | 5 ++--- tauri-app/src/pages/Home/index.tsx | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tauri-app/src/pages/Home/index.css b/tauri-app/src/pages/Home/index.css index 991884d..1016240 100644 --- a/tauri-app/src/pages/Home/index.css +++ b/tauri-app/src/pages/Home/index.css @@ -21,13 +21,13 @@ margin: 20px 0px; } -.header { +#header { font-family: "Roboto"; font-size: 20px; font-weight: 500; } -.header b { +#header b { font-family: "Pacifico"; text-transform: capitalize; color: var(--color-blue); @@ -150,7 +150,6 @@ } @keyframes morphBorder { - 0%, 100% { border-radius: 70% 30% 41% 59% / 47% 73% 27% 53%; diff --git a/tauri-app/src/pages/Home/index.tsx b/tauri-app/src/pages/Home/index.tsx index 45fb46d..0e8f03e 100644 --- a/tauri-app/src/pages/Home/index.tsx +++ b/tauri-app/src/pages/Home/index.tsx @@ -6,7 +6,7 @@ export default function HomePage() {
- + Hi welcome to, pulsePal From f7fd39c174801c8646e44b1cd4a8c97aac0093d2 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Fri, 5 Jan 2024 15:14:50 +0100 Subject: [PATCH 027/120] fix add card modal padding --- .../src/components/AddCardComponent/index.css | 33 +++++++++++++++---- .../src/components/AddCardComponent/index.tsx | 2 +- .../components/AddRemedyComponent/index.css | 8 ++--- .../components/AddRemedyComponent/index.tsx | 2 +- .../components/DetailCardComponent/index.css | 21 ++++++++++-- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/tauri-app/src/components/AddCardComponent/index.css b/tauri-app/src/components/AddCardComponent/index.css index 62a2e57..a10a401 100644 --- a/tauri-app/src/components/AddCardComponent/index.css +++ b/tauri-app/src/components/AddCardComponent/index.css @@ -1,7 +1,7 @@ .main-add-card-container { background: var(--color-white); width: 500px; - min-height: 300px; + max-height: 600px; position: relative; z-index: 7; border-radius: 15px; @@ -21,6 +21,25 @@ justify-content: space-between; align-items: center; flex-direction: column; + padding: 10px; + overflow-y: scroll; + min-height: 300px; +} + +.input-form::-webkit-scrollbar { + width: 6px; +} + +.input-form::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1); + border-radius: 5px; +} + +.input-form::-webkit-scrollbar-thumb { + width: 2px; + background: var(--color-blue); + border-radius: 5px; + margin: 0 3px; } .input-form input[type="text"] { @@ -74,9 +93,9 @@ border: 2px solid var(--color-blue); border-style: dashed; border-radius: 15px; - width: 100%; - height: 100px; - margin: 15px 0; + width: 90%; + min-height: 60px; + margin: 15px; display: flex; justify-content: center; align-items: center; @@ -86,9 +105,9 @@ .form-container-active { border: 2px solid var(--color-green); border-radius: 15px; - width: 100%; - height: 100px; - margin: 15px 0; + width: 90%; + min-height: 60px; + margin: 15px; display: flex; justify-content: center; align-items: center; diff --git a/tauri-app/src/components/AddCardComponent/index.tsx b/tauri-app/src/components/AddCardComponent/index.tsx index 3da12d8..9e324bd 100644 --- a/tauri-app/src/components/AddCardComponent/index.tsx +++ b/tauri-app/src/components/AddCardComponent/index.tsx @@ -9,7 +9,7 @@ const FileUploader = () => { const [file, setFile] = useState({ file: null }); return ( -
+
{ setFile({ file: e?.target?.files?.[0] }); diff --git a/tauri-app/src/components/AddRemedyComponent/index.css b/tauri-app/src/components/AddRemedyComponent/index.css index 6d610f5..13c1aa5 100644 --- a/tauri-app/src/components/AddRemedyComponent/index.css +++ b/tauri-app/src/components/AddRemedyComponent/index.css @@ -29,7 +29,7 @@ flex-direction: column; overflow-y: scroll; overflow-x: hidden; - max-height: 300px; + height: 400px; } .input-form::-webkit-scrollbar { @@ -101,7 +101,7 @@ border-style: dashed; border-radius: 15px; width: 100%; - height: 100px; + min-height: 60px; margin: 15px 0; display: flex; justify-content: center; @@ -113,7 +113,7 @@ border: 2px solid var(--color-green); border-radius: 15px; width: 100%; - height: 100px; + min-height: 60px; margin: 15px 0; display: flex; justify-content: center; @@ -167,7 +167,7 @@ } .uploader-content { - width: 100%; + width: 90%; } @media (max-width: 750px) { diff --git a/tauri-app/src/components/AddRemedyComponent/index.tsx b/tauri-app/src/components/AddRemedyComponent/index.tsx index 31d8dc4..323808c 100644 --- a/tauri-app/src/components/AddRemedyComponent/index.tsx +++ b/tauri-app/src/components/AddRemedyComponent/index.tsx @@ -9,7 +9,7 @@ const FileUploader: FC = () => { const [file, setFile] = useState({ file: null }); return ( -
+
{ setFile({ file: e?.target?.files?.[0] }); diff --git a/tauri-app/src/components/DetailCardComponent/index.css b/tauri-app/src/components/DetailCardComponent/index.css index 093fbff..e93f6dd 100644 --- a/tauri-app/src/components/DetailCardComponent/index.css +++ b/tauri-app/src/components/DetailCardComponent/index.css @@ -1,12 +1,11 @@ .main-detail-container { width: 500px; - min-height: 450px; + max-height: 600px; background: var(--color-white); padding: var(--padding-desktop); border-radius: 15px; position: relative; margin-top: 20px; - overflow-y: scroll; } .main-detail-container h1 { @@ -24,6 +23,24 @@ .main-detail-container p { margin: 20px 0; font-family: "Open Sans"; + max-height: 300px; + overflow-y: scroll; +} + +.main-detail-container::-webkit-scrollbar { + width: 6px; +} + +.main-detail-container::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1); + border-radius: 5px; +} + +.main-detail-container::-webkit-scrollbar-thumb { + width: 2px; + background: var(--color-blue); + border-radius: 5px; + margin: 0 3px; } .close-btn { From 521207eb47b9de63522542fa9c017ec599c9074b Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 14:54:26 +0000 Subject: [PATCH 028/120] updated the protocol --- tauri-app/src/stores/useWeb5Store.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tauri-app/src/stores/useWeb5Store.ts b/tauri-app/src/stores/useWeb5Store.ts index 9f0a7a9..ba32509 100644 --- a/tauri-app/src/stores/useWeb5Store.ts +++ b/tauri-app/src/stores/useWeb5Store.ts @@ -1,6 +1,7 @@ import { Web5 } from "@web5/api/browser"; import { create } from "zustand"; import ConditionsProtocol from "@/utils/protocols/conditions"; +import DocumentProtocol from "@/utils/protocols/document"; interface Web5State { web5: Web5 | null; @@ -68,7 +69,7 @@ const useWeb5Store = create((set, get) => ({ // configure protocol on local DWN const { protocol, status: protocolConfigurationStatus } = await web5.dwn.protocols.configure({ message: { - definition: p, + definition: Object.assign(p), }, }); if (!protocol) { @@ -202,4 +203,4 @@ export const schemaOrgProtocolDefinition = { }, }; -const protocols = [schemaOrgProtocolDefinition, ConditionsProtocol]; +const protocols = [schemaOrgProtocolDefinition, ConditionsProtocol, DocumentProtocol]; From 6eba629e49187d095bd4c44abd6cc08dbf57c830 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 14:54:32 +0000 Subject: [PATCH 029/120] updated the medic page --- tauri-app/src/pages/medic.tsx | 99 ++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/tauri-app/src/pages/medic.tsx b/tauri-app/src/pages/medic.tsx index 9ae13ff..b732166 100644 --- a/tauri-app/src/pages/medic.tsx +++ b/tauri-app/src/pages/medic.tsx @@ -1,6 +1,9 @@ import { FunctionComponent, useEffect, useState } from "react"; -import useWeb5Store from "@/stores/useWeb5Store"; -import { useDocuments } from "@/stores/useDocuments"; +import useWeb5Store from "@/stores/useWeb5Store"; +import DocumentUtils from "@/utils/document"; +import { Record as DocumentRecord } from "@/utils/protocols/document"; +import { Record as Web5Record } from "@web5/api/browser"; +import AuthGuard from "@/components/Auth/Guard"; const possibleConditions = [ "Cancer", @@ -11,55 +14,46 @@ const possibleConditions = [ "Mental Illness", ] -const MedicPage: FunctionComponent = () => { - const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })) - const { fetchDocuments, documents, createDocument, getDocumentFile } = useDocuments(web5, did) - const [docsWithImageUrls, setDocsWithImageUrls] = useState<{ - document: typeof documents[0], - url: string - }[]>([]) - - const [form, setForm] = useState<{ - name: string - doc: File, - condition: string - }>({ +const Page: FunctionComponent = () => { + const agent = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })) + const [documentsWithUrl, setDocumentsWithUrl] = useState<{ document: DocumentRecord.Document, fileUrl: string, record: Web5Record }[]>([]) + const [form, setForm] = useState({ name: "", - doc: new File([], ""), - condition: "" + file: new File([], ""), + condition: possibleConditions[0] }) useEffect(() => { - if (web5) { - fetchDocuments() - } - }, [web5]) - - async function processDocsImage() { - const docsWithImageUrls: { document: typeof documents[0], url: string }[] = [] - - for (const doc of documents) { - const file = await getDocumentFile(doc) - let url = "" - if (file) - url = URL.createObjectURL(file) - - docsWithImageUrls.push({ - document: doc, - url - }) - } - - setDocsWithImageUrls(docsWithImageUrls) - } - - useEffect(() => { - processDocsImage() - }, [documents]) + (async () => { + const docRecords = await DocumentUtils.fetchDocumentRecords(agent) + if (!docRecords) { + console.log("Failed to fetch document records") + return + } + + const docsWithUrl = [] + for (const docRecord of docRecords) { + const data: DocumentRecord.Document = await docRecord.data.json() + const fileRecord = await DocumentUtils.fetchBlobRecord(agent, data.url) + + if (!fileRecord) + continue + + const file = new File([await fileRecord.data.blob()], data.name, { type: data.encodingFormat }) + + docsWithUrl.push({ + record: docRecord, + document: data, + fileUrl: URL.createObjectURL(file), + }) + } + + setDocumentsWithUrl(docsWithUrl) + })() + }, []) const saveMedicalRecord = async () => { - console.log(form) - const res = await createDocument({ name: form.name ? form.name : undefined, file: form.doc, condition: form.condition }) + const res = await DocumentUtils.createDocumentRecord(agent, form) if (res) { alert(`Medical record saved: ${res}`) @@ -69,8 +63,6 @@ const MedicPage: FunctionComponent = () => { } } - console.log(documents) - return (
{ @@ -96,7 +88,7 @@ const MedicPage: FunctionComponent = () => { setForm({ ...form, - doc: file + file: file }) }} placeholder="Document" /> @@ -105,6 +97,7 @@ const MedicPage: FunctionComponent = () => {
diff --git a/tauri-app/src/components/UserProfile/index.css b/tauri-app/src/components/UserProfile/index.css new file mode 100644 index 0000000..2c3dd37 --- /dev/null +++ b/tauri-app/src/components/UserProfile/index.css @@ -0,0 +1,55 @@ +.userprofile-container { + box-shadow: var(--box-shadow-black); + width: 200px; + text-align: center; + border-radius: 15px; + padding: 8px 12px; + position: relative; +} + +.userprofile-info-container img { + width: 80px; + height: 80px; + border-radius: 50%; + background: var(--color-white); + padding: 10px; + position: absolute; + top: 80px; + left: 50%; + transform: translateX(-50%); +} + +.userprofile-info-container p { + font-family: "Open Sans"; + margin-top: 40px; +} + +.cover-container { + height: 130px; + border-radius: 15px; + text-align: left; +} + +.cover-container h3 { + color: var(--color-white); + font-family: "Roboto"; + font-size: 18px; + position: relative; + left: 6px; + top: 10px; +} + +.cover-container p { + color: var(--color-white); + font-family: "Open Sans"; + font-size: 14px; + position: relative; + left: 6px; + top: 15px; +} + +@media (max-width: 750px) { + .userprofile-container { + width: 100%; + } +} diff --git a/tauri-app/src/components/UserProfile/index.tsx b/tauri-app/src/components/UserProfile/index.tsx new file mode 100644 index 0000000..59c87f0 --- /dev/null +++ b/tauri-app/src/components/UserProfile/index.tsx @@ -0,0 +1,42 @@ +import React, { FC } from "react"; + +import "./index.css"; + +interface UserProfileProps { + username: String; + profile_pic: String; + cover_pic: String; + about_user: String; + friends: Number; +} +const index: FC = ({ + username, + profile_pic, + cover_pic, + about_user, + friends, +}) => { + return ( +
+
+

@{username}

+

+ Friends | {friends} +

+
+
+ +

{about_user}

+
+
+ ); +}; + +export default index; diff --git a/tauri-app/src/pages/Chat/index.css b/tauri-app/src/pages/Chat/index.css index e69de29..322a4e5 100644 --- a/tauri-app/src/pages/Chat/index.css +++ b/tauri-app/src/pages/Chat/index.css @@ -0,0 +1,12 @@ +.main-chat-container { + padding: var(--padding-desktop); + display: flex; + justify-content: center; + align-items: center; +} + +@media (max-width: 750px) { + .main-chat-container { + padding: var(--padding-mobile); + } +} diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index ab8d90e..89b5b1f 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -1,9 +1,18 @@ import "./index.css"; +import UserProfile from "../../components/UserProfile/"; -const index= () => { +const index = () => { return ( -
-

Chat Page

+
+
); }; From 2e416aacb1a371fc422eef09b23c0bd336ad37f4 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 19:29:46 +0000 Subject: [PATCH 039/120] updated the protocol defs --- tauri-app/src/utils/document.ts | 2 + tauri-app/src/utils/medical-document.ts | 206 ------------------------ tauri-app/src/utils/protocols/defns.ts | 2 +- tauri-app/src/utils/protocols/user.ts | 2 + tauri-app/src/utils/user.ts | 180 +++++++++++++++++++++ 5 files changed, 185 insertions(+), 207 deletions(-) delete mode 100644 tauri-app/src/utils/medical-document.ts create mode 100644 tauri-app/src/utils/user.ts diff --git a/tauri-app/src/utils/document.ts b/tauri-app/src/utils/document.ts index 01c36de..7ffa21d 100644 --- a/tauri-app/src/utils/document.ts +++ b/tauri-app/src/utils/document.ts @@ -238,6 +238,8 @@ const DocumentUtils = { fetchDocumentRecords, updateDocumentRecord, createDocumentRecord, + createBlobRecord, + updateBlobRecord, fetchBlobRecord, } diff --git a/tauri-app/src/utils/medical-document.ts b/tauri-app/src/utils/medical-document.ts deleted file mode 100644 index 7296af3..0000000 --- a/tauri-app/src/utils/medical-document.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { Record as Web5Record, Web5 } from "@web5/api" - -export namespace MedicalRecord { - export type NullFlavor = "253|unknown|" | "271|no information|" | "272|masked|" | "273|not applicable|" - - export type QuantityComment = { - "@type": "DV_TEXT", - value: string - } - - export type QuantityMagnitude = { - "@type": "DV_MAGNITUDE", - magnitude: number, - unit: string, - comment?: string - } - - type Quantity = QuantityMagnitude | QuantityComment - - export type Element = { - "@type": "ELEMENT", - name: string, - value: Quantity - } & ({ - null_flavor?: NullFlavor, - null_reason?: string - } | { - null_flavor: NullFlavor, - null_reason: string - }) - - export type ItemSingle = { - "@type": "ITEM_SINGLE", - item: Element - } - - export type ItemList = { - "@type": "ITEM_LIST", - items: Item[] - } - - export type Item = ItemSingle | ItemList - - export type HistoryEvent = { - "@type": "EVENT", - time: Date, - state: Item - } - - export type History = { - "@type": "HISTORY", - origin?: Date, - period?: Date, - duration?: Date, - events: HistoryEvent[] - } - - export type Document = { - history?: History, - comment?: string - } -} - -export function createQuantityMagnitude(quantity: Omit): MedicalRecord.QuantityMagnitude { - return { - ...quantity, - "@type": "DV_MAGNITUDE" - } -} - -export function createQuantityComment(quantity: Omit): MedicalRecord.QuantityComment { - return { - ...quantity, - "@type": "DV_TEXT" - } -} - - -export function createItem(element: Omit): MedicalRecord.ItemSingle { - return { - "@type": "ITEM_SINGLE", - item: { - ...element, - "@type": "ELEMENT" - } - } -} - -export class MedicalDocument { - declare private _web5: Web5 - declare private _protocol: string - private _id: string | undefined = undefined - declare private _history: MedicalRecord.History - private _comment: string | undefined = "" - declare private _record: Web5Record - - constructor(web5: Web5, protocol: string, doc?: MedicalRecord.Document & { id: string }) { - this._web5 = web5 - this._protocol = protocol - - this._history = { - "@type": "HISTORY", - events: [] - } - - if (doc) { - if (doc.history) - this._history = doc.history - this._comment = doc.comment - this._id = doc.id - } - } - - setHistory(payload: { origin?: Date, period?: Date, duration?: Date }) { - this._history = { - '@type': 'HISTORY', - origin: payload.origin, - period: payload.period, - duration: payload.duration, - events: [] - } - } - - addHistoryEvent(payload: { time: Date, state: MedicalRecord.Item }) { - this._history.events.push({ - "@type": "EVENT", - time: payload.time, - state: payload.state - }) - - return this._history.events.length - 1 - } - - set comment(comment: string | undefined) { - this._comment = comment - } - - get comment() { - return this._comment - } - - static async getById(web5: Web5, protocol: string, id: string) { - const { records } = await web5.dwn.records.query({ - message: { - filter: { - recordId: id, - protocol - } - } - }) - - if (!records) - return null - - const firstRecordResponse = records[0] - if (!firstRecordResponse) - return null - - const medicalRecord: MedicalRecord.Document = await firstRecordResponse.data.json() - - return new MedicalDocument(web5, protocol, Object.assign(medicalRecord, { id })) - } - - async save(): Promise { - let record: Web5Record | undefined = undefined - - if (this._id) { - const res = await this._record.update({ - data: { - history: this._history, - comment: this._comment - } - }) - - if (res.status.code === 200) - return this._id - - return false - } - - const res = await this._web5.dwn.records.create({ - data: { - "@context": "https://schema.org", - "@type": "MEDICAL_RECORD", - history: this._history, - comment: this._comment - }, - message: { - schema: "https://schema.org/Person", - dataFormat: "application/json", - protocol: this._protocol, - protocolPath: "person", - }, - }) - - record = res.record - console.log(res) - - if (!record) - return false - - this._id = record.id - - return record.id - } -} diff --git a/tauri-app/src/utils/protocols/defns.ts b/tauri-app/src/utils/protocols/defns.ts index 9a68b17..89846ca 100644 --- a/tauri-app/src/utils/protocols/defns.ts +++ b/tauri-app/src/utils/protocols/defns.ts @@ -1 +1 @@ -export const url = "https://dschema.org/v0.0.1" as const +export const url = "https://dschema.org/v0.0.2" as const diff --git a/tauri-app/src/utils/protocols/user.ts b/tauri-app/src/utils/protocols/user.ts index fd61a66..afbc382 100644 --- a/tauri-app/src/utils/protocols/user.ts +++ b/tauri-app/src/utils/protocols/user.ts @@ -17,6 +17,7 @@ const UserDetailsProtocol = { $actions: [ { who: "author", + of: "details", can: "read" }, { @@ -33,6 +34,7 @@ export namespace Record { firstName: string lastName: string profilePictureUrl: string + dateCreated: string } } diff --git a/tauri-app/src/utils/user.ts b/tauri-app/src/utils/user.ts new file mode 100644 index 0000000..44a53a2 --- /dev/null +++ b/tauri-app/src/utils/user.ts @@ -0,0 +1,180 @@ +import { Web5, Record as Web5Record } from "@web5/api/browser" +import UserDetailsProtocol, { Record as UserDetailsProtocolRecord, did as UserDetailsProtocolDID } from "./protocols/user"; +import DocumentUtils from "./document"; +import _ from "lodash"; + +type Agent = { + web5: Web5 + did: string +} + +type FilterObj = { + recordId: string, +} + +type Type = keyof typeof UserDetailsProtocol["types"] +type Schema = typeof UserDetailsProtocol["types"][T]["schema"] +type DataFormat = typeof UserDetailsProtocol["types"][T]["dataFormats"][number] + +type FullFilterObj = { + protocolPath: T + schema: Schema +} + +type FullMessageObj = { + schema: Schema + protocolPath: T + dataFormat: DataFormat + published: typeof UserDetailsProtocol["published"] +} + +async function createRecord(agent: Agent, data: UserDetailsProtocolRecord.Details, message: FullMessageObj) { + const { record, status } = await agent.web5.dwn.records.create({ + data, + message: Object.assign({ + ...message, + protocol: UserDetailsProtocol.protocol, + }) + }); + + if (!record) { + console.error("Failed to create record:", status) + return false + } + + const { status: syncStatus } = await record.send(UserDetailsProtocolDID) + + if (syncStatus.code !== 202) { + console.log("Failed to sync record with remote DWN:", syncStatus) + } + + return record +} + +async function fetchRecords(agent: Agent, filter: FullFilterObj) { + const { records, status } = await agent.web5.dwn.records.query({ + from: UserDetailsProtocolDID, + message: { + filter: { + ...filter, + protocol: UserDetailsProtocol.protocol, + }, + // @ts-ignore + dateSort: "createdAscending", + }, + }); + + if (!records) { + console.log("Failed to fetch records:", status) + return false + } + return records +} + +async function fetchUserDetailsRecord(agent: Agent) { + const records = await fetchRecords(agent, { + schema: UserDetailsProtocol.types.details.schema, + protocolPath: "details", + }) + + if (!records || !records[0]) return false + + return records[0] +} + +async function fetchUserDetailsRecords(agent: Agent) { + return fetchRecords(agent, { + protocolPath: "details", + schema: UserDetailsProtocol.types.details.schema, + }) +} + +type UpdatePayload = Partial<{ + firstName: string + lastName: string + profilePicture: File +}> + +async function updateUserDetailsRecord(agent: Agent, idOrRecord: string | Web5Record, payload: Partial) { + let record: Web5Record + + if (typeof idOrRecord === "string") { + const fetchedRecord = await fetchUserDetailsRecord(agent, { recordId: idOrRecord }) + + if (!fetchedRecord) return false + + record = fetchedRecord + } + else { + record = idOrRecord + } + + const data: UserDetailsProtocolRecord.Details = await record.data.json() + const { profilePicture, ...restPayload } = payload + + let url = data.profilePictureUrl + if (profilePicture) { + const blobRecord = await DocumentUtils.updateBlobRecord(agent, url, profilePicture) + if (!blobRecord) return false + + url = blobRecord.id + } + + const { status } = await record.update({ + data: _.merge(data, Object.assign(restPayload, { url })) + }) + + if (status.code !== 202) { + console.log("Failed to sync document record update with remote DWN:", status) + return false + } + + return record +} + +type CreatePayload = { + firstName: string + lastName: string + profilePicture: File, +} +async function createUserDetailsRecord(agent: Agent, payload: CreatePayload) { + const existingRecord = await fetchUserDetailsRecord(agent) + if (existingRecord) { + console.error("User details record already exists") + return false + } + + const blobRecord = await DocumentUtils.createBlobRecord(agent, payload.profilePicture) + if (!blobRecord) return false + + const { profilePicture, ...restPayload } = payload + + const record = await createRecord( + agent, + { + ...restPayload, + profilePictureUrl: blobRecord.id, + dateCreated: new Date().toISOString() + }, + { + schema: UserDetailsProtocol.types.details.schema, + protocolPath: "details", + dataFormat: UserDetailsProtocol.types.details.dataFormats[0], + published: UserDetailsProtocol.published, + }) + + if (!record) { + console.error("Failed to create document record") + return false + } + + return record +} + +const UserDetailsUtils = { + fetchUserDetailsRecord, + updateUserDetailsRecord, + createUserDetailsRecord, +} + +export default UserDetailsUtils From 336689b1e060f21843d37784156660e70007bc8b Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 19:29:53 +0000 Subject: [PATCH 040/120] added new components for the auth --- .../src/components/Auth/Account/Guard.tsx | 18 ++++++++++++++++++ tauri-app/src/components/Navbar/index.tsx | 16 ++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 tauri-app/src/components/Auth/Account/Guard.tsx diff --git a/tauri-app/src/components/Auth/Account/Guard.tsx b/tauri-app/src/components/Auth/Account/Guard.tsx new file mode 100644 index 0000000..c558411 --- /dev/null +++ b/tauri-app/src/components/Auth/Account/Guard.tsx @@ -0,0 +1,18 @@ +import { PropsWithChildren, ReactNode } from "react"; +import AuthGuard from "../Guard"; +import { useProfile } from "@/stores/profile"; + +const Guard = ({ children, fallback }: PropsWithChildren & { fallback?: ReactNode }) => { + const isSignedIn = useProfile(state => state.state.isSignedIn) + + if (!isSignedIn) + return <>{fallback} ?? null + + return <>{children} +} + +export default function AccountGuard(props: PropsWithChildren & { fallback?: ReactNode }) { + return + + +} diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index dbdee85..71fc31e 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -1,3 +1,4 @@ +import AccountGuard from "../Auth/Account/Guard"; import "./index.css"; import { NavLink } from "react-router-dom"; @@ -43,10 +44,17 @@ const index = () => {
-
-

Join us!

- -
+ +

Join us!

+ +
+ }> +
+

Profile

+ +
+
); }; From 3e86282f6f0dafcd8667b9c4676241b8593edecb Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 19:30:00 +0000 Subject: [PATCH 041/120] added a new profile store --- tauri-app/src/stores/profile.ts | 77 +++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tauri-app/src/stores/profile.ts diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts new file mode 100644 index 0000000..df439f2 --- /dev/null +++ b/tauri-app/src/stores/profile.ts @@ -0,0 +1,77 @@ +import { create } from "zustand" +import { combine } from "zustand/middleware"; +import { Record as UserDetailsProtocolRecord } from "@/utils/protocols/user"; +import { Agent } from "@/components/Auth/types"; +import UserDetailsUtils from "@/utils/user"; +import DocumentUtils from "@/utils/document"; + +type State = { + profile: { + firstName: string, + lastName: string, + profilePictureUrl: string + }, + isSignedIn: true +} | { + profile: null, + isSignedIn: false +} + +type Payload = { + firstName: string, + lastName: string, + profilePicture: File +} + +export const useProfile = create( + combine({ + state: { + profile: null, + isSignedIn: false + } as State + }, (set, get) => ({ + signOut: () => { + if (get().state.isSignedIn) { + set({ + state: { + isSignedIn: false, + profile: null + } + }) + } + }, + signIn: async (agent: Agent) => { + const profileRecord = await UserDetailsUtils.fetchUserDetailsRecord(agent) + if (!profileRecord) return false + + const profile: UserDetailsProtocolRecord.Details = await profileRecord.data.json() + console.log(profile) + + const profilePicture = await DocumentUtils.fetchBlobRecord(agent, profile.profilePictureUrl) + let profilePictureUrl = "" + if (profilePicture) { + const profilePictureBlob = await profilePicture.data.blob() + profilePictureUrl = URL.createObjectURL(profilePictureBlob) + } + + set({ + state: { + isSignedIn: true, + profile: { + firstName: profile.firstName, + lastName: profile.lastName, + profilePictureUrl + } + } + }) + + return true + }, + signUp: async (agent: Agent, payload: Payload) => { + const profile = await UserDetailsUtils.createUserDetailsRecord(agent, payload) + if (!profile) return false + + return true + } + })) +) From 8253b5d277a3d1629a420898a637fe5ca22cd19e Mon Sep 17 00:00:00 2001 From: Adophilus Date: Fri, 5 Jan 2024 19:30:15 +0000 Subject: [PATCH 042/120] updated the es version on the server --- server/tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/tsconfig.json b/server/tsconfig.json index b77ecc0..880f229 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -5,6 +5,7 @@ "noImplicitAny": true, "noFallthroughCasesInSwitch": true, "module": "CommonJS", + "target": "ES2020", "baseUrl": ".", "paths": { "@backend/*": ["./src/*"], @@ -12,7 +13,7 @@ } }, "include": [ - "server.ts", + "*.ts", "./src/**/*.ts" ], "exclude": [ From 6e07780dcb36ca11498922e45f4d8cb3c01e3095 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Fri, 5 Jan 2024 22:04:33 +0100 Subject: [PATCH 043/120] fixed some bugs again --- tauri-app/src/components/AddCardComponent/index.css | 3 ++- tauri-app/src/components/AddRemedyComponent/index.css | 3 ++- tauri-app/src/components/Navbar/index.css | 2 +- tauri-app/src/pages/Remedies/index.css | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tauri-app/src/components/AddCardComponent/index.css b/tauri-app/src/components/AddCardComponent/index.css index a10a401..e82047b 100644 --- a/tauri-app/src/components/AddCardComponent/index.css +++ b/tauri-app/src/components/AddCardComponent/index.css @@ -23,7 +23,8 @@ flex-direction: column; padding: 10px; overflow-y: scroll; - min-height: 300px; + overflow-x: hidden; + max-height: 300px; } .input-form::-webkit-scrollbar { diff --git a/tauri-app/src/components/AddRemedyComponent/index.css b/tauri-app/src/components/AddRemedyComponent/index.css index b2ba7cd..47a106b 100644 --- a/tauri-app/src/components/AddRemedyComponent/index.css +++ b/tauri-app/src/components/AddRemedyComponent/index.css @@ -29,7 +29,8 @@ flex-direction: column; padding: 10px; overflow-y: scroll; - height: 300px; + overflow-x: hidden; + max-height: 300px; } .input-form-r::-webkit-scrollbar { diff --git a/tauri-app/src/components/Navbar/index.css b/tauri-app/src/components/Navbar/index.css index 9ec3d00..056aa0b 100644 --- a/tauri-app/src/components/Navbar/index.css +++ b/tauri-app/src/components/Navbar/index.css @@ -7,7 +7,7 @@ position: sticky; top: 0; background: var(--color-white); - z-index: 8; + z-index: 10; } .logo_container { diff --git a/tauri-app/src/pages/Remedies/index.css b/tauri-app/src/pages/Remedies/index.css index 52d4931..483959e 100644 --- a/tauri-app/src/pages/Remedies/index.css +++ b/tauri-app/src/pages/Remedies/index.css @@ -69,6 +69,7 @@ justify-content: center; align-items: center; z-index: 6; + margin-top: 30px; } .active-remedy-container { From 457d3a51acd732746f2609d617a2df65b417746b Mon Sep 17 00:00:00 2001 From: coder12git Date: Sat, 6 Jan 2024 08:18:50 +0530 Subject: [PATCH 044/120] integrated remedy Signed-off-by: coder12git --- tauri-app/src/App.tsx | 2 - .../components/AddRemedyComponent/index.tsx | 46 +++++----- tauri-app/src/components/Navbar/index.tsx | 2 +- tauri-app/src/components/RemedyCard/index.tsx | 14 ++- tauri-app/src/pages/Remedies/index.tsx | 89 ++++++++++--------- tauri-app/src/pages/remedy.tsx | 75 ++++++++++------ tauri-app/src/stores/useRemedy.ts | 10 ++- 7 files changed, 133 insertions(+), 105 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 043b4b3..3035450 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -9,7 +9,6 @@ import Doctors from "./pages/nearbyDoctor"; import HomePage from "./pages/Home"; import SharedLayout from "./pages/SharedLayout/"; import Records from "./pages/Records"; -import Remedies from "./pages/Remedies"; import Chat from "./pages/Chat/"; import Contact from "./pages/Contact/"; @@ -20,7 +19,6 @@ const router = createHashRouter([ children: [ { path: "/", element: }, { path: "/records", element: }, - { path: "/remedies", element: }, { path: "/connect", element: }, { path: "/remedy", element: }, { path: "/medic", element: }, diff --git a/tauri-app/src/components/AddRemedyComponent/index.tsx b/tauri-app/src/components/AddRemedyComponent/index.tsx index 323808c..9d00665 100644 --- a/tauri-app/src/components/AddRemedyComponent/index.tsx +++ b/tauri-app/src/components/AddRemedyComponent/index.tsx @@ -1,5 +1,6 @@ import "./index.css"; import React, { FC, useState } from "react"; +import Remedies from '../../pages/Remedies' interface FileProp { file: File | null | undefined; @@ -37,7 +38,8 @@ const StepField: FC = ({ index }) => { ); }; -const index: FC = () => { +//@ts-ignore +const index: FC = ({saveFunc, formFunc, form}) => { const [steps, setSteps] = useState([ , ]); @@ -45,29 +47,29 @@ const index: FC = () => { return (

Create New Remedy

- + {/* */} + { + e.preventDefault() + saveFunc() + }} + >
- - -
-
- setSteps([...steps, ]) - } - > - -
- {steps.map((Field) => { - return Field; - })} -
- -

- *ensure inputted information are correct as once saved it cannot be - deleted/edited -

+ formFunc({ ...form, name: e.target.value })} + /> + + + +
+
+ )}
); diff --git a/tauri-app/src/pages/Remedies/index.css b/tauri-app/src/pages/Remedies/index.css index 483959e..e39bc8a 100644 --- a/tauri-app/src/pages/Remedies/index.css +++ b/tauri-app/src/pages/Remedies/index.css @@ -33,7 +33,7 @@ align-items: center; border-radius: 50%; cursor: pointer; - z-index: 8; + z-index: 9; } .close-add-records-btn { @@ -48,7 +48,7 @@ align-items: center; border-radius: 50%; cursor: pointer; - z-index: 8; + z-index: 9; transform: rotate(45deg); transition: 0.3s; } @@ -69,7 +69,7 @@ justify-content: center; align-items: center; z-index: 6; - margin-top: 30px; + margin-top: 40px; } .active-remedy-container { diff --git a/tauri-app/src/stores/pulseGlobalStore.ts b/tauri-app/src/stores/pulseGlobalStore.ts new file mode 100644 index 0000000..069b0b7 --- /dev/null +++ b/tauri-app/src/stores/pulseGlobalStore.ts @@ -0,0 +1,13 @@ +import { create } from "zustand"; + +type PulseGlobalStore = { + isAuthBtnClicked: boolean; + toggleIsAuthBtnClicked: () => void; +}; + +export const usePulseGlobalStore = create((set) => ({ + isAuthBtnClicked: true, + toggleIsAuthBtnClicked: () => { + set((state) => ({ isAuthBtnClicked: !state.isAuthBtnClicked })); + }, +})); From 7b6bf959963f896b6c9f2691723bd5bbe1261b97 Mon Sep 17 00:00:00 2001 From: coder12git Date: Sat, 6 Jan 2024 19:03:10 +0530 Subject: [PATCH 054/120] fixed remedy bug Signed-off-by: coder12git --- tauri-app/src/components/RemedyCard/index.tsx | 4 ++-- tauri-app/src/pages/Remedies/index.tsx | 12 ++++++------ tauri-app/src/pages/remedy.tsx | 2 +- tauri-app/src/stores/useRemedy.ts | 1 + 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tauri-app/src/components/RemedyCard/index.tsx b/tauri-app/src/components/RemedyCard/index.tsx index 4acf880..0144f85 100644 --- a/tauri-app/src/components/RemedyCard/index.tsx +++ b/tauri-app/src/components/RemedyCard/index.tsx @@ -60,7 +60,7 @@ const index = ({ // @ts-ignore description, // @ts-ignore - created_by, url, + created_by, useUrl, // @ts-ignore rating, // @ts-ignore @@ -70,7 +70,7 @@ const index = ({
{ description: "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat...", desc: "Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis.", - url: "/pg.jpg", + useUrl: "/pg.jpg", rating: '1.5', created_by: "draky", // steps: [ @@ -31,7 +31,7 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { name: "Aloe Vera Eczema Fix", description: "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat...", - url: "/pg.jpg", + useUrl: "/pg.jpg", rating: '4', created_by: "dave", }, @@ -39,7 +39,7 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { name: "Asthma Breathing Exercises", description: "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat...", - url: "/pg.jpg", + useUrl: "/pg.jpg", rating: '3.5', created_by: "nikki", }, @@ -105,7 +105,7 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { { { className="rimg-container" style={{ // @ts-ignore - background: `url(/pg.jpg)`, + background: `url(${activeRemedy.useUrl})`, backgroundPosition: "center", backgroundSize: "cover", }} diff --git a/tauri-app/src/pages/remedy.tsx b/tauri-app/src/pages/remedy.tsx index 7fb9f6f..eb39b90 100644 --- a/tauri-app/src/pages/remedy.tsx +++ b/tauri-app/src/pages/remedy.tsx @@ -57,7 +57,7 @@ const Remedy: FunctionComponent = () => { if (file) url = URL.createObjectURL(file) console.log(url); - + doc.data.useUrl=url docsWithImageUrls.push({ document: doc, url diff --git a/tauri-app/src/stores/useRemedy.ts b/tauri-app/src/stores/useRemedy.ts index 4170818..8e5199e 100644 --- a/tauri-app/src/stores/useRemedy.ts +++ b/tauri-app/src/stores/useRemedy.ts @@ -9,6 +9,7 @@ export type Remedy = { name: string; description: string; created_by: string; + useUrl: string; encodingFormat: string; size: string; url: string; From 891f92544bdfe3749fc08aa83d1b597ce143c119 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Sat, 6 Jan 2024 14:48:37 +0100 Subject: [PATCH 055/120] fixed buttin z-index --- tauri-app/src/App.tsx | 4 +- tauri-app/src/components/RemedyCard/index.tsx | 2 +- tauri-app/src/pages/Remedies/index.css | 4 +- tauri-app/src/pages/Remedies/index.tsx | 75 +++++++++++-------- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 28269fe..ff8e222 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -35,7 +35,9 @@ function App() { if (!web5) connect(); }, []); - return <>{web5 ? :
Connecting...
}; + return ( + <>{true ? :
Connecting...
} + ); } export default App; diff --git a/tauri-app/src/components/RemedyCard/index.tsx b/tauri-app/src/components/RemedyCard/index.tsx index 5110d2c..79e6422 100644 --- a/tauri-app/src/components/RemedyCard/index.tsx +++ b/tauri-app/src/components/RemedyCard/index.tsx @@ -45,7 +45,7 @@ const index = ({
-

{desc_snippet.slice(0, 150) + "..."}

+

{description.substring(0, 150) + "..."}

diff --git a/tauri-app/src/pages/Remedies/index.css b/tauri-app/src/pages/Remedies/index.css index e39bc8a..cffe86d 100644 --- a/tauri-app/src/pages/Remedies/index.css +++ b/tauri-app/src/pages/Remedies/index.css @@ -33,7 +33,7 @@ align-items: center; border-radius: 50%; cursor: pointer; - z-index: 9; + z-index: 8; } .close-add-records-btn { @@ -48,7 +48,7 @@ align-items: center; border-radius: 50%; cursor: pointer; - z-index: 9; + z-index: 8; transform: rotate(45deg); transition: 0.3s; } diff --git a/tauri-app/src/pages/Remedies/index.tsx b/tauri-app/src/pages/Remedies/index.tsx index e6fdc4c..c4ca609 100644 --- a/tauri-app/src/pages/Remedies/index.tsx +++ b/tauri-app/src/pages/Remedies/index.tsx @@ -6,7 +6,7 @@ import RemedyCard from "../../components/RemedyCard/"; import AddRemedyComponent from "../../components/AddRemedyComponent/"; import Remedy from "../remedy"; //@ts-ignore -const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { +const index = ({ save, formFunc, form, remediesData, docsWithImageUrls }) => { const [remedies, setRemedies] = useState([ { name: "Lavendar Scalp Treament", @@ -14,7 +14,7 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat...", desc: "Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis.", useUrl: "/pg.jpg", - rating: '1.5', + rating: "1.5", created_by: "draky", // steps: [ // { @@ -32,7 +32,7 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { description: "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat...", useUrl: "/pg.jpg", - rating: '4', + rating: "4", created_by: "dave", }, { @@ -40,7 +40,7 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { description: "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat...", useUrl: "/pg.jpg", - rating: '3.5', + rating: "3.5", created_by: "nikki", }, ]); @@ -48,7 +48,7 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { const [isDetailRemedyActive, setIsDetailRemedyActive] = useState(false); const [activeRemedy, setActiveRemedy] = useState(null); - const url = ''; + const url = ""; // @ts-ignore const remedyClicked = (remedyDetail) => { setActiveRemedy(remedyDetail); @@ -113,22 +113,23 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { ); })} - {/* Remedy Created by user */} - {//@ts-ignore - docsWithImageUrls.map(({document, url}) => { - return ( - - ); - })} + { + //@ts-ignore + docsWithImageUrls.map(({ document, url }) => { + return ( + + ); + }) + }
{isDetailRemedyActive && (
@@ -162,21 +163,30 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => {
Rate()} className="rd-container"> - {// @ts-ignore - activeRemedy.rating} + { + // @ts-ignore + activeRemedy.rating + }
-

{// @ts-ignore - activeRemedy.name}

+

+ { + // @ts-ignore + activeRemedy.name + }{" "} +

-

{ - // @ts-ignore - activeRemedy.description}

+

+ { + // @ts-ignore + activeRemedy.description + } +

@@ -185,11 +195,14 @@ const index = ({save, formFunc, form, remediesData, docsWithImageUrls}) => { {isAddRemedyActive && (
- +
)}
From 261b68cb0667a279a189833e3757632ee4522611 Mon Sep 17 00:00:00 2001 From: coder12git Date: Sat, 6 Jan 2024 22:57:53 +0530 Subject: [PATCH 056/120] fix text overflow in remedy Signed-off-by: coder12git --- tauri-app/src/components/RemedyCard/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tauri-app/src/components/RemedyCard/index.tsx b/tauri-app/src/components/RemedyCard/index.tsx index 79e6422..32ae41e 100644 --- a/tauri-app/src/components/RemedyCard/index.tsx +++ b/tauri-app/src/components/RemedyCard/index.tsx @@ -16,8 +16,7 @@ const index = ({ // @ts-ignore description, // @ts-ignore - created_by, - url, + created_by, useUrl, // @ts-ignore rating, // @ts-ignore @@ -27,7 +26,7 @@ const index = ({
-

{description.substring(0, 150) + "..."}

+

{description.substring(0,50) + "..."}

From ca7c7028fdc9edf220abc4f61c76177e91f3436e Mon Sep 17 00:00:00 2001 From: coder12git Date: Sat, 6 Jan 2024 23:14:02 +0530 Subject: [PATCH 057/120] Revert "fix text overflow in remedy" This reverts commit 261b68cb0667a279a189833e3757632ee4522611. --- tauri-app/src/components/RemedyCard/index.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tauri-app/src/components/RemedyCard/index.tsx b/tauri-app/src/components/RemedyCard/index.tsx index 32ae41e..79e6422 100644 --- a/tauri-app/src/components/RemedyCard/index.tsx +++ b/tauri-app/src/components/RemedyCard/index.tsx @@ -16,7 +16,8 @@ const index = ({ // @ts-ignore description, // @ts-ignore - created_by, useUrl, + created_by, + url, // @ts-ignore rating, // @ts-ignore @@ -26,7 +27,7 @@ const index = ({
-

{description.substring(0,50) + "..."}

+

{description.substring(0, 150) + "..."}

From d14636da7853f14601bdd49c075eaed236d7262d Mon Sep 17 00:00:00 2001 From: coder12git Date: Sat, 6 Jan 2024 23:18:59 +0530 Subject: [PATCH 058/120] changes Signed-off-by: coder12git --- tauri-app/src/App.tsx | 2 +- tauri-app/src/components/RemedyCard/index.tsx | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index ff8e222..de7a969 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -36,7 +36,7 @@ function App() { }, []); return ( - <>{true ? :
Connecting...
} + <>{web5 ? :
Connecting...
} ); } diff --git a/tauri-app/src/components/RemedyCard/index.tsx b/tauri-app/src/components/RemedyCard/index.tsx index 79e6422..21709a2 100644 --- a/tauri-app/src/components/RemedyCard/index.tsx +++ b/tauri-app/src/components/RemedyCard/index.tsx @@ -16,8 +16,7 @@ const index = ({ // @ts-ignore description, // @ts-ignore - created_by, - url, + created_by, useUrl, // @ts-ignore rating, // @ts-ignore @@ -27,7 +26,7 @@ const index = ({
-

{description.substring(0, 150) + "..."}

+

{description.substring(0, 50) + "..."}

From 98d192bfcd014689aa635c968563cd74d19ac632 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sat, 6 Jan 2024 21:37:03 +0000 Subject: [PATCH 059/120] updated the protocol schema --- tauri-app/src/utils/protocols/defns.ts | 2 +- tauri-app/src/utils/protocols/document.ts | 6 ++---- tauri-app/src/utils/protocols/index.ts | 4 ++-- tauri-app/src/utils/protocols/user.ts | 3 +-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/tauri-app/src/utils/protocols/defns.ts b/tauri-app/src/utils/protocols/defns.ts index 89846ca..a634369 100644 --- a/tauri-app/src/utils/protocols/defns.ts +++ b/tauri-app/src/utils/protocols/defns.ts @@ -1 +1 @@ -export const url = "https://dschema.org/v0.0.2" as const +export const url = "https://dschema.org/v0.0.5" as const diff --git a/tauri-app/src/utils/protocols/document.ts b/tauri-app/src/utils/protocols/document.ts index eddff20..c1b6883 100644 --- a/tauri-app/src/utils/protocols/document.ts +++ b/tauri-app/src/utils/protocols/document.ts @@ -29,8 +29,7 @@ const DocumentProtocol = { can: "read" }, { - who: "author", - of: "document", + who: "anyone", can: "write" } ] @@ -42,8 +41,7 @@ const DocumentProtocol = { can: "read" }, { - who: "author", - of: "blob", + who: "anyone", can: "write" } ] diff --git a/tauri-app/src/utils/protocols/index.ts b/tauri-app/src/utils/protocols/index.ts index ce802f2..1c0a671 100644 --- a/tauri-app/src/utils/protocols/index.ts +++ b/tauri-app/src/utils/protocols/index.ts @@ -4,6 +4,6 @@ import UserDetailsProtocol from "./user" export const protocols = [ DocumentProtocol, - UserDetailsProtocol - // ConditionsProtocol, + UserDetailsProtocol, + ConditionsProtocol, ] diff --git a/tauri-app/src/utils/protocols/user.ts b/tauri-app/src/utils/protocols/user.ts index 7402ca6..227b09f 100644 --- a/tauri-app/src/utils/protocols/user.ts +++ b/tauri-app/src/utils/protocols/user.ts @@ -16,8 +16,7 @@ const UserDetailsProtocol = { details: { $actions: [ { - who: "author", - of: "details", + who: "anyone", can: "read" }, { From 300e87740a5cc44d3471ac4bf925aaf691bd6b2c Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sat, 6 Jan 2024 21:37:23 +0000 Subject: [PATCH 060/120] integrated auth --- tauri-app/package.json | 1 + tauri-app/src/App.tsx | 9 +- .../src/components/Auth/Profile/Guard.tsx | 10 +- tauri-app/src/components/Navbar/index.css | 5 + tauri-app/src/components/Navbar/index.tsx | 37 +++-- tauri-app/src/pages/Home/SignUpForm.tsx | 142 ++++++++++++++++++ tauri-app/src/pages/Home/index.tsx | 58 ++----- tauri-app/src/stores/profile.ts | 7 +- tauri-app/src/stores/pulseGlobalStore.ts | 10 +- tauri-app/src/stores/useWeb5Store.ts | 3 - 10 files changed, 211 insertions(+), 71 deletions(-) create mode 100644 tauri-app/src/pages/Home/SignUpForm.tsx diff --git a/tauri-app/package.json b/tauri-app/package.json index 39b4c47..ff5225a 100644 --- a/tauri-app/package.json +++ b/tauri-app/package.json @@ -29,6 +29,7 @@ "react-dropzone": "^14.2.3", "react-easy-crop": "^5.0.4", "react-hook-form": "^7.49.2", + "react-hot-toast": "^2.4.1", "react-pdf": "^7.6.0", "react-router-dom": "^6.21.1", "react-spinners": "^0.13.8", diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index de7a969..77b379a 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -9,6 +9,7 @@ import HomePage from "./pages/Home"; import SharedLayout from "./pages/SharedLayout/"; import Records from "./pages/Records"; import Chat from "./pages/Chat/"; +import { Toaster } from "react-hot-toast"; const router = createHashRouter([ { @@ -36,7 +37,13 @@ function App() { }, []); return ( - <>{web5 ? :
Connecting...
} + <> + <>{web5 ? :
Connecting...
} + + ); } diff --git a/tauri-app/src/components/Auth/Profile/Guard.tsx b/tauri-app/src/components/Auth/Profile/Guard.tsx index d36719a..b20e4e8 100644 --- a/tauri-app/src/components/Auth/Profile/Guard.tsx +++ b/tauri-app/src/components/Auth/Profile/Guard.tsx @@ -1,9 +1,15 @@ -import { PropsWithChildren, ReactNode } from "react"; +import { PropsWithChildren, ReactNode, useEffect } from "react"; import AuthGuard from "../Guard"; import { useProfile } from "@/stores/profile"; +import useWeb5Store from "@/stores/useWeb5Store"; const Guard = ({ children, fallback }: PropsWithChildren & { fallback?: ReactNode }) => { - const isSignedIn = useProfile(state => state.state.isSignedIn) + const agent = useWeb5Store(state => ({ web5: state.web5!, did: state.did! })) + const { isSignedIn, signIn } = useProfile(state => ({ isSignedIn: state.state.isSignedIn, signIn: state.signIn })) + + useEffect(() => { + signIn(agent) + }, [signIn]) if (!isSignedIn) return <>{fallback} ?? null diff --git a/tauri-app/src/components/Navbar/index.css b/tauri-app/src/components/Navbar/index.css index 056aa0b..b433b8d 100644 --- a/tauri-app/src/components/Navbar/index.css +++ b/tauri-app/src/components/Navbar/index.css @@ -72,7 +72,12 @@ opacity: 1; } +.auth_container:focus { + outline: none; +} + .auth_container { + border: 0; display: flex; align-items: center; justify-content: center; diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index 02fca70..73a729e 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -2,11 +2,24 @@ import ProfileGuard from "../Auth/Profile/Guard"; import "./index.css"; import { NavLink } from "react-router-dom"; import { usePulseGlobalStore } from "../../stores/pulseGlobalStore.ts"; +import useWeb5Store from "@/stores/useWeb5Store.ts"; +import { Agent } from "../Auth/types"; +import { useProfile } from "@/stores/profile.ts"; const index = () => { - const toggleIsAuthBtnClicked = usePulseGlobalStore( - (store) => store.toggleIsAuthBtnClicked, - ); + const { web5, did } = useWeb5Store((state) => ({ web5: state.web5, did: state.did })); + const { signIn, setShowAuthModal, signOut } = useProfile(state => ({ + signIn: state.signIn, + signOut: state.signOut, + setShowAuthModal: state.setShowAuthModal + })) + + const beginAuthFlow = async (agent: Agent) => { + const signedIn = await signIn(agent) + if (!signedIn) + setShowAuthModal(true) + } + return (
@@ -50,19 +63,23 @@ const index = () => {
toggleIsAuthBtnClicked()} + onClick={() => web5 && did ? beginAuthFlow({ web5, did }) : null} >

Join us!

-
+ } > -
-

Profile

- -
+
); diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx new file mode 100644 index 0000000..ed71e4c --- /dev/null +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -0,0 +1,142 @@ +import "./index.css"; +import useWeb5Store from "@/stores/useWeb5Store"; +import { useProfile } from "@/stores/profile"; +import { Agent } from "@/components/Auth/types"; +import { FunctionComponent, useRef, useState } from "react"; +import { z } from "zod" +import { zodResolver } from "@hookform/resolvers/zod" +import { Controller, useForm } from "react-hook-form" +import { parse } from "path"; +import toast from "react-hot-toast"; + +const formSchema = z.object({ + firstName: z.string().min(1), + lastName: z.string().min(1), + description: z.string().min(1), + profilePicture: z.instanceof(File) +}) + +interface FileProp { + file: File | null | undefined; +} + +const FileUploader: FunctionComponent<{ onChange: (file: File | null) => void }> = ({ onChange }) => { + const [file, setFile] = useState({ file: null }); + + return ( +
+

Profile Picture

+
+ { + const file = e?.target?.files?.[0] + onChange(file ? file : null) + setFile({ file: e?.target?.files?.[0] }); + }} + type="file" + accept=".jpg,.png,.jpeg" + /> +
+ ); +}; + +export default function SignUpForm() { + const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })); + const submitBtnRef = useRef(null); + const { setShowAuthModal, signUp, signIn } = useProfile( + (state) => ({ signUp: state.signUp, signIn: state.signIn, setShowAuthModal: state.setShowAuthModal }), + ); + // const [form, setForm] = useState({ + // firstName: "", + // lastName: "", + // description: "", + // profilePicture: new File([], ""), + // }) + + const form = useForm>({ + resolver: zodResolver(formSchema) + }) + + form.watch((value) => { + if (!submitBtnRef.current) return + + const isValid = formSchema.safeParse(value).success + + if (isValid) { + submitBtnRef.current.classList.remove("not-filled-btn") + submitBtnRef.current.classList.add("filled-btn") + submitBtnRef.current.disabled = false + } + else { + submitBtnRef.current.classList.add("not-filled-btn") + submitBtnRef.current.classList.remove("filled-btn") + submitBtnRef.current.disabled = true + } + }) + + type Payload = { + firstName: string + lastName: string + description: string + profilePicture: File + } + + const createProfile = async (agent: Agent, payload: Payload) => { + const hasSignedUpSuccessfully = await signUp(agent, payload) + + if (!hasSignedUpSuccessfully) { + toast.success('Sorry an error occurred!') + + return + } + + if (!await signIn()) return + + toast.success('Successfully signed up!') + + + setShowAuthModal(false) + } + + const onSubmit = (value: z.infer) => { + if (web5 && did) createProfile({ web5, did }, value) + } + + return ( +
+ + form.setValue("profilePicture", file as File)} + /> + + + + - - -
-
+ {showAuthModal && ( + + + )} -
+
); } diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index df439f2..4d45e9c 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -28,8 +28,12 @@ export const useProfile = create( state: { profile: null, isSignedIn: false - } as State + } as State, + showAuthModal: false }, (set, get) => ({ + setShowAuthModal: (showAuthModal: boolean) => { + set({ showAuthModal }) + }, signOut: () => { if (get().state.isSignedIn) { set({ @@ -45,7 +49,6 @@ export const useProfile = create( if (!profileRecord) return false const profile: UserDetailsProtocolRecord.Details = await profileRecord.data.json() - console.log(profile) const profilePicture = await DocumentUtils.fetchBlobRecord(agent, profile.profilePictureUrl) let profilePictureUrl = "" diff --git a/tauri-app/src/stores/pulseGlobalStore.ts b/tauri-app/src/stores/pulseGlobalStore.ts index 069b0b7..9252348 100644 --- a/tauri-app/src/stores/pulseGlobalStore.ts +++ b/tauri-app/src/stores/pulseGlobalStore.ts @@ -1,13 +1,13 @@ import { create } from "zustand"; type PulseGlobalStore = { - isAuthBtnClicked: boolean; - toggleIsAuthBtnClicked: () => void; + showAuthModal: boolean; + toggleAuthModal: () => void; }; export const usePulseGlobalStore = create((set) => ({ - isAuthBtnClicked: true, - toggleIsAuthBtnClicked: () => { - set((state) => ({ isAuthBtnClicked: !state.isAuthBtnClicked })); + showAuthModal: true, + toggleAuthModal: () => { + set((state) => ({ showAuthModal: !state.showAuthModal })); }, })); diff --git a/tauri-app/src/stores/useWeb5Store.ts b/tauri-app/src/stores/useWeb5Store.ts index 37eff48..2451557 100644 --- a/tauri-app/src/stores/useWeb5Store.ts +++ b/tauri-app/src/stores/useWeb5Store.ts @@ -1,8 +1,5 @@ import { Web5 } from "@web5/api/browser"; import { create } from "zustand"; -import ConditionsProtocol from "@/utils/protocols/conditions"; -import DocumentProtocol from "@/utils/protocols/document"; -import UserDetailsProtocol from "@/utils/protocols/user"; import { protocols as AllProtocols } from "@/utils/protocols"; interface Web5State { From 82082514ffd36a2178b038b897855109e67ff200 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sat, 6 Jan 2024 21:37:32 +0000 Subject: [PATCH 061/120] added a SS script for testing --- server/script.ts | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 server/script.ts diff --git a/server/script.ts b/server/script.ts new file mode 100644 index 0000000..e58a7e5 --- /dev/null +++ b/server/script.ts @@ -0,0 +1,94 @@ +import { Web5 } from "@web5/api"; +import { protocols } from "@frontend/utils/protocols"; +import DocumentUtils from "@frontend/utils/document"; +import { Agent } from "@backend/utils"; + +async function configureProtocols(agent: Agent) { + console.log("=== CONFIGURE PROTOCOL ===") + + for (const protocol of protocols) { + const { protocols } = await agent.web5.dwn.protocols.query({ + message: { + filter: { + protocol: protocol.protocol, + } + } + }) + + if (protocols.length > 0) { + console.log("Protocol already exists:", protocol.protocol) + continue + } + + const { protocol: configuredProtocol, status: localProtocolConfigurationStatus } = await agent.web5.dwn.protocols.configure({ + message: { + definition: Object.assign({ ...protocol }), + } + }); + + if (!configuredProtocol) { + console.log("Failed to configure protocol:", localProtocolConfigurationStatus) + return + } + + console.log("Configured protocol on local DWN:", protocol.protocol) + const { status: remoteProtocolConfigurationStatus } = await configuredProtocol.send(agent.did) + + console.log("Sent protocol to remote DWN") + console.log(protocol.protocol, remoteProtocolConfigurationStatus) + } + + console.log("=== END CONFIGURE PROTOCOL ===") +} + +async function queryConditions(agent: Agent) { + console.log("=== QUERY CONDITIONS ===") + + const records = await DocumentUtils.fetchDocumentRecords(agent) + if (!records) { + console.log("No records found") + return + } + + if (records.length > 0) { + for (const record of records) { + // console.log("author:", record.author) + // console.log("recipient:", record.recipient) + // Bun.write("records/" + record.id + ".json", JSON.stringify(record)) + // console.log(record.author === record.target) + console.log(await record.data.json()) + } + } + + console.log("=== END QUERY CONDITIONS ===") +} + +async function createCondition(agent: Agent) { + console.log("=== CREATE CONDITION ===") + + const record = await DocumentUtils.createDocumentRecord(agent, { name: "test", condition: "command", file: new File([], "", { type: "image/png" }) }) + + if (!record) return false + + console.log("=== END CREATE CONDITION ===") +} + +async function connect() { + console.log("=== CONNECT ===") + const agent = await Web5.connect({ + sync: "5s", + }); + + console.log("=== END CONNECT ===") + + return agent +} +async function main() { + const agent = await connect() + await configureProtocols(agent) + await queryConditions(agent) + // await createCondition(agent) + // await queryConditions(agent) +} + +main() From b83bdda525cdc1c516e36303d964f4dc690197b2 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Sat, 6 Jan 2024 23:01:21 +0100 Subject: [PATCH 062/120] chat still in dev moving to add minor feature --- tauri-app/src/components/Chat/index.css | 74 ++++++++++++++++++ tauri-app/src/components/Chat/index.tsx | 48 ++++++++++++ .../src/components/UserFriendList/index.css | 78 +++++++++++++++++++ .../src/components/UserFriendList/index.tsx | 61 +++++++++++++++ .../src/components/UserProfile/index.css | 2 +- tauri-app/src/index.css | 4 + tauri-app/src/pages/Chat/index.css | 15 +++- tauri-app/src/pages/Chat/index.tsx | 35 ++++++--- 8 files changed, 305 insertions(+), 12 deletions(-) create mode 100644 tauri-app/src/components/Chat/index.css create mode 100644 tauri-app/src/components/Chat/index.tsx create mode 100644 tauri-app/src/components/UserFriendList/index.css create mode 100644 tauri-app/src/components/UserFriendList/index.tsx diff --git a/tauri-app/src/components/Chat/index.css b/tauri-app/src/components/Chat/index.css new file mode 100644 index 0000000..b2b6a6f --- /dev/null +++ b/tauri-app/src/components/Chat/index.css @@ -0,0 +1,74 @@ +.chat-component-container { + box-shadow: var(--box-shadow-black); + border-radius: 15px; + padding: 20px; + width: 100%; + height: 100%; + min-height: 500px; +} + +.chat-message-input-container { + width: 100%; + padding: 15px 0px; + display: flex; + justify-content: space-around; + align-items: center; +} + +.chat-message-input-container input { + width: 80%; + height: 30px; + padding: 8px 12px; + background: var(--color-slate-accent); + border: none; + border-radius: 25px; + outline: none; + font-family: "Roboto"; + font-size: 20px; + text-indent: 8px; +} + +.chat-message-input-container button { + width: 40px; + height: 40px; + border: none; + border-radius: 50%; + color: var(--color-white); + background: var(--color-blue); + box-shadow: var(--box-shadow-blue); + font-size: 20px; +} + +.chats-container { + width: 95%; + background: var(--color-light-grey); + height: 90%; + padding: 12px; + border-radius: 15px; + margin: 0 auto; +} + +.msg-container { + width: 100%; + margin: 25px 2px; +} + +.msg-f { + width: max-content; + background: var(--color-light-green); + font-family: "Roboto"; + padding: 4px 10px; + border-radius: 8px 8px 8px 0px; + margin-right: auto; + max-width: 300px; +} + +.msg-t { + width: max-content; + background: var(--color-light-blue); + font-family: "Roboto"; + padding: 4px 10px; + border-radius: 8px 8px 0px 8px; + margin-left: auto; + max-width: 300px; +} diff --git a/tauri-app/src/components/Chat/index.tsx b/tauri-app/src/components/Chat/index.tsx new file mode 100644 index 0000000..9492f36 --- /dev/null +++ b/tauri-app/src/components/Chat/index.tsx @@ -0,0 +1,48 @@ +import "./index.css"; +import React, { FC } from "react"; + +interface MessageProp { + message: string; + isLeft: boolean; +} + +const Message: FC = ({ message, isLeft }) => { + return ( +
+
+

{message}

+
+
+ ); +}; + +const index: FC = () => { + return ( +
+
+ + + + +
+
+ + +
+
+ ); +}; + +export default index; diff --git a/tauri-app/src/components/UserFriendList/index.css b/tauri-app/src/components/UserFriendList/index.css new file mode 100644 index 0000000..dc82b4b --- /dev/null +++ b/tauri-app/src/components/UserFriendList/index.css @@ -0,0 +1,78 @@ +.friend-tag-container { + display: flex; + justify-content: space-between; + align-items: center; + margin: 12px 0; + border-radius: 8px; + transition: 0.3s; + padding: 8px; + transition: 0.3s; +} + +.friend-tag-container h1 { + font-size: 18px; + font-family: "Roboto"; +} + +.friend-tag-container img { + width: 40px; + height: 40px; + border-radius: 5px; +} + +.friends-list-container hr { + width: 60%; + margin: 0 auto; +} + +.friends-list-container hr:last-child { + display: none; +} + +.friend-tag-container:hover { + background: var(--color-slate-accent); +} + +.friends-list-container { + box-shadow: var(--box-shadow-black); + padding: 8px 14px; + border-radius: 15px; + margin-top: 30px; + width: 300px; +} + +.friends-list-header { + background: var(--color-blue); + padding: 4px 12px; + border-radius: 10px; + color: var(--color-white); + font-family: "Roboto"; + text-align: center; +} + +.friend-main-list-container { + overflow-y: scroll; + height: 300px; + margin: 15px 0; + padding: 5px; +} + +.friend-main-list-container::-webkit-scrollbar { + width: 6px; +} + +.friend-main-list-container::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1); + border-radius: 5px; +} + +.friend-main-list-container::-webkit-scrollbar-thumb { + width: 2px; + background: var(--color-blue); + border-radius: 5px; + margin: 0 3px; +} + +.friends-list-header b { + font-family: "Pacifico"; +} diff --git a/tauri-app/src/components/UserFriendList/index.tsx b/tauri-app/src/components/UserFriendList/index.tsx new file mode 100644 index 0000000..d76e959 --- /dev/null +++ b/tauri-app/src/components/UserFriendList/index.tsx @@ -0,0 +1,61 @@ +import "./index.css"; +import React, { FC, useState } from "react"; + +interface FriendTagProp { + friendProfileImg: string; + friendName: string; + isFriendOnline: boolean; +} + +const FriendTag: FC = ({ + friendProfileImg, + friendName, + isFriendOnline, +}) => { + return ( +
+ +

{friendName.slice(0, 60) + "..."}

+ +
+ ); +}; + +interface UserFriendListProp { + friendList: FriendTagProp[]; +} + +const index: FC = ({ friendList }) => { + return ( +
+
+

+ Friends 45 +

+
+
+ {friendList.map((friend) => { + return ( + <> + +
+ + ); + })} +
+
+ ); +}; + +export default index; diff --git a/tauri-app/src/components/UserProfile/index.css b/tauri-app/src/components/UserProfile/index.css index 2c3dd37..b426bd5 100644 --- a/tauri-app/src/components/UserProfile/index.css +++ b/tauri-app/src/components/UserProfile/index.css @@ -1,6 +1,6 @@ .userprofile-container { box-shadow: var(--box-shadow-black); - width: 200px; + width: 300px; text-align: center; border-radius: 15px; padding: 8px 12px; diff --git a/tauri-app/src/index.css b/tauri-app/src/index.css index 0b0b566..5bfae8d 100644 --- a/tauri-app/src/index.css +++ b/tauri-app/src/index.css @@ -11,6 +11,10 @@ --color-black: #000; --color-slate: #e2e8f0; --color-orange: #f97316; + --color-light-green: #4ade80; + --color-light-blue: #7dd3fc; + --color-light-grey: #f8fafc; + --color-grey: #d1d5db; --padding-desktop: 40px 65px; --padding-mobile: 40px 25px; } diff --git a/tauri-app/src/pages/Chat/index.css b/tauri-app/src/pages/Chat/index.css index 322a4e5..d96fd05 100644 --- a/tauri-app/src/pages/Chat/index.css +++ b/tauri-app/src/pages/Chat/index.css @@ -1,8 +1,19 @@ .main-chat-container { padding: var(--padding-desktop); display: flex; - justify-content: center; - align-items: center; + justify-content: space-between; + align-items: flex-start; + position: relative; +} + +.utils-container { + width: 35%; +} + +.chat-container { + width: 60%; + height: 100%; + height: 40vh; } @media (max-width: 750px) { diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index 89b5b1f..560826e 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -1,18 +1,35 @@ import "./index.css"; import UserProfile from "../../components/UserProfile/"; +import UserFriendList from "../../components/UserFriendList/"; +import Chat from "../../components/Chat/"; + +import { useState } from "react"; const index = () => { + const [friends, setFriends] = useState([ + { profile_pic: "/pg.jpg", username: "@scriptkidd", isOnline: false }, + { profile_pic: "/pg.jpg", username: "@nikki", isOnline: false }, + { profile_pic: "/pm.jpg", username: "@gregidd", isOnline: true }, + { profile_pic: "/pic.jpg", username: "@scdd", isOnline: false }, + ]); + return (
- +
+ + +
+
+ +
); }; From c086371345a5b41cd9b21d13ffc0bf6ec81c4e6d Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 00:03:36 +0000 Subject: [PATCH 063/120] made the schema to match the site --- tauri-app/src/pages/Home/SignUpForm.tsx | 9 +- tauri-app/src/pages/Records/index.tsx | 79 ++++++++++++++-- tauri-app/src/pages/connect.tsx | 2 +- tauri-app/src/pages/medic.tsx | 2 +- tauri-app/src/stores/profile.ts | 19 ++-- tauri-app/src/utils/document.ts | 105 ++++++++++++++++++---- tauri-app/src/utils/protocols/document.ts | 21 +++-- 7 files changed, 187 insertions(+), 50 deletions(-) diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index ed71e4c..0a1f2fd 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -5,8 +5,7 @@ import { Agent } from "@/components/Auth/types"; import { FunctionComponent, useRef, useState } from "react"; import { z } from "zod" import { zodResolver } from "@hookform/resolvers/zod" -import { Controller, useForm } from "react-hook-form" -import { parse } from "path"; +import { useForm } from "react-hook-form" import toast from "react-hot-toast"; const formSchema = z.object({ @@ -46,12 +45,6 @@ export default function SignUpForm() { const { setShowAuthModal, signUp, signIn } = useProfile( (state) => ({ signUp: state.signUp, signIn: state.signIn, setShowAuthModal: state.setShowAuthModal }), ); - // const [form, setForm] = useState({ - // firstName: "", - // lastName: "", - // description: "", - // profilePicture: new File([], ""), - // }) const form = useForm>({ resolver: zodResolver(formSchema) diff --git a/tauri-app/src/pages/Records/index.tsx b/tauri-app/src/pages/Records/index.tsx index d95d177..54ef08d 100644 --- a/tauri-app/src/pages/Records/index.tsx +++ b/tauri-app/src/pages/Records/index.tsx @@ -1,23 +1,75 @@ import "./index.css"; -import { useState } from "react"; +import { useEffect, useState } from "react"; +import { Record as DocumentRecord } from "@/utils/protocols/document"; import AddCardComponent from "../../components/AddCardComponent"; import DetailCardComponent from "../../components/DetailCardComponent"; import Card from "../../components/Card"; +import { Agent } from "@/components/Auth/types"; +import DocumentUtils from "@/utils/document"; +import { ProfileState, useProfile } from "@/stores/profile"; +import useWeb5Store from "@/stores/useWeb5Store"; + +const fetchRecords = async (agent: Agent, profile: ProfileState) => { + const records = await DocumentUtils.fetchDocumentRecords(agent) + if (!records) return false + + const profileRecords = [] + for (const record of records) { + const data: DocumentRecord.Document = await record.data.json() + const fileRecord = await DocumentUtils.fetchBlobRecord(agent, data.file.id) + if (!fileRecord) continue + const fileData = await fileRecord.data.blob() + + const otherFiles = await Promise.all(data.otherFiles.map(async file => { + const record = await DocumentUtils.fetchBlobRecord(agent, file.id) + if (!record) return false + + const data = await record.data.blob() + return { + name: file.name, + type: file.type, + url: URL.createObjectURL( + new File([data], file.name, { type: file.type }) + ) + } + })) + + if (data.profileId === profile.id) { + profileRecords.push({ + title: data.title, + description: data.description, + dateCreated: data.dateCreated, + file: { + name: data.file.name, + type: data.file.type, + url: URL.createObjectURL( + new File([fileData], data.file.name, { type: data.file.type }) + ) + }, + otherFiles + }) + } + } + return profileRecords +} const index = () => { + const agent = useWeb5Store(state => ({ web5: state.web5!, did: state.did! })) + const profile = useProfile(state => state.state.profile!) + const [cardsData, setCardsData] = useState([ { title: "Diabetes Docs", - desc: "documentation of test ran for diagonese of diabtets slated for type dissertion", + description: "documentation of test ran for diagonese of diabtets slated for type dissertion", date: "1/2/24", file_extension: "pdf", file_name: "Diabetes_scan.pdf", }, { title: "Diabetes Docs", - desc: "documentation of test ran for diagonese of diabtets slated for type dissertion", + description: "documentation of test ran for diagonese of diabtets slated for type dissertion", date: "1/2/24", file_extension: "pdf", file_name: "Diabetes_scan.pdf", @@ -28,7 +80,7 @@ const index = () => { }, { title: "Diabetes Docs", - desc: "documentation of test ran for diagonese of diabtets slated for type dissertion", + description: "documentation of test ran for diagonese of diabtets slated for type dissertion", date: "1/2/24", file_extension: "docx", file_name: "Diabetes_test.docx", @@ -50,6 +102,17 @@ const index = () => { }, ]); + useEffect(() => { + (async () => { + const records = await fetchRecords(agent, profile) + console.log(records) + + if (!records) return + + return + })() + }, []) + const [isAddCardActive, setIsAddCardActive] = useState(false); const [isCardDetailActive, setIsCardDetailActive] = useState(false); const [activeCard, setActiveCard] = useState(null); @@ -75,7 +138,7 @@ const index = () => {
- {cardsData.map((card) => { + {cardsData.length > 0 ? cardsData.map((card) => { return ( { // @ts-ignore title={card.title} date={card.date} - desc={card.desc} + desc={card.description} cardUtils={[card, isCardClicked]} /> ); - })} + }) :
No Records Found
}
{(isAddCardActive || isCardDetailActive) && (
{ {isAddCardActive && } {isCardDetailActive && ( diff --git a/tauri-app/src/pages/connect.tsx b/tauri-app/src/pages/connect.tsx index 88c7fcc..7519602 100644 --- a/tauri-app/src/pages/connect.tsx +++ b/tauri-app/src/pages/connect.tsx @@ -74,7 +74,7 @@ function Connect() { {similarConditionDocuments.map((doc, index) => (
- {doc.name} + {doc.title}
{doc.condition} diff --git a/tauri-app/src/pages/medic.tsx b/tauri-app/src/pages/medic.tsx index 17ad038..9ca1924 100644 --- a/tauri-app/src/pages/medic.tsx +++ b/tauri-app/src/pages/medic.tsx @@ -39,7 +39,7 @@ const Page: FunctionComponent = () => { if (!fileRecord) continue - const file = new File([await fileRecord.data.blob()], data.name, { type: data.encodingFormat }) + const file = new File([await fileRecord.data.blob()], data.title, { type: data.encodingFormat }) docsWithUrl.push({ record: docRecord, diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index 4d45e9c..62d2eee 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -5,21 +5,23 @@ import { Agent } from "@/components/Auth/types"; import UserDetailsUtils from "@/utils/user"; import DocumentUtils from "@/utils/document"; +export type ProfileState = { + id: string + // username: string + firstName: string, + lastName: string, + profilePictureUrl: string +} + type State = { - profile: { - firstName: string, - lastName: string, - profilePictureUrl: string - }, + profile: ProfileState, isSignedIn: true } | { profile: null, isSignedIn: false } -type Payload = { - firstName: string, - lastName: string, +type Payload = Omit & { profilePicture: File } @@ -61,6 +63,7 @@ export const useProfile = create( state: { isSignedIn: true, profile: { + id: profileRecord.id, firstName: profile.firstName, lastName: profile.lastName, profilePictureUrl diff --git a/tauri-app/src/utils/document.ts b/tauri-app/src/utils/document.ts index 6e66835..ab8245d 100644 --- a/tauri-app/src/utils/document.ts +++ b/tauri-app/src/utils/document.ts @@ -73,18 +73,45 @@ async function fetchRecords(agent: Agent, filter: FullFilterObj< return records } -async function createDocumentRecord(agent: Agent, { name, file, condition }: { name: string | undefined, file: File, condition: string }) { +type CreatePayload = Omit & +{ + title?: string + file: File, + otherFiles: File[] +} + +async function createDocumentRecord(agent: Agent, payload: CreatePayload) { + const { file, otherFiles, ...restPayload } = payload + const blobRecord = await createBlobRecord(agent, file) if (!blobRecord) return false + const fileData = { + id: blobRecord.id, + size: file.size, + type: file.type, + name: file.name, + } + + const otherFilesData = [] + for (const file of otherFiles) { + const blobRecord = await createBlobRecord(agent, file) + if (!blobRecord) return false + + otherFilesData.push({ + id: blobRecord.id, + size: file.size, + type: file.type, + name: file.name, + }) + } + const record = await createRecord( agent, { - name: name ?? file.name, - encodingFormat: file.type, - size: file.size, - url: blobRecord.id, - condition, + ..._.merge({ title: file.name }, restPayload), + file: fileData, + otherFiles: otherFilesData, dateCreated: new Date().toISOString(), dateModified: new Date().toISOString() }, @@ -160,11 +187,13 @@ async function fetchBlobRecords(agent: Agent) { }) } -type UpdatePayload = Partial<{ - name: string - condition: string - file: File -}> +type UpdatePayload = Partial< + Omit & + { + file: File, + otherFiles: File[] + } +> async function updateDocumentRecord(agent: Agent, id: string, payload: UpdatePayload): Promise; async function updateDocumentRecord(agent: Agent, record: Web5Record, payload: UpdatePayload): Promise; @@ -184,18 +213,56 @@ async function updateDocumentRecord(agent: Agent, idOrRecord: string | Web5Recor } const data: DocumentProtocolRecord.Document = await record.data.json() - const { file, ...restPayload } = payload + const { file, otherFiles, ...restPayload } = payload - let url = data.url + const fileData = data.file if (file) { - const blobRecord = await updateBlobRecord(agent, url, file) + const blobRecord = await updateBlobRecord(agent, data.file.id, file) if (!blobRecord) return false - url = blobRecord.id + fileData.id = blobRecord.id + fileData.name = file.name + fileData.size = file.size + fileData.type = file.type + } + + const otherFilesData = data.otherFiles + if (otherFiles) { + for (let i = 0; i < otherFiles.length; i++) { + const file = otherFiles[i] + const otherFile = otherFilesData[i] + + const blobRecord = await updateBlobRecord(agent, otherFile.id, file) + if (!blobRecord) return false + + otherFile.id = blobRecord.id + otherFile.name = file.name + otherFile.size = file.size + otherFile.type = file.type + } + + if (otherFiles.length < otherFilesData.length) { + otherFilesData.splice(otherFiles.length, otherFilesData.length - otherFiles.length) + } + else { + for (let i = otherFilesData.length; i < otherFiles.length; i++) { + const file = otherFiles[i] + + const blobRecord = await createBlobRecord(agent, file) + if (!blobRecord) return false + + otherFilesData.push({ + id: blobRecord.id, + name: file.name, + size: file.size, + type: file.type, + }) + } + } } const { status } = await record.update({ - data: _.merge(data, Object.assign(restPayload, { url })) + data: _.merge(data, Object.assign(restPayload, { file: fileData, otherFiles: otherFilesData })) }) if (status.code !== 202) { @@ -252,9 +319,13 @@ async function deleteDocumentRecord(agent: Agent, idOrRecord: string | Web5Recor const document: DocumentProtocolRecord.Document = await record.data.json() - const hasDeletedBlobRecord = await deleteBlobRecord(agent, document.url) + const hasDeletedBlobRecord = await deleteBlobRecord(agent, document.file.id) if (!hasDeletedBlobRecord) return false + for (const otherFile of document.otherFiles) { + await deleteBlobRecord(agent, otherFile.id) + } + const { status } = await agent.web5.dwn.records.delete({ message: { recordId: record.id diff --git a/tauri-app/src/utils/protocols/document.ts b/tauri-app/src/utils/protocols/document.ts index c1b6883..a248fe6 100644 --- a/tauri-app/src/utils/protocols/document.ts +++ b/tauri-app/src/utils/protocols/document.ts @@ -50,17 +50,24 @@ const DocumentProtocol = { } as const export namespace Record { + type FileMeta = { + id: string + size: number + type: string + name: string + } + export type File = Blob export type Document = { - name: string - encodingFormat: string - size: number - url: string - // profileUrl: string + title: string + file: FileMeta, + description?: string + otherFiles: FileMeta[], + profileId: string condition: string - dateCreated?: string - dateModified?: string + dateCreated: string + dateModified: string }; } From 7ff667f1ac59ca339a8df674a7df33e0771b9f3f Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 01:12:14 +0000 Subject: [PATCH 064/120] integrated the record feature --- tauri-app/src/App.tsx | 3 +- .../src/components/AddCardComponent/index.css | 21 +++ .../src/components/AddCardComponent/index.tsx | 157 ++++++++++++---- .../components/DetailCardComponent/index.tsx | 67 ++++--- tauri-app/src/pages/Home/SignUpForm.tsx | 5 +- tauri-app/src/pages/Records/index.tsx | 167 +++++++----------- tauri-app/src/pages/Records/utils.tsx | 54 ++++++ tauri-app/src/utils/protocols/document.ts | 2 +- 8 files changed, 306 insertions(+), 170 deletions(-) create mode 100644 tauri-app/src/pages/Records/utils.tsx diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 77b379a..be69d99 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -10,6 +10,7 @@ import SharedLayout from "./pages/SharedLayout/"; import Records from "./pages/Records"; import Chat from "./pages/Chat/"; import { Toaster } from "react-hot-toast"; +import ProfileGuard from "./components/Auth/Profile/Guard"; const router = createHashRouter([ { @@ -17,7 +18,7 @@ const router = createHashRouter([ element: , children: [ { path: "/", element: }, - { path: "/records", element: }, + { path: "/records", element: }, { path: "/connect", element: }, { path: "/remedies", element: }, { path: "/medic", element: }, diff --git a/tauri-app/src/components/AddCardComponent/index.css b/tauri-app/src/components/AddCardComponent/index.css index e82047b..a644737 100644 --- a/tauri-app/src/components/AddCardComponent/index.css +++ b/tauri-app/src/components/AddCardComponent/index.css @@ -56,6 +56,20 @@ margin-right: 40%; } +.input-form select { + width: 60%; + border: none; + background: var(--color-slate); + padding: 10px 2px; + border-radius: 8px; + font-family: "Roboto"; + text-indent: 10px; + outline: none; + margin-bottom: 10px; + margin-right: 40%; +} + + .input-form textarea { width: 100%; border: none; @@ -66,6 +80,7 @@ text-indent: 10px; outline: none; min-height: 80px; + margin-bottom: 10px; } .input-form button { @@ -203,6 +218,12 @@ margin-right: 0; } + .input-form select { + width: 100%; + margin-right: 0; + } + + .input-form input[type="file"] { padding: 10px 0; } diff --git a/tauri-app/src/components/AddCardComponent/index.tsx b/tauri-app/src/components/AddCardComponent/index.tsx index 9e324bd..a30753f 100644 --- a/tauri-app/src/components/AddCardComponent/index.tsx +++ b/tauri-app/src/components/AddCardComponent/index.tsx @@ -1,56 +1,153 @@ import "./index.css"; -import React, { useState } from "react"; +import React, { FunctionComponent, useState } from "react"; +import { z } from "zod" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" +import toast from "react-hot-toast"; +import DocumentUtils from "@/utils/document"; +import { Agent } from "../Auth/types"; +import { ProfileState } from "@/stores/profile"; + +const possibleConditions = [ + "Cancer", + "Diabetes", + "Heart Disease", + "High Blood Pressure", + "High Cholesterol", + "Mental Illness", +] interface FileProp { file: File | null | undefined; } -const FileUploader = () => { +const FileUploader: FunctionComponent<{ required?: boolean, onChange: (file: File | null) => void }> = ({ required, onChange }) => { const [file, setFile] = useState({ file: null }); return ( -
+
{ + const file = e?.target?.files?.[0] + onChange(file ? file : null) setFile({ file: e?.target?.files?.[0] }); }} type="file" - accept=".jpg,.png,.jpeg,.docx,.pdf" + accept=".jpg,.png,.jpeg" />
); }; -const index = () => { - const [fileUploaders, setUploaderFile] = useState([ - , - ]); +// const FileUploader = () => { +// const [file, setFile] = useState({ file: null }); +// +// return ( +//
+// { +// setFile({ file: e?.target?.files?.[0] }); +// }} +// type="file" +// accept=".jpg,.png,.jpeg,.docx,.pdf" +// /> +//
+// ); +// }; + +const formSchema = z.object({ + title: z.string().optional(), + description: z.string().min(1), + condition: z.string().min(1), + file: z.instanceof(File), + otherFiles: z.array(z.instanceof(File)) +}) + +const index: FunctionComponent<{profile: ProfileState, agent: Agent, onClose: () => void}> = ({ profile, agent, onClose }) => { + const [numFileUploaders, setNumFileUploaders] = useState(0) + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + otherFiles: [] + } + }) + // console.log(form.formState.errors) + + const onSubmit = async (data: z.infer) => { + const payload = { + ...data, + profileId: profile.id + } + const createdRecord = await DocumentUtils.createDocumentRecord(agent, payload) + if (!createdRecord) { + toast.error('Sorry an error occurred!') + return + } + + toast.success('Successfully created record!') + + onClose() + } + return (

Create New Record

-
- {fileUploaders.length > 2 &&

Max file uploads reached

} -
2 ? "sadd-mu" : "add-mu"} - onClick={() => - fileUploaders.length > 2 - ? null - : setUploaderFile([...fileUploaders, ]) - } - > - + +
+ {numFileUploaders > 2 &&

Max file uploads reached

} +
2 ? "sadd-mu" : "add-mu"} + onClick={() => + numFileUploaders > 2 + ? null + : setNumFileUploaders(numFileUploaders + 1) + } + > + +
+ {Array.from({ length: numFileUploaders }) + .map((_, index) => ( + { + const otherFiles = form.getValues("otherFiles") + otherFiles[index] = file as File + form.setValue("otherFiles", otherFiles) + }} /> + ))} + + - -

- *ensure inputted information are correct as once saved it cannot be - deleted/edited -

-
+
); }; diff --git a/tauri-app/src/components/DetailCardComponent/index.tsx b/tauri-app/src/components/DetailCardComponent/index.tsx index 9ae854b..b22aedb 100644 --- a/tauri-app/src/components/DetailCardComponent/index.tsx +++ b/tauri-app/src/components/DetailCardComponent/index.tsx @@ -1,25 +1,27 @@ import "./index.css"; import React, { FC, useState } from "react"; +import { CardData } from "@/pages/Records/utils"; -interface OtherFileProp { - title: String; - file_extension: string; - file_name: string; +// interface OtherFileProp { +// title: String; +// file_extension: string; +// file_name: string; +// +// file_url: string; +// } - file_url: string; -} - -interface CardDataProps { - file_name: String; - file_extension: string; - title: String; - desc: String; - date: String; - other_files: OtherFileProp[]; -} +// interface CardDataProps { +// file_name: String; +// file_extension: string; +// title: String; +// desc: String; +// date: String; +// other_files: OtherFileProp[]; +// } interface CardProp { - cardData: CardDataProps; + // cardData: CardDataProps; + cardData: CardData close: (isCardDetailActive: boolean) => void; } @@ -33,40 +35,37 @@ const index: FC = ({ cardData, close }) => { return (
close(false)}> - +
-

{cardData.title ? cardData.title : cardData.file_name}

- {supportedIMGExtensions.includes(cardData.file_extension) && ( +

{cardData.title ? cardData.title : cardData.file.name}

+ {supportedIMGExtensions.includes(cardData.file.type.split("/")[1]) && (
- + {cardData.file.name}
)} -

{cardData.desc}

+

{cardData.description}

- {cardData.other_files && - cardData.other_files.map((file) => { + {cardData.otherFiles.map((file) => { + const fileExtension = file.type.split("/")[1] return (
- {file.file_extension == "pdf" && ( + {fileExtension === "pdf" && ( + className="fa-solid fa-file-pdf" /> )} - {file.file_extension == "docx" && ( + {fileExtension === "docx" && ( + className="fas fa-file-word" /> )} - {supportedIMGExtensions.includes(file.file_extension) && ( + {supportedIMGExtensions.includes(fileExtension) && ( + style={{ color: "var(--color-blue)" }} /> )} - -

{file.file_name}

+
+

{file.name}

); diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index 0a1f2fd..2dfb6f6 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -78,12 +78,11 @@ export default function SignUpForm() { const hasSignedUpSuccessfully = await signUp(agent, payload) if (!hasSignedUpSuccessfully) { - toast.success('Sorry an error occurred!') - + toast.error('Sorry an error occurred!') return } - if (!await signIn()) return + if (!await signIn(agent)) return toast.success('Successfully signed up!') diff --git a/tauri-app/src/pages/Records/index.tsx b/tauri-app/src/pages/Records/index.tsx index 54ef08d..46983e9 100644 --- a/tauri-app/src/pages/Records/index.tsx +++ b/tauri-app/src/pages/Records/index.tsx @@ -1,117 +1,76 @@ import "./index.css"; import { useEffect, useState } from "react"; -import { Record as DocumentRecord } from "@/utils/protocols/document"; +import { format } from "date-fns"; import AddCardComponent from "../../components/AddCardComponent"; import DetailCardComponent from "../../components/DetailCardComponent"; import Card from "../../components/Card"; -import { Agent } from "@/components/Auth/types"; -import DocumentUtils from "@/utils/document"; -import { ProfileState, useProfile } from "@/stores/profile"; +import { useProfile } from "@/stores/profile"; import useWeb5Store from "@/stores/useWeb5Store"; - -const fetchRecords = async (agent: Agent, profile: ProfileState) => { - const records = await DocumentUtils.fetchDocumentRecords(agent) - if (!records) return false - - const profileRecords = [] - for (const record of records) { - const data: DocumentRecord.Document = await record.data.json() - const fileRecord = await DocumentUtils.fetchBlobRecord(agent, data.file.id) - if (!fileRecord) continue - const fileData = await fileRecord.data.blob() - - const otherFiles = await Promise.all(data.otherFiles.map(async file => { - const record = await DocumentUtils.fetchBlobRecord(agent, file.id) - if (!record) return false - - const data = await record.data.blob() - return { - name: file.name, - type: file.type, - url: URL.createObjectURL( - new File([data], file.name, { type: file.type }) - ) - } - })) - - if (data.profileId === profile.id) { - profileRecords.push({ - title: data.title, - description: data.description, - dateCreated: data.dateCreated, - file: { - name: data.file.name, - type: data.file.type, - url: URL.createObjectURL( - new File([fileData], data.file.name, { type: data.file.type }) - ) - }, - otherFiles - }) - } - } - return profileRecords -} +import { fetchRecords } from "./utils"; const index = () => { const agent = useWeb5Store(state => ({ web5: state.web5!, did: state.did! })) const profile = useProfile(state => state.state.profile!) - const [cardsData, setCardsData] = useState([ - { - title: "Diabetes Docs", - description: "documentation of test ran for diagonese of diabtets slated for type dissertion", - date: "1/2/24", - file_extension: "pdf", - file_name: "Diabetes_scan.pdf", - }, - { - title: "Diabetes Docs", - description: "documentation of test ran for diagonese of diabtets slated for type dissertion", - date: "1/2/24", - file_extension: "pdf", - file_name: "Diabetes_scan.pdf", - other_files: [ - { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - ], - }, - { - title: "Diabetes Docs", - description: "documentation of test ran for diagonese of diabtets slated for type dissertion", - date: "1/2/24", - file_extension: "docx", - file_name: "Diabetes_test.docx", - other_files: [ - { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - ], - }, - { - desc: "documentation of test ran for diagonese of diabtets slated for type dissertion", - date: "1/2/24", - file_extension: "jpg", - file_name: "D_IMG1103.jpg", - file_1_url: "../../../public/pic.jpg", - other_files: [ - { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - ], - }, + const [cardsData, setCardsData] = useState([ + // { + // title: "Diabetes Docs", + // description: "documentation of test ran for diagonese of diabtets slated for type dissertion", + // date: "1/2/24", + // file_extension: "pdf", + // file_name: "Diabetes_scan.pdf", + // }, + // { + // title: "Diabetes Docs", + // description: "documentation of test ran for diagonese of diabtets slated for type dissertion", + // date: "1/2/24", + // file_extension: "pdf", + // file_name: "Diabetes_scan.pdf", + // other_files: [ + // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, + // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, + // ], + // }, + // { + // title: "Diabetes Docs", + // description: "documentation of test ran for diagonese of diabtets slated for type dissertion", + // date: "1/2/24", + // file_extension: "docx", + // file_name: "Diabetes_test.docx", + // other_files: [ + // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, + // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, + // ], + // }, + // { + // desc: "documentation of test ran for diagonese of diabtets slated for type dissertion", + // date: "1/2/24", + // file_extension: "jpg", + // file_name: "D_IMG1103.jpg", + // file_1_url: "../../../public/pic.jpg", + // other_files: [ + // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, + // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, + // ], + // }, ]); useEffect(() => { - (async () => { - const records = await fetchRecords(agent, profile) - console.log(records) + refetchRecords() + }, []) - if (!records) return + const refetchRecords = async () => { + const records = await fetchRecords(agent, profile) + console.log('records:', records) - return - })() - }, []) + if (!records) return + + setCardsData(records) + + return + } const [isAddCardActive, setIsAddCardActive] = useState(false); const [isCardDetailActive, setIsCardDetailActive] = useState(false); @@ -141,11 +100,10 @@ const index = () => { {cardsData.length > 0 ? cardsData.map((card) => { return ( @@ -158,7 +116,14 @@ const index = () => { style={{ zIndex: `${isCardDetailActive ? "7" : "6"}` }} >
- {isAddCardActive && } + {isAddCardActive && { + setIsAddCardActive(false) + refetchRecords() + }} /> + } {isCardDetailActive && ( { + const records = await DocumentUtils.fetchDocumentRecords(agent) + if (!records) return false + + const profileRecords = [] + for (const record of records) { + const data: DocumentRecord.Document = await record.data.json() + const fileRecord = await DocumentUtils.fetchBlobRecord(agent, data.file.id) + if (!fileRecord) continue + const fileData = await fileRecord.data.blob() + + const otherFilesProcessing = await Promise.all(data.otherFiles.map(async file => { + const record = await DocumentUtils.fetchBlobRecord(agent, file.id) + if (!record) return false + + const data = await record.data.blob() + return { + name: file.name, + type: file.type, + url: URL.createObjectURL( + new File([data], file.name, { type: file.type }) + ) + } + })) + + if (otherFilesProcessing.includes(false)) continue + + const otherFiles = otherFilesProcessing as Exclude[] + + if (data.profileId === profile.id) { + profileRecords.push({ + title: data.title, + description: data.description, + dateCreated: data.dateCreated, + file: { + name: data.file.name, + type: data.file.type, + url: URL.createObjectURL( + new File([fileData], data.file.name, { type: data.file.type }) + ) + }, + otherFiles + }) + } + } + return profileRecords +} + +export type CardData = Exclude>, false>[0] diff --git a/tauri-app/src/utils/protocols/document.ts b/tauri-app/src/utils/protocols/document.ts index a248fe6..33838c2 100644 --- a/tauri-app/src/utils/protocols/document.ts +++ b/tauri-app/src/utils/protocols/document.ts @@ -62,7 +62,7 @@ export namespace Record { export type Document = { title: string file: FileMeta, - description?: string + description: string otherFiles: FileMeta[], profileId: string condition: string From 8ffc12ce623bc94279782c61a20f35097a9eb784 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 01:13:03 +0000 Subject: [PATCH 065/120] added date fns --- tauri-app/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tauri-app/package.json b/tauri-app/package.json index ff5225a..9c9b086 100644 --- a/tauri-app/package.json +++ b/tauri-app/package.json @@ -21,6 +21,7 @@ "axios": "^1.6.3", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", + "date-fns": "^3.1.0", "hono": "^3.12.0", "lodash": "^4.17.21", "lucide-react": "^0.298.0", From 3c38834dc41b0d1d166e6a806511c120eb032aa3 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 01:22:44 +0000 Subject: [PATCH 066/120] removed medic page --- tauri-app/src/App.tsx | 2 - tauri-app/src/pages/Records/index.tsx | 4 +- tauri-app/src/pages/medic.tsx | 134 -------------------------- 3 files changed, 2 insertions(+), 138 deletions(-) delete mode 100644 tauri-app/src/pages/medic.tsx diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index be69d99..d609656 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -3,7 +3,6 @@ import useWeb5Store from "./stores/useWeb5Store"; import { useEffect } from "react"; import Connect from "./pages/connect"; import Remedy from "./pages/remedy"; -import MedicPage from "./pages/medic"; import Doctors from "./pages/nearbyDoctor"; import HomePage from "./pages/Home"; import SharedLayout from "./pages/SharedLayout/"; @@ -21,7 +20,6 @@ const router = createHashRouter([ { path: "/records", element: }, { path: "/connect", element: }, { path: "/remedies", element: }, - { path: "/medic", element: }, { path: "/contact", element: }, { path: "/chat", element: }, ], diff --git a/tauri-app/src/pages/Records/index.tsx b/tauri-app/src/pages/Records/index.tsx index 46983e9..7c0d7e8 100644 --- a/tauri-app/src/pages/Records/index.tsx +++ b/tauri-app/src/pages/Records/index.tsx @@ -8,7 +8,7 @@ import DetailCardComponent from "../../components/DetailCardComponent"; import Card from "../../components/Card"; import { useProfile } from "@/stores/profile"; import useWeb5Store from "@/stores/useWeb5Store"; -import { fetchRecords } from "./utils"; +import { CardData, fetchRecords } from "./utils"; const index = () => { const agent = useWeb5Store(state => ({ web5: state.web5!, did: state.did! })) @@ -93,7 +93,7 @@ const index = () => { } onClick={() => setIsAddCardActive(!isAddCardActive)} > - +
diff --git a/tauri-app/src/pages/medic.tsx b/tauri-app/src/pages/medic.tsx deleted file mode 100644 index 9ca1924..0000000 --- a/tauri-app/src/pages/medic.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { FunctionComponent, useEffect, useState } from "react"; -import useWeb5Store from "@/stores/useWeb5Store"; -import DocumentUtils from "@/utils/document"; -import { Record as DocumentRecord } from "@/utils/protocols/document"; -import { Record as Web5Record } from "@web5/api/browser"; -import AuthGuard from "@/components/Auth/Guard"; - -const possibleConditions = [ - "Cancer", - "Diabetes", - "Heart Disease", - "High Blood Pressure", - "High Cholesterol", - "Mental Illness", -] - -const Page: FunctionComponent = () => { - const agent = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })) - const [documentsWithUrl, setDocumentsWithUrl] = useState<{ document: DocumentRecord.Document, fileUrl: string, record: Web5Record }[]>([]) - const [form, setForm] = useState({ - name: "", - file: new File([], ""), - condition: possibleConditions[0] - }) - - useEffect(() => { - (async () => { - const docRecords = await DocumentUtils.fetchDocumentRecords(agent) - if (!docRecords) { - console.log("Failed to fetch document records") - return - } - - const docsWithUrl = [] - for (const docRecord of docRecords) { - const data: DocumentRecord.Document = await docRecord.data.json() - const fileRecord = await DocumentUtils.fetchBlobRecord(agent, data.url) - - if (!fileRecord) - continue - - const file = new File([await fileRecord.data.blob()], data.title, { type: data.encodingFormat }) - - docsWithUrl.push({ - record: docRecord, - document: data, - fileUrl: URL.createObjectURL(file), - }) - } - - setDocumentsWithUrl(docsWithUrl) - })() - }, []) - - const saveMedicalRecord = async () => { - const res = await DocumentUtils.createDocumentRecord(agent, form) - - if (res) { - alert(`Medical record saved: ${res}`) - } - else { - alert("Failed to save record") - } - } - - return ( -
-
{ - e.preventDefault() - saveMedicalRecord() - }}> -
- setForm({ ...form, name: e.target.value })} - placeholder="Name" /> -
-
- { - const fileList = e.target.files - if (!fileList) return - - const file = fileList[0] - if (!file) return - - setForm({ - ...form, - file: file - }) - }} - placeholder="Document" /> -
-
- -
- -
-
- {documentsWithUrl.map(({ record, document, fileUrl: url }) => ( -
- -
- ))} -
-
- ) -} - -const MedicPage: FunctionComponent = () => { - return ( - - - - ) -} - -export default MedicPage From 1af754135a87dc8eeca6be6be34c411c68db1ac9 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 01:22:49 +0000 Subject: [PATCH 067/120] updated dev deps --- tauri-app/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tauri-app/package.json b/tauri-app/package.json index 9c9b086..63472a0 100644 --- a/tauri-app/package.json +++ b/tauri-app/package.json @@ -48,6 +48,7 @@ "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@types/react-window": "^1.8.8", + "@types/readable-stream": "^4.0.10", "@vitejs/plugin-react": "^4.0.3", "autoprefixer": "^10.4.16", "postcss": "^8.4.32", From ccb8c54c2378a0c5f5191e5176802bda9af6df14 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 01:22:53 +0000 Subject: [PATCH 068/120] updated tsconfig --- tauri-app/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tauri-app/tsconfig.json b/tauri-app/tsconfig.json index 36ff4af..0a1cb27 100644 --- a/tauri-app/tsconfig.json +++ b/tauri-app/tsconfig.json @@ -5,6 +5,7 @@ "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, + "esModuleInterop": true, /* Bundler mode */ "moduleResolution": "bundler", From ac3ef61814695982b31c50db515be16c3c7739df Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 01:23:16 +0000 Subject: [PATCH 069/120] remved comments --- tauri-app/src/pages/Records/index.tsx | 43 +-------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/tauri-app/src/pages/Records/index.tsx b/tauri-app/src/pages/Records/index.tsx index 7c0d7e8..6a3c4ef 100644 --- a/tauri-app/src/pages/Records/index.tsx +++ b/tauri-app/src/pages/Records/index.tsx @@ -14,48 +14,7 @@ const index = () => { const agent = useWeb5Store(state => ({ web5: state.web5!, did: state.did! })) const profile = useProfile(state => state.state.profile!) - const [cardsData, setCardsData] = useState([ - // { - // title: "Diabetes Docs", - // description: "documentation of test ran for diagonese of diabtets slated for type dissertion", - // date: "1/2/24", - // file_extension: "pdf", - // file_name: "Diabetes_scan.pdf", - // }, - // { - // title: "Diabetes Docs", - // description: "documentation of test ran for diagonese of diabtets slated for type dissertion", - // date: "1/2/24", - // file_extension: "pdf", - // file_name: "Diabetes_scan.pdf", - // other_files: [ - // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - // ], - // }, - // { - // title: "Diabetes Docs", - // description: "documentation of test ran for diagonese of diabtets slated for type dissertion", - // date: "1/2/24", - // file_extension: "docx", - // file_name: "Diabetes_test.docx", - // other_files: [ - // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - // ], - // }, - // { - // desc: "documentation of test ran for diagonese of diabtets slated for type dissertion", - // date: "1/2/24", - // file_extension: "jpg", - // file_name: "D_IMG1103.jpg", - // file_1_url: "../../../public/pic.jpg", - // other_files: [ - // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - // { file_name: "cat scan", file_extension: "pdf", file_url: "some url" }, - // ], - // }, - ]); + const [cardsData, setCardsData] = useState([]); useEffect(() => { refetchRecords() From 7863d645dc273651d1e3b04fe12b21e6e955defc Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 01:26:33 +0000 Subject: [PATCH 070/120] fixed some type issues --- tauri-app/src/stores/profile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index 62d2eee..f916d86 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -21,7 +21,7 @@ type State = { isSignedIn: false } -type Payload = Omit & { +type Payload = Omit & { profilePicture: File } From 618aa1e5100f6a988f0d407fe5c5be798b9b843b Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 07:28:55 +0000 Subject: [PATCH 071/120] updated the protocol version --- tauri-app/src/utils/user.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tauri-app/src/utils/user.ts b/tauri-app/src/utils/user.ts index 6d04b12..10dec36 100644 --- a/tauri-app/src/utils/user.ts +++ b/tauri-app/src/utils/user.ts @@ -93,7 +93,7 @@ async function createUserDetailsRecord(agent: Agent, payload: CreatePayload) { agent, { ...restPayload, - profilePictureUrl: blobRecord.id, + profilePictureId: blobRecord.id, dateCreated: new Date().toISOString() }, { @@ -153,7 +153,7 @@ async function updateUserDetailsRecord(agent: Agent, idOrRecord: string | Web5Re const data: UserDetailsProtocolRecord.Details = await record.data.json() const { profilePicture, ...restPayload } = payload - let url = data.profilePictureUrl + let url = data.profilePictureId if (profilePicture) { const blobRecord = await DocumentUtils.updateBlobRecord(agent, url, profilePicture) if (!blobRecord) return false @@ -179,7 +179,7 @@ async function deleteUserDetailsRecord(agent: Agent) { const profile: UserDetailsProtocolRecord.Details = await record.data.json() - const hasDeletedProfilePictureRecord = await DocumentUtils.deleteBlobRecord(agent, profile.profilePictureUrl) + const hasDeletedProfilePictureRecord = await DocumentUtils.deleteBlobRecord(agent, profile.profilePictureId) if (!hasDeletedProfilePictureRecord) return false const { status } = await agent.web5.dwn.records.delete({ From b29f11b4d8a32c412bfb8e7261142c5bca2ae180 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 07:29:08 +0000 Subject: [PATCH 072/120] updated the protocol version --- tauri-app/src/utils/protocols/defns.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/utils/protocols/defns.ts b/tauri-app/src/utils/protocols/defns.ts index a634369..7af44e2 100644 --- a/tauri-app/src/utils/protocols/defns.ts +++ b/tauri-app/src/utils/protocols/defns.ts @@ -1 +1 @@ -export const url = "https://dschema.org/v0.0.5" as const +export const url = "https://dschema.org/v0.0.6" as const From b600b3f78dd36adf3b3b1e6509ad3076a08465d1 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 08:18:53 +0000 Subject: [PATCH 073/120] fixed bug --- tauri-app/src/App.tsx | 10 ++++++++-- tauri-app/src/components/Navbar/index.tsx | 11 ++++++----- tauri-app/src/pages/Home/SignUpForm.tsx | 13 ++++--------- tauri-app/src/pages/Home/index.tsx | 1 + tauri-app/src/pages/Records/utils.tsx | 2 ++ tauri-app/src/stores/profile.ts | 6 +++--- tauri-app/src/stores/pulseGlobalStore.ts | 13 ------------- tauri-app/src/utils/user.ts | 22 ++++++++++------------ 8 files changed, 34 insertions(+), 44 deletions(-) delete mode 100644 tauri-app/src/stores/pulseGlobalStore.ts diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index d609656..c88dc27 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -1,4 +1,4 @@ -import { RouterProvider, createHashRouter } from "react-router-dom"; +import { RouterProvider, createHashRouter, Navigate } from "react-router-dom"; import useWeb5Store from "./stores/useWeb5Store"; import { useEffect } from "react"; import Connect from "./pages/connect"; @@ -17,7 +17,13 @@ const router = createHashRouter([ element: , children: [ { path: "/", element: }, - { path: "/records", element: }, + { + path: "/records", element: ( + }> + + + ) + }, { path: "/connect", element: }, { path: "/remedies", element: }, { path: "/contact", element: }, diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index 73a729e..5b48669 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -1,7 +1,6 @@ import ProfileGuard from "../Auth/Profile/Guard"; import "./index.css"; import { NavLink } from "react-router-dom"; -import { usePulseGlobalStore } from "../../stores/pulseGlobalStore.ts"; import useWeb5Store from "@/stores/useWeb5Store.ts"; import { Agent } from "../Auth/types"; import { useProfile } from "@/stores/profile.ts"; @@ -16,8 +15,10 @@ const index = () => { const beginAuthFlow = async (agent: Agent) => { const signedIn = await signIn(agent) - if (!signedIn) + if (!signedIn) { + console.log("displaying auth modal") setShowAuthModal(true) + } } return ( @@ -74,9 +75,9 @@ const index = () => { } > diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index 2dfb6f6..68a1fe6 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -7,6 +7,7 @@ import { z } from "zod" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import toast from "react-hot-toast"; +import { CreatePayload } from "@/utils/user"; const formSchema = z.object({ firstName: z.string().min(1), @@ -40,6 +41,7 @@ const FileUploader: FunctionComponent<{ onChange: (file: File | null) => void }> }; export default function SignUpForm() { + console.log("kfjle") const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })); const submitBtnRef = useRef(null); const { setShowAuthModal, signUp, signIn } = useProfile( @@ -67,14 +69,7 @@ export default function SignUpForm() { } }) - type Payload = { - firstName: string - lastName: string - description: string - profilePicture: File - } - - const createProfile = async (agent: Agent, payload: Payload) => { + const createProfile = async (agent: Agent, payload: CreatePayload) => { const hasSignedUpSuccessfully = await signUp(agent, payload) if (!hasSignedUpSuccessfully) { @@ -82,7 +77,7 @@ export default function SignUpForm() { return } - if (!await signIn(agent)) return + if (!await signIn(agent)) return toast.success('Successfully signed up!') diff --git a/tauri-app/src/pages/Home/index.tsx b/tauri-app/src/pages/Home/index.tsx index 8ab5cf9..867031f 100644 --- a/tauri-app/src/pages/Home/index.tsx +++ b/tauri-app/src/pages/Home/index.tsx @@ -221,6 +221,7 @@ export default function HomePage() {
{showAuthModal && ( + {console.log("fjekkfle") || null} )} diff --git a/tauri-app/src/pages/Records/utils.tsx b/tauri-app/src/pages/Records/utils.tsx index 6f36241..c1d36b6 100644 --- a/tauri-app/src/pages/Records/utils.tsx +++ b/tauri-app/src/pages/Records/utils.tsx @@ -32,6 +32,8 @@ export const fetchRecords = async (agent: Agent, profile: ProfileState) => { const otherFiles = otherFilesProcessing as Exclude[] + console.log(data.profileId) + console.log(data.profileId === profile.id) if (data.profileId === profile.id) { profileRecords.push({ title: data.title, diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index f916d86..bce5670 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -2,7 +2,7 @@ import { create } from "zustand" import { combine } from "zustand/middleware"; import { Record as UserDetailsProtocolRecord } from "@/utils/protocols/user"; import { Agent } from "@/components/Auth/types"; -import UserDetailsUtils from "@/utils/user"; +import UserDetailsUtils, { CreatePayload } from "@/utils/user"; import DocumentUtils from "@/utils/document"; export type ProfileState = { @@ -52,7 +52,7 @@ export const useProfile = create( const profile: UserDetailsProtocolRecord.Details = await profileRecord.data.json() - const profilePicture = await DocumentUtils.fetchBlobRecord(agent, profile.profilePictureUrl) + const profilePicture = await DocumentUtils.fetchBlobRecord(agent, profile.profilePictureId) let profilePictureUrl = "" if (profilePicture) { const profilePictureBlob = await profilePicture.data.blob() @@ -73,7 +73,7 @@ export const useProfile = create( return true }, - signUp: async (agent: Agent, payload: Payload) => { + signUp: async (agent: Agent, payload: CreatePayload) => { const profile = await UserDetailsUtils.createUserDetailsRecord(agent, payload) if (!profile) return false diff --git a/tauri-app/src/stores/pulseGlobalStore.ts b/tauri-app/src/stores/pulseGlobalStore.ts deleted file mode 100644 index 9252348..0000000 --- a/tauri-app/src/stores/pulseGlobalStore.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { create } from "zustand"; - -type PulseGlobalStore = { - showAuthModal: boolean; - toggleAuthModal: () => void; -}; - -export const usePulseGlobalStore = create((set) => ({ - showAuthModal: true, - toggleAuthModal: () => { - set((state) => ({ showAuthModal: !state.showAuthModal })); - }, -})); diff --git a/tauri-app/src/utils/user.ts b/tauri-app/src/utils/user.ts index 10dec36..91db42d 100644 --- a/tauri-app/src/utils/user.ts +++ b/tauri-app/src/utils/user.ts @@ -51,9 +51,9 @@ async function createRecord(agent: Agent, data: UserDetailsProto return record } -async function fetchRecords(agent: Agent, filter: FullFilterObj) { +async function fetchRecords(agent: Agent, filter: FullFilterObj, from?: string) { const { records, status } = await agent.web5.dwn.records.query({ - from: UserDetailsProtocolDID, + from, message: { filter: { ...filter, @@ -71,12 +71,10 @@ async function fetchRecords(agent: Agent, filter: FullFilterObj< return records } -type CreatePayload = { - firstName: string - lastName: string - description: string +export type CreatePayload = Omit & { profilePicture: File, } + async function createUserDetailsRecord(agent: Agent, payload: CreatePayload) { const existingRecord = await fetchUserDetailsRecord(agent) if (existingRecord) { @@ -129,12 +127,12 @@ async function fetchUserDetailsRecords(agent: Agent) { }) } -type UpdatePayload = Partial<{ - firstName: string - lastName: string - description: string - profilePicture: File -}> +type UpdatePayload = Partial< + Omit & + { + profilePicture: File, + } +> async function updateUserDetailsRecord(agent: Agent, idOrRecord: string | Web5Record, payload: Partial) { let record: Web5Record From a18ea86ebb4352a8ecbf375e7fbaa93b591ce536 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 08:19:42 +0000 Subject: [PATCH 074/120] updated protocol --- tauri-app/src/utils/protocols/defns.ts | 2 +- tauri-app/src/utils/protocols/user.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tauri-app/src/utils/protocols/defns.ts b/tauri-app/src/utils/protocols/defns.ts index 7af44e2..d2f24d1 100644 --- a/tauri-app/src/utils/protocols/defns.ts +++ b/tauri-app/src/utils/protocols/defns.ts @@ -1 +1 @@ -export const url = "https://dschema.org/v0.0.6" as const +export const url = "https://dschema.org/v0.0.7" as const diff --git a/tauri-app/src/utils/protocols/user.ts b/tauri-app/src/utils/protocols/user.ts index 227b09f..95967af 100644 --- a/tauri-app/src/utils/protocols/user.ts +++ b/tauri-app/src/utils/protocols/user.ts @@ -32,7 +32,7 @@ export namespace Record { export type Details = { firstName: string lastName: string - profilePictureUrl: string + profilePictureId: string description: string dateCreated: string } From b37e2c6028964db7630317869d2ef59874474930 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Sun, 7 Jan 2024 11:06:25 +0100 Subject: [PATCH 075/120] ahhhh finally found the right one for mobile about to start implementing it --- tauri-app/src/App.tsx | 9 ++--- .../src/components/Auth/Profile/Guard.tsx | 38 ++++++++++++------- tauri-app/src/components/Card/index.tsx | 2 +- tauri-app/src/components/Chat/index.css | 36 ++++++++++++++---- tauri-app/src/components/Chat/index.tsx | 12 ++++++ tauri-app/src/components/Navbar/index.tsx | 2 +- .../src/components/UserFriendList/index.css | 6 +-- .../src/components/UserFriendList/index.tsx | 6 +-- .../src/components/UserProfile/index.css | 5 ++- tauri-app/src/pages/Chat/index.css | 6 +-- 10 files changed, 82 insertions(+), 40 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 77b379a..54a6107 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -38,11 +38,10 @@ function App() { return ( <> - <>{web5 ? :
Connecting...
} - + <> + {web5 ? :
Connecting...
} + + ); } diff --git a/tauri-app/src/components/Auth/Profile/Guard.tsx b/tauri-app/src/components/Auth/Profile/Guard.tsx index b20e4e8..d74f652 100644 --- a/tauri-app/src/components/Auth/Profile/Guard.tsx +++ b/tauri-app/src/components/Auth/Profile/Guard.tsx @@ -3,22 +3,34 @@ import AuthGuard from "../Guard"; import { useProfile } from "@/stores/profile"; import useWeb5Store from "@/stores/useWeb5Store"; -const Guard = ({ children, fallback }: PropsWithChildren & { fallback?: ReactNode }) => { - const agent = useWeb5Store(state => ({ web5: state.web5!, did: state.did! })) - const { isSignedIn, signIn } = useProfile(state => ({ isSignedIn: state.state.isSignedIn, signIn: state.signIn })) +const Guard = ({ + children, + fallback, +}: PropsWithChildren & { fallback?: ReactNode }) => { + const agent = useWeb5Store((state) => ({ + web5: state.web5!, + did: state.did!, + })); + const { isSignedIn, signIn } = useProfile((state) => ({ + isSignedIn: state.state.isSignedIn, + signIn: state.signIn, + })); useEffect(() => { - signIn(agent) - }, [signIn]) + signIn(agent); + }, [signIn]); - if (!isSignedIn) - return <>{fallback} ?? null + if (!isSignedIn) return <>{fallback} ?? null; - return <>{children} -} + return <>{children}; +}; -export default function ProfileGuard(props: PropsWithChildren & { fallback?: ReactNode }) { - return - - +export default function ProfileGuard( + props: PropsWithChildren & { fallback?: ReactNode }, +) { + return ( + + + + ); } diff --git a/tauri-app/src/components/Card/index.tsx b/tauri-app/src/components/Card/index.tsx index d61c871..994dabd 100644 --- a/tauri-app/src/components/Card/index.tsx +++ b/tauri-app/src/components/Card/index.tsx @@ -48,7 +48,7 @@ const index: FC = ({

{title ? title : file_name}

-

{desc}

+

{desc.slice(0, 150)}

{date} diff --git a/tauri-app/src/components/Chat/index.css b/tauri-app/src/components/Chat/index.css index b2b6a6f..a5a6d6c 100644 --- a/tauri-app/src/components/Chat/index.css +++ b/tauri-app/src/components/Chat/index.css @@ -16,9 +16,8 @@ } .chat-message-input-container input { - width: 80%; - height: 30px; - padding: 8px 12px; + width: 85%; + padding: 12px 8px; background: var(--color-slate-accent); border: none; border-radius: 25px; @@ -37,15 +36,36 @@ background: var(--color-blue); box-shadow: var(--box-shadow-blue); font-size: 20px; + outline: none; } .chats-container { - width: 95%; + width: 98%; background: var(--color-light-grey); - height: 90%; + height: 85%; padding: 12px; - border-radius: 15px; + border-radius: 15px 5px 5px 15px; margin: 0 auto; + overflow-y: scroll; + overflow-x: hidden; + height: 600px; +} + +.chats-container::-webkit-scrollbar { + width: 6px; +} + +.chats-container::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1); + border-radius: 0 15px 15px 0; + transform: translateX(-4px); +} + +.chats-container::-webkit-scrollbar-thumb { + width: 2px; + background: var(--color-blue); + border-radius: 5px; + margin: 0 3px; } .msg-container { @@ -60,7 +80,7 @@ padding: 4px 10px; border-radius: 8px 8px 8px 0px; margin-right: auto; - max-width: 300px; + max-width: 400px; } .msg-t { @@ -70,5 +90,5 @@ padding: 4px 10px; border-radius: 8px 8px 0px 8px; margin-left: auto; - max-width: 300px; + max-width: 400px; } diff --git a/tauri-app/src/components/Chat/index.tsx b/tauri-app/src/components/Chat/index.tsx index 9492f36..4bc8898 100644 --- a/tauri-app/src/components/Chat/index.tsx +++ b/tauri-app/src/components/Chat/index.tsx @@ -34,6 +34,18 @@ const index: FC = () => { } isLeft={true} /> + +
diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index 73a729e..8bbe621 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -68,7 +68,7 @@ const index = () => { className="auth_container" onClick={() => web5 && did ? beginAuthFlow({ web5, did }) : null} > -

Join us!

+

Connect Wallet

} diff --git a/tauri-app/src/components/UserFriendList/index.css b/tauri-app/src/components/UserFriendList/index.css index dc82b4b..9082926 100644 --- a/tauri-app/src/components/UserFriendList/index.css +++ b/tauri-app/src/components/UserFriendList/index.css @@ -10,7 +10,7 @@ } .friend-tag-container h1 { - font-size: 18px; + font-size: 15px; font-family: "Roboto"; } @@ -38,12 +38,12 @@ padding: 8px 14px; border-radius: 15px; margin-top: 30px; - width: 300px; + width: 200px; } .friends-list-header { background: var(--color-blue); - padding: 4px 12px; + padding: 8px 12px; border-radius: 10px; color: var(--color-white); font-family: "Roboto"; diff --git a/tauri-app/src/components/UserFriendList/index.tsx b/tauri-app/src/components/UserFriendList/index.tsx index d76e959..38833b0 100644 --- a/tauri-app/src/components/UserFriendList/index.tsx +++ b/tauri-app/src/components/UserFriendList/index.tsx @@ -15,7 +15,7 @@ const FriendTag: FC = ({ return (
-

{friendName.slice(0, 60) + "..."}

+

{friendName.slice(0, 6) + "..."}

{ return (
-

- Friends 45 -

+

Friends

{friendList.map((friend) => { diff --git a/tauri-app/src/components/UserProfile/index.css b/tauri-app/src/components/UserProfile/index.css index b426bd5..084e0cd 100644 --- a/tauri-app/src/components/UserProfile/index.css +++ b/tauri-app/src/components/UserProfile/index.css @@ -1,10 +1,11 @@ .userprofile-container { box-shadow: var(--box-shadow-black); - width: 300px; + width: 200px; text-align: center; border-radius: 15px; - padding: 8px 12px; + padding: 8px 11px; position: relative; + padding-bottom: 12px; } .userprofile-info-container img { diff --git a/tauri-app/src/pages/Chat/index.css b/tauri-app/src/pages/Chat/index.css index d96fd05..4632a88 100644 --- a/tauri-app/src/pages/Chat/index.css +++ b/tauri-app/src/pages/Chat/index.css @@ -4,16 +4,16 @@ justify-content: space-between; align-items: flex-start; position: relative; + max-height: 100%; } .utils-container { - width: 35%; + width: 30%; } .chat-container { - width: 60%; + width: 70%; height: 100%; - height: 40vh; } @media (max-width: 750px) { From a4bd25e15182a81276f7905f193fc1863668811a Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 11:36:59 +0000 Subject: [PATCH 076/120] removed log --- tauri-app/src/pages/Home/SignUpForm.tsx | 1 - tauri-app/src/pages/Home/index.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index 68a1fe6..f059f00 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -81,7 +81,6 @@ export default function SignUpForm() { toast.success('Successfully signed up!') - setShowAuthModal(false) } diff --git a/tauri-app/src/pages/Home/index.tsx b/tauri-app/src/pages/Home/index.tsx index 867031f..8ab5cf9 100644 --- a/tauri-app/src/pages/Home/index.tsx +++ b/tauri-app/src/pages/Home/index.tsx @@ -221,7 +221,6 @@ export default function HomePage() {
{showAuthModal && ( - {console.log("fjekkfle") || null} )} From d822ec116cab61011c499bfad2dd453036f6af08 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 11:37:16 +0000 Subject: [PATCH 077/120] return profile record after creating it --- tauri-app/src/stores/profile.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index bce5670..0592e03 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -55,7 +55,9 @@ export const useProfile = create( const profilePicture = await DocumentUtils.fetchBlobRecord(agent, profile.profilePictureId) let profilePictureUrl = "" if (profilePicture) { + console.log('fetching blob:', profilePicture.data) const profilePictureBlob = await profilePicture.data.blob() + console.log(profilePictureBlob) profilePictureUrl = URL.createObjectURL(profilePictureBlob) } @@ -77,7 +79,7 @@ export const useProfile = create( const profile = await UserDetailsUtils.createUserDetailsRecord(agent, payload) if (!profile) return false - return true + return profile } })) ) From c44e436aa1c32b467ed362c96be27b64bb27d36e Mon Sep 17 00:00:00 2001 From: Suruchi Kumari Date: Sun, 7 Jan 2024 17:46:29 +0530 Subject: [PATCH 078/120] Update README.md --- README.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d3ea6a..5c39ce2 100644 --- a/README.md +++ b/README.md @@ -1 +1,59 @@ -# Web5-Hack \ No newline at end of file +# PulsePal 🌟 + +Safely store medical records with decentralized identifiers and web nodes, ensuring data security. Connect with similar conditions, share home remedies with a rating system, and access specialized doctors based on your location. PulsePal – where advanced technology meets user-friendly design for your secure, connected health journey. + +## What it does + +1. Secure Medical Record Storage: +- Users can securely store their medical records using decentralized identifiers (DIDs) in the app. +- Data stored through decentralized web nodes (DWNs) ensures security and user ownership. + +2. Connect with Similar Medical Conditions: +- An algorithm will match users based on their medical records, enabling them to chat and connect. +- Users can share experiences, insights, and support each other within the platform. + +3. Home Remedies Section: +- Users can contribute and share simple, effective home remedies. +- Remedies will be rated by users to gauge their usefulness. + +4. Recommend specialized doctors in your nearby areas, based on your current location + +## Setting up Local Development + +1. Clone the repository + +``` +git clone https://github.com/coder12git/Web5-Hack.git +``` + +2. Navigate to the project folder + +``` +cd Web5-Hack/tauri-app +``` + +3. Install dependencies + +``` +npm install +``` + +4. To start the server run + +``` +npm run dev +``` + +## What's next for Pulsepal + +1. Personalized Health Insights: "Our plan includes integrating AI-driven analytics to offer personalized health insights, assessing individual health risks and predicting future health trends based on users' medical records." + +2. Natural Language Processing (NLP) Chatbot: "We aim to implement an NLP-powered chatbot that assists users in comprehending medical terminology, interpreting test results, and providing preliminary guidance in emergencies based on entered symptoms." + +3. AI-Driven Diagnostics: "Incorporating an AI system for preliminary diagnostics, we intend to analyze symptoms and user-entered data to provide suggestive measures or identify potential health issues, prompting users to seek professional medical advice." + +4. Augmented Reality (AR) for First Aid Guidance: "Our future plan involves integrating AR technology to guide users through basic first aid procedures by overlaying instructional visuals onto real-time surroundings." + +5. Health Gamification and Incentivization: "To encourage healthy habits, we plan to introduce gamification within PulsePal, utilizing AI to personalize challenges, rewards, and reminders aligned with individual health goals." + +6. Predictive Appointment Scheduling: "Utilizing AI algorithms, we aim to predict potential health concerns or follow-up appointments based on stored medical records, proactively suggesting relevant appointments or check-ups." From 128a22c1278b68d73c4d9de785ffe2c8b9e85eff Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 12:32:50 +0000 Subject: [PATCH 079/120] removed script --- server/script.ts | 94 ------------------------------------------------ 1 file changed, 94 deletions(-) delete mode 100644 server/script.ts diff --git a/server/script.ts b/server/script.ts deleted file mode 100644 index e58a7e5..0000000 --- a/server/script.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Web5 } from "@web5/api"; -import { protocols } from "@frontend/utils/protocols"; -import DocumentUtils from "@frontend/utils/document"; -import { Agent } from "@backend/utils"; - -async function configureProtocols(agent: Agent) { - console.log("=== CONFIGURE PROTOCOL ===") - - for (const protocol of protocols) { - const { protocols } = await agent.web5.dwn.protocols.query({ - message: { - filter: { - protocol: protocol.protocol, - } - } - }) - - if (protocols.length > 0) { - console.log("Protocol already exists:", protocol.protocol) - continue - } - - const { protocol: configuredProtocol, status: localProtocolConfigurationStatus } = await agent.web5.dwn.protocols.configure({ - message: { - definition: Object.assign({ ...protocol }), - } - }); - - if (!configuredProtocol) { - console.log("Failed to configure protocol:", localProtocolConfigurationStatus) - return - } - - console.log("Configured protocol on local DWN:", protocol.protocol) - const { status: remoteProtocolConfigurationStatus } = await configuredProtocol.send(agent.did) - - console.log("Sent protocol to remote DWN") - console.log(protocol.protocol, remoteProtocolConfigurationStatus) - } - - console.log("=== END CONFIGURE PROTOCOL ===") -} - -async function queryConditions(agent: Agent) { - console.log("=== QUERY CONDITIONS ===") - - const records = await DocumentUtils.fetchDocumentRecords(agent) - if (!records) { - console.log("No records found") - return - } - - if (records.length > 0) { - for (const record of records) { - // console.log("author:", record.author) - // console.log("recipient:", record.recipient) - // Bun.write("records/" + record.id + ".json", JSON.stringify(record)) - // console.log(record.author === record.target) - console.log(await record.data.json()) - } - } - - console.log("=== END QUERY CONDITIONS ===") -} - -async function createCondition(agent: Agent) { - console.log("=== CREATE CONDITION ===") - - const record = await DocumentUtils.createDocumentRecord(agent, { name: "test", condition: "command", file: new File([], "", { type: "image/png" }) }) - - if (!record) return false - - console.log("=== END CREATE CONDITION ===") -} - -async function connect() { - console.log("=== CONNECT ===") - const agent = await Web5.connect({ - sync: "5s", - }); - - console.log("=== END CONNECT ===") - - return agent -} -async function main() { - const agent = await connect() - await configureProtocols(agent) - await queryConditions(agent) - // await createCondition(agent) - // await queryConditions(agent) -} - -main() From 683c2b7bfa00c20d647c1f1cc431bdee4c672c0f Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 12:35:25 +0000 Subject: [PATCH 080/120] updated the protocol and record form --- .gitignore | 1 + tauri-app/src/components/Auth/Profile/Guard.tsx | 8 +------- tauri-app/src/components/Card/index.tsx | 2 +- tauri-app/src/pages/Home/SignUpForm.tsx | 1 - tauri-app/src/pages/Records/utils.tsx | 5 +++-- tauri-app/src/stores/profile.ts | 6 ++---- 6 files changed, 8 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 649ac14..a873b84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ pnpm-lock.yaml *.tsbuildinfo +utils/ diff --git a/tauri-app/src/components/Auth/Profile/Guard.tsx b/tauri-app/src/components/Auth/Profile/Guard.tsx index b20e4e8..527f8bf 100644 --- a/tauri-app/src/components/Auth/Profile/Guard.tsx +++ b/tauri-app/src/components/Auth/Profile/Guard.tsx @@ -1,15 +1,9 @@ import { PropsWithChildren, ReactNode, useEffect } from "react"; import AuthGuard from "../Guard"; import { useProfile } from "@/stores/profile"; -import useWeb5Store from "@/stores/useWeb5Store"; const Guard = ({ children, fallback }: PropsWithChildren & { fallback?: ReactNode }) => { - const agent = useWeb5Store(state => ({ web5: state.web5!, did: state.did! })) - const { isSignedIn, signIn } = useProfile(state => ({ isSignedIn: state.state.isSignedIn, signIn: state.signIn })) - - useEffect(() => { - signIn(agent) - }, [signIn]) + const { isSignedIn } = useProfile(state => ({ isSignedIn: state.state.isSignedIn, signIn: state.signIn })) if (!isSignedIn) return <>{fallback} ?? null diff --git a/tauri-app/src/components/Card/index.tsx b/tauri-app/src/components/Card/index.tsx index d61c871..4edfdac 100644 --- a/tauri-app/src/components/Card/index.tsx +++ b/tauri-app/src/components/Card/index.tsx @@ -48,7 +48,7 @@ const index: FC = ({

{title ? title : file_name}

-

{desc}

+

{desc.substring(0, 50)}

{date} diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index f059f00..b232969 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -41,7 +41,6 @@ const FileUploader: FunctionComponent<{ onChange: (file: File | null) => void }> }; export default function SignUpForm() { - console.log("kfjle") const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })); const submitBtnRef = useRef(null); const { setShowAuthModal, signUp, signIn } = useProfile( diff --git a/tauri-app/src/pages/Records/utils.tsx b/tauri-app/src/pages/Records/utils.tsx index c1d36b6..852ceac 100644 --- a/tauri-app/src/pages/Records/utils.tsx +++ b/tauri-app/src/pages/Records/utils.tsx @@ -2,6 +2,7 @@ import { Agent } from "@/components/Auth/types" import { ProfileState } from "@/stores/profile" import { Record as DocumentRecord } from "@/utils/protocols/document"; import DocumentUtils from "@/utils/document" +import BlobUtils from "@/utils/blob"; export const fetchRecords = async (agent: Agent, profile: ProfileState) => { const records = await DocumentUtils.fetchDocumentRecords(agent) @@ -10,12 +11,12 @@ export const fetchRecords = async (agent: Agent, profile: ProfileState) => { const profileRecords = [] for (const record of records) { const data: DocumentRecord.Document = await record.data.json() - const fileRecord = await DocumentUtils.fetchBlobRecord(agent, data.file.id) + const fileRecord = await BlobUtils.fetchBlobRecord(agent, { recordId: data.file.id }) if (!fileRecord) continue const fileData = await fileRecord.data.blob() const otherFilesProcessing = await Promise.all(data.otherFiles.map(async file => { - const record = await DocumentUtils.fetchBlobRecord(agent, file.id) + const record = await BlobUtils.fetchBlobRecord(agent, { recordId: file.id }) if (!record) return false const data = await record.data.blob() diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index 0592e03..69aa213 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -3,7 +3,7 @@ import { combine } from "zustand/middleware"; import { Record as UserDetailsProtocolRecord } from "@/utils/protocols/user"; import { Agent } from "@/components/Auth/types"; import UserDetailsUtils, { CreatePayload } from "@/utils/user"; -import DocumentUtils from "@/utils/document"; +import BlobUtils from "@/utils/blob"; export type ProfileState = { id: string @@ -52,12 +52,10 @@ export const useProfile = create( const profile: UserDetailsProtocolRecord.Details = await profileRecord.data.json() - const profilePicture = await DocumentUtils.fetchBlobRecord(agent, profile.profilePictureId) + const profilePicture = await BlobUtils.fetchBlobRecord(agent, { recordId: profile.profilePictureId }) let profilePictureUrl = "" if (profilePicture) { - console.log('fetching blob:', profilePicture.data) const profilePictureBlob = await profilePicture.data.blob() - console.log(profilePictureBlob) profilePictureUrl = URL.createObjectURL(profilePictureBlob) } From ba64d6d679442ae0a457de901c4af8aec6474e8c Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 12:36:31 +0000 Subject: [PATCH 081/120] updated protocols --- tauri-app/src/utils/document.ts | 124 +++------------------- tauri-app/src/utils/protocols/defns.ts | 2 +- tauri-app/src/utils/protocols/document.ts | 23 ---- tauri-app/src/utils/protocols/index.ts | 2 + tauri-app/src/utils/user.ts | 37 ++++--- 5 files changed, 41 insertions(+), 147 deletions(-) diff --git a/tauri-app/src/utils/document.ts b/tauri-app/src/utils/document.ts index ab8245d..47382b6 100644 --- a/tauri-app/src/utils/document.ts +++ b/tauri-app/src/utils/document.ts @@ -1,5 +1,6 @@ import { Web5, Record as Web5Record } from "@web5/api/browser" -import DocumentProtocol, { Record as DocumentProtocolRecord, did as DocumentProtocolDID } from "./protocols/document"; +import DocumentProtocol, { Record } from "./protocols/document"; +import BlobUtils from "./blob"; import _ from "lodash"; type Agent = { @@ -27,10 +28,7 @@ type FullMessageObj = { published: typeof DocumentProtocol["published"] } -async function createRecord(agent: Agent, data: DocumentProtocolRecord.Document, message: FullMessageObj<"document">): Promise; -async function createRecord(agent: Agent, data: DocumentProtocolRecord.File, message: FullMessageObj<"blob">): Promise; - -async function createRecord(agent: Agent, data: DocumentProtocolRecord.Document | DocumentProtocolRecord.File, message: FullMessageObj) { +async function createRecord(agent: Agent, data: Record.Document, message: FullMessageObj) { const { record, status } = await agent.web5.dwn.records.create({ data, message: Object.assign({ @@ -44,7 +42,8 @@ async function createRecord(agent: Agent, data: DocumentProtocol return false } - const { status: syncStatus } = await record.send(DocumentProtocolDID) + // const { status: syncStatus } = await record.send(DocumentProtocolDID) + const { status: syncStatus } = await record.send(agent.did) if (syncStatus.code !== 202) { console.log("Failed to sync record with remote DWN:", syncStatus) @@ -55,7 +54,7 @@ async function createRecord(agent: Agent, data: DocumentProtocol async function fetchRecords(agent: Agent, filter: FullFilterObj) { const { records, status } = await agent.web5.dwn.records.query({ - from: DocumentProtocolDID, + // from: DocumentProtocolDID, message: { filter: { ...filter, @@ -73,7 +72,7 @@ async function fetchRecords(agent: Agent, filter: FullFilterObj< return records } -type CreatePayload = Omit & +type CreatePayload = Omit & { title?: string file: File, @@ -83,7 +82,7 @@ type CreatePayload = Omit, - published: DocumentProtocol.published, - } - ) - - if (!record) { - console.error("Failed to create blob record") - return false - } - - return record -} - async function fetchDocumentRecord(agent: Agent, filter: FilterObj) { const records = await fetchRecords(agent, { ...filter, @@ -169,26 +148,8 @@ async function fetchDocumentRecords(agent: Agent) { }) } -async function fetchBlobRecord(agent: Agent, id: string) { - const records = await fetchRecords(agent, { - protocolPath: "blob", - schema: DocumentProtocol.types.blob.schema, - }) - - if (!records || !records[0]) return false - - return records[0] -} - -async function fetchBlobRecords(agent: Agent) { - return fetchRecords(agent, { - protocolPath: "blob", - schema: DocumentProtocol.types.blob.schema, - }) -} - type UpdatePayload = Partial< - Omit & + Omit & { file: File, otherFiles: File[] @@ -212,12 +173,12 @@ async function updateDocumentRecord(agent: Agent, idOrRecord: string | Web5Recor record = idOrRecord } - const data: DocumentProtocolRecord.Document = await record.data.json() + const data: Record.Document = await record.data.json() const { file, otherFiles, ...restPayload } = payload const fileData = data.file if (file) { - const blobRecord = await updateBlobRecord(agent, data.file.id, file) + const blobRecord = await BlobUtils.updateBlobRecord(agent, data.file.id, { file }) if (!blobRecord) return false fileData.id = blobRecord.id @@ -232,7 +193,7 @@ async function updateDocumentRecord(agent: Agent, idOrRecord: string | Web5Recor const file = otherFiles[i] const otherFile = otherFilesData[i] - const blobRecord = await updateBlobRecord(agent, otherFile.id, file) + const blobRecord = await BlobUtils.updateBlobRecord(agent, otherFile.id, { file }) if (!blobRecord) return false otherFile.id = blobRecord.id @@ -248,7 +209,7 @@ async function updateDocumentRecord(agent: Agent, idOrRecord: string | Web5Recor for (let i = otherFilesData.length; i < otherFiles.length; i++) { const file = otherFiles[i] - const blobRecord = await createBlobRecord(agent, file) + const blobRecord = await BlobUtils.createBlobRecord(agent, { file }) if (!blobRecord) return false otherFilesData.push({ @@ -273,33 +234,6 @@ async function updateDocumentRecord(agent: Agent, idOrRecord: string | Web5Recor return record } -async function updateBlobRecord(agent: Agent, id: string, file: File): Promise; -async function updateBlobRecord(agent: Agent, record: Web5Record, file: File): Promise; - -async function updateBlobRecord(agent: Agent, idOrRecord: string | Web5Record, file: File): Promise { - let record: Web5Record - - if (typeof idOrRecord === "string") { - const blobRecord = await fetchBlobRecord(agent, idOrRecord) - if (!blobRecord) return false - record = blobRecord - } - else { - record = idOrRecord - } - - const { status } = await record.update({ - data: new Blob([file], { type: file.type }) - }) - - if (status.code !== 202) { - console.log("Failed to sync blob record update with remote DWN:", status) - return false - } - - return record -} - async function deleteDocumentRecord(agent: Agent, id: string): Promise; async function deleteDocumentRecord(agent: Agent, record: Web5Record): Promise; @@ -317,13 +251,13 @@ async function deleteDocumentRecord(agent: Agent, idOrRecord: string | Web5Recor record = idOrRecord } - const document: DocumentProtocolRecord.Document = await record.data.json() + const document: Record.Document = await record.data.json() - const hasDeletedBlobRecord = await deleteBlobRecord(agent, document.file.id) + const hasDeletedBlobRecord = await BlobUtils.deleteBlobRecord(agent, document.file.id) if (!hasDeletedBlobRecord) return false for (const otherFile of document.otherFiles) { - await deleteBlobRecord(agent, otherFile.id) + await BlobUtils.deleteBlobRecord(agent, otherFile.id) } const { status } = await agent.web5.dwn.records.delete({ @@ -339,36 +273,12 @@ async function deleteDocumentRecord(agent: Agent, idOrRecord: string | Web5Recor return true } -async function deleteBlobRecord(agent: Agent, id: string): Promise; -async function deleteBlobRecord(agent: Agent, record: Web5Record): Promise; - -async function deleteBlobRecord(agent: Agent, idOrRecord: string | Web5Record): Promise { - const record = typeof idOrRecord === "string" ? await fetchBlobRecord(agent, idOrRecord) : idOrRecord - if (!record) return false - - const { status } = await agent.web5.dwn.records.delete({ - message: { - recordId: record.id - } - }) - if (status.code !== 202) { - console.log("Failed to delete blob record:", status) - return false - } - - return true -} - const DocumentUtils = { createDocumentRecord, - createBlobRecord, fetchDocumentRecord, fetchDocumentRecords, - fetchBlobRecord, updateDocumentRecord, - updateBlobRecord, deleteDocumentRecord, - deleteBlobRecord } export default DocumentUtils diff --git a/tauri-app/src/utils/protocols/defns.ts b/tauri-app/src/utils/protocols/defns.ts index d2f24d1..b1ffec6 100644 --- a/tauri-app/src/utils/protocols/defns.ts +++ b/tauri-app/src/utils/protocols/defns.ts @@ -1 +1 @@ -export const url = "https://dschema.org/v0.0.7" as const +export const url = "https://dschema.org/v0.0.8" as const diff --git a/tauri-app/src/utils/protocols/document.ts b/tauri-app/src/utils/protocols/document.ts index 33838c2..a13f7e6 100644 --- a/tauri-app/src/utils/protocols/document.ts +++ b/tauri-app/src/utils/protocols/document.ts @@ -10,15 +10,6 @@ const DocumentProtocol = { dataFormats: [ "application/json" ] - }, - blob: { - schema: `${protocol}/schema/blob.json`, - dataFormats: [ - "image/png", - "image/jpeg", - "image/jpg", - "application/pdf" - ] } }, structure: { @@ -33,18 +24,6 @@ const DocumentProtocol = { can: "write" } ] - }, - blob: { - $actions: [ - { - who: "anyone", - can: "read" - }, - { - who: "anyone", - can: "write" - } - ] } } } as const @@ -57,8 +36,6 @@ export namespace Record { name: string } - export type File = Blob - export type Document = { title: string file: FileMeta, diff --git a/tauri-app/src/utils/protocols/index.ts b/tauri-app/src/utils/protocols/index.ts index 1c0a671..e6a7e25 100644 --- a/tauri-app/src/utils/protocols/index.ts +++ b/tauri-app/src/utils/protocols/index.ts @@ -1,9 +1,11 @@ import DocumentProtocol from "./document" import ConditionsProtocol from "./conditions" import UserDetailsProtocol from "./user" +import BlobProtocol from "./blob" export const protocols = [ DocumentProtocol, + BlobProtocol, UserDetailsProtocol, ConditionsProtocol, ] diff --git a/tauri-app/src/utils/user.ts b/tauri-app/src/utils/user.ts index 91db42d..73b8238 100644 --- a/tauri-app/src/utils/user.ts +++ b/tauri-app/src/utils/user.ts @@ -1,7 +1,7 @@ import { Web5, Record as Web5Record } from "@web5/api/browser" import UserDetailsProtocol, { Record as UserDetailsProtocolRecord, did as UserDetailsProtocolDID } from "./protocols/user"; -import DocumentUtils from "./document"; import _ from "lodash"; +import BlobUtils from "./blob"; type Agent = { web5: Web5 @@ -42,18 +42,22 @@ async function createRecord(agent: Agent, data: UserDetailsProto return false } - const { status: syncStatus } = await record.send(UserDetailsProtocolDID) + const { status: protocolDwnSyncStatus } = await record.send(UserDetailsProtocolDID) + if (protocolDwnSyncStatus.code !== 202) { + console.log("Failed to sync record with protocol remote DWN:", protocolDwnSyncStatus) + } - if (syncStatus.code !== 202) { - console.log("Failed to sync record with remote DWN:", syncStatus) + const { status: remoteDwnSyncStatus } = await record.send(agent.did) + if (remoteDwnSyncStatus.code !== 202) { + console.log("Failed to sync record with remote DWN:", remoteDwnSyncStatus) } return record } -async function fetchRecords(agent: Agent, filter: FullFilterObj, from?: string) { +async function fetchRecords(agent: Agent, filter: FullFilterObj, remote?: boolean) { const { records, status } = await agent.web5.dwn.records.query({ - from, + from: remote ? UserDetailsProtocolDID : undefined, message: { filter: { ...filter, @@ -82,7 +86,7 @@ async function createUserDetailsRecord(agent: Agent, payload: CreatePayload) { return false } - const blobRecord = await DocumentUtils.createBlobRecord(agent, payload.profilePicture) + const blobRecord = await BlobUtils.createBlobRecord(agent, { file: payload.profilePicture }, true) if (!blobRecord) return false const { profilePicture, ...restPayload } = payload @@ -109,13 +113,13 @@ async function createUserDetailsRecord(agent: Agent, payload: CreatePayload) { return record } -async function fetchUserDetailsRecord(agent: Agent) { +async function fetchUserDetailsRecord(agent: Agent, remote?: boolean) { const records = await fetchRecords(agent, { schema: UserDetailsProtocol.types.details.schema, protocolPath: "details", - }) + }, remote) - if (!records || !records[0]) return false + if (!records) return false return records[0] } @@ -124,7 +128,7 @@ async function fetchUserDetailsRecords(agent: Agent) { return fetchRecords(agent, { protocolPath: "details", schema: UserDetailsProtocol.types.details.schema, - }) + }, true) } type UpdatePayload = Partial< @@ -151,16 +155,16 @@ async function updateUserDetailsRecord(agent: Agent, idOrRecord: string | Web5Re const data: UserDetailsProtocolRecord.Details = await record.data.json() const { profilePicture, ...restPayload } = payload - let url = data.profilePictureId + let profilePictureId = data.profilePictureId if (profilePicture) { - const blobRecord = await DocumentUtils.updateBlobRecord(agent, url, profilePicture) + const blobRecord = await BlobUtils.updateBlobRecord(agent, profilePictureId, { file: profilePicture }) if (!blobRecord) return false - url = blobRecord.id + profilePictureId = blobRecord.id } const { status } = await record.update({ - data: _.merge(data, Object.assign(restPayload, { url })) + data: _.merge(data, Object.assign(restPayload, { profilePictureId })) }) if (status.code !== 202) { @@ -177,7 +181,7 @@ async function deleteUserDetailsRecord(agent: Agent) { const profile: UserDetailsProtocolRecord.Details = await record.data.json() - const hasDeletedProfilePictureRecord = await DocumentUtils.deleteBlobRecord(agent, profile.profilePictureId) + const hasDeletedProfilePictureRecord = await BlobUtils.deleteBlobRecord(agent, profile.profilePictureId) if (!hasDeletedProfilePictureRecord) return false const { status } = await agent.web5.dwn.records.delete({ @@ -196,6 +200,7 @@ async function deleteUserDetailsRecord(agent: Agent) { const UserDetailsUtils = { fetchUserDetailsRecord, + fetchUserDetailsRecords, updateUserDetailsRecord, createUserDetailsRecord, deleteUserDetailsRecord From a05c87d667beb5b0440025550b44dc5bcad73e53 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 12:37:03 +0000 Subject: [PATCH 082/120] added a new blob protocol --- tauri-app/src/utils/blob.ts | 181 ++++++++++++++++++++++++++ tauri-app/src/utils/protocols/blob.ts | 42 ++++++ 2 files changed, 223 insertions(+) create mode 100644 tauri-app/src/utils/blob.ts create mode 100644 tauri-app/src/utils/protocols/blob.ts diff --git a/tauri-app/src/utils/blob.ts b/tauri-app/src/utils/blob.ts new file mode 100644 index 0000000..67ea009 --- /dev/null +++ b/tauri-app/src/utils/blob.ts @@ -0,0 +1,181 @@ +import { Web5, Record as Web5Record } from "@web5/api/browser" +import BlobProtocol, { Record, did as BlobProtocolDID } from "./protocols/blob"; +import _ from "lodash"; + +type Agent = { + web5: Web5 + did: string +} + +type FilterObj = { + recordId: string, +} + +type Type = keyof typeof BlobProtocol["types"] +type Schema = typeof BlobProtocol["types"][T]["schema"] +type DataFormat = typeof BlobProtocol["types"][T]["dataFormats"][number] + +type FullFilterObj = { + protocolPath: T + schema: Schema +} + +type FullMessageObj = { + schema: Schema + protocolPath: T + dataFormat: DataFormat + published: typeof BlobProtocol["published"] +} + +async function createRecord(agent: Agent, data: Record.Blob, message: FullMessageObj, remote?: boolean) { + const { record, status } = await agent.web5.dwn.records.create({ + data, + message: Object.assign({ + ...message, + protocol: BlobProtocol.protocol, + }) + }); + + if (!record) { + console.error("Failed to create record:", status) + return false + } + + if (remote) { + const { status: syncStatus } = await record.send(BlobProtocolDID) + + if (syncStatus.code !== 202) { + console.log("Failed to sync record protocol with remote DWN:", syncStatus) + return false + } + } + + const { status: syncStatus } = await record.send(agent.did) + + if (syncStatus.code !== 202) { + console.log("Failed to sync record with remote DWN:", syncStatus) + + if (remote) + return false + } + + return record +} + +async function fetchRecords(agent: Agent, filter: FullFilterObj, remote?: boolean) { + const { records, status } = await agent.web5.dwn.records.query({ + from: remote ? BlobProtocolDID : undefined, + message: { + filter: { + ...filter, + protocol: BlobProtocol.protocol, + }, + // @ts-ignore + dateSort: "createdAscending", + }, + }); + + if (!records) { + console.log("Failed to fetch records:", status) + return false + } + return records +} + +type CreatePayload = { + file: File +} +async function createBlobRecord(agent: Agent, payload: CreatePayload, remote?: boolean) { + const { file } = payload + + const record = await createRecord( + agent, + new Blob([file], { type: file.type }), + { + schema: BlobProtocol.types.blob.schema, + protocolPath: "blob", + dataFormat: file.type as DataFormat<"blob">, + published: BlobProtocol.published, + }, + remote + ) + + if (!record) { + console.error("Failed to create blob record") + return false + } + + return record +} + +async function fetchBlobRecord(agent: Agent, filter: FilterObj) { + const records = await fetchRecords(agent, { + ...filter, + protocolPath: "blob", + schema: BlobProtocol.types.blob.schema, + }) + + if (!records || !records[0]) return false + + return records[0] +} + +async function fetchBlobRecords(agent: Agent) { + return fetchRecords(agent, { + protocolPath: "blob", + schema: BlobProtocol.types.blob.schema, + }) +} + +type UpdatePayload = CreatePayload + +async function updateBlobRecord(agent: Agent, id: string, payload: UpdatePayload): Promise; +async function updateBlobRecord(agent: Agent, record: Web5Record, payload: UpdatePayload): Promise; + +async function updateBlobRecord(agent: Agent, idOrRecord: string | Web5Record, payload: UpdatePayload): Promise { + const { file } = payload + + const record = typeof idOrRecord === "string" ? await fetchBlobRecord(agent, { recordId: idOrRecord }) : idOrRecord + if (!record) return false + + const { status } = await record.update({ + data: new Blob([file], { type: file.type }) + }) + + if (status.code !== 202) { + console.log("Failed to sync blob record update with remote DWN:", status) + return false + } + + return record +} + +async function deleteBlobRecord(agent: Agent, id: string): Promise; +async function deleteBlobRecord(agent: Agent, record: Web5Record): Promise; + +async function deleteBlobRecord(agent: Agent, idOrRecord: string | Web5Record): Promise { + const record = typeof idOrRecord === "string" ? await fetchBlobRecord(agent, { recordId: idOrRecord }) : idOrRecord + if (!record) return false + + const { status } = await agent.web5.dwn.records.delete({ + message: { + recordId: record.id + } + }) + if (status.code !== 202) { + console.log("Failed to delete blob record:", status) + return false + } + + return true +} + +const BlobUtils = { + createBlobRecord, + fetchBlobRecords, + fetchBlobRecord, + updateBlobRecord, + deleteBlobRecord +} + +export default BlobUtils diff --git a/tauri-app/src/utils/protocols/blob.ts b/tauri-app/src/utils/protocols/blob.ts new file mode 100644 index 0000000..f6d65a5 --- /dev/null +++ b/tauri-app/src/utils/protocols/blob.ts @@ -0,0 +1,42 @@ +import { url } from "./defns" +const protocol = `${url}/protocols/blob` as const + +const BlobProtocol = { + protocol, + published: true, + types: { + blob: { + schema: `${protocol}/schema/blob.json`, + dataFormats: [ + "image/png", + "image/jpeg", + "image/jpg", + "application/pdf" + ] + } + }, + structure: { + blob: { + $actions: [ + { + who: "anyone", + // of: "blob", + can: "read" + }, + { + who: "anyone", + // of: "blob", + can: "write" + } + ] + } + } +} as const + +export namespace Record { + export type Blob = globalThis.Blob +} + +export const did = "did:ion:EiAx_twrw3f0yLOv3Pe6pk4gWG4miV9SVXiHe_Q4lMn8Ow:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJkd24tc2lnIiwicHVibGljS2V5SndrIjp7ImNydiI6IkVkMjU1MTkiLCJrdHkiOiJPS1AiLCJ4IjoiV1M1QXFqeDA1V2Z0YWMwYUhYRnpGNV9wZjM2eTVPQ0N0Qy1tM1lCTFo4WSJ9LCJwdXJwb3NlcyI6WyJhdXRoZW50aWNhdGlvbiJdLCJ0eXBlIjoiSnNvbldlYktleTIwMjAifSx7ImlkIjoiZHduLWVuYyIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJpSnpYYkljR0FHdm1QMzd2Z2VfTjB1M3FadllmLWpteGdyM2RTaDUtOE5vIiwieSI6InBBc1BuQ1hLcXlXRWhiS1ZDWjFJejhrWkljVVRXQXBNS2NOS3VtQ3R4T2cifSwicHVycG9zZXMiOlsia2V5QWdyZWVtZW50Il0sInR5cGUiOiJKc29uV2ViS2V5MjAyMCJ9XSwic2VydmljZXMiOlt7ImlkIjoiZHduIiwic2VydmljZUVuZHBvaW50Ijp7ImVuY3J5cHRpb25LZXlzIjpbIiNkd24tZW5jIl0sIm5vZGVzIjpbImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduNSIsImh0dHBzOi8vZHduLnRiZGRldi5vcmcvZHduMyJdLCJzaWduaW5nS2V5cyI6WyIjZHduLXNpZyJdfSwidHlwZSI6IkRlY2VudHJhbGl6ZWRXZWJOb2RlIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlBSVIyQWFjQXZFVi16ODgwWHl2eHB4bWMzWDJkbDdYVmcwRHdWTGtfTms0QSJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpRGlvWktVc3cyZ0gzU29Nb0V5T0duVE9NQkZURFhZZ1hFX3Z6am5RU0M5aUEiLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUQzU0JIaEtXXzduUF9QamV1WDcybDRjcXVTMWVPVTBCUk1EcW1vdnFpVGxnIn19" + +export default BlobProtocol From 5c090e30102a1df35560867a13b90f2e156ec8c7 Mon Sep 17 00:00:00 2001 From: coder12git Date: Sun, 7 Jan 2024 18:10:52 +0530 Subject: [PATCH 083/120] added chat initialization and deleted server Signed-off-by: coder12git --- server/.gitignore | 146 --- server/package-lock.json | 2354 ---------------------------------- server/package.json | 18 - server/script.ts | 94 -- server/server.ts | 9 - server/src/app.ts | 32 - server/src/middleware.ts | 22 - server/src/utils.ts | 89 -- server/tsconfig.json | 22 - tauri-app/package-lock.json | 54 +- tauri-app/src/pages/chat.tsx | 278 ++++ 11 files changed, 330 insertions(+), 2788 deletions(-) delete mode 100644 server/.gitignore delete mode 100644 server/package-lock.json delete mode 100644 server/package.json delete mode 100644 server/script.ts delete mode 100644 server/server.ts delete mode 100644 server/src/app.ts delete mode 100644 server/src/middleware.ts delete mode 100644 server/src/utils.ts delete mode 100644 server/tsconfig.json create mode 100644 tauri-app/src/pages/chat.tsx diff --git a/server/.gitignore b/server/.gitignore deleted file mode 100644 index 5b81ddf..0000000 --- a/server/.gitignore +++ /dev/null @@ -1,146 +0,0 @@ -# Created by https://www.toptal.com/developers/gitignore/api/node -# Edit at https://www.toptal.com/developers/gitignore?templates=node - -### Node ### -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - -### Node Patch ### -# Serverless Webpack directories -.webpack/ - -# Optional stylelint cache - -# SvelteKit build / generate output -.svelte-kit - -# End of https://www.toptal.com/developers/gitignore/api/node - -DATA/ diff --git a/server/package-lock.json b/server/package-lock.json deleted file mode 100644 index 9794805..0000000 --- a/server/package-lock.json +++ /dev/null @@ -1,2354 +0,0 @@ -{ - "name": "server", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@hono/node-server": "^1.4.0", - "@hono/zod-validator": "^0.1.11", - "@web5/api": "^0.8.3", - "hono": "^3.12.0", - "true-myth": "5", - "tsconfig-paths": "^4.2.0", - "zod": "^3.22.4" - }, - "devDependencies": { - "tsx": "^4.7.0", - "typescript": "^5.3.3" - } - }, - "node_modules/@assemblyscript/loader": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.9.4.tgz", - "integrity": "sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA==" - }, - "node_modules/@decentralized-identity/ion-pow-sdk": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/@decentralized-identity/ion-pow-sdk/-/ion-pow-sdk-1.0.17.tgz", - "integrity": "sha512-vk7DTDM8aKDbFyu1ad/qkoRrGL4q+KvNeL/FNZXhkWPaDhVExBN/qGEoRLf1YSfFe+myto3+4RYTPut+riiqnw==", - "dependencies": { - "buffer": "6.0.3", - "cross-fetch": "3.1.5", - "hash-wasm": "4.9.0" - } - }, - "node_modules/@decentralized-identity/ion-pow-sdk/node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dependencies": { - "node-fetch": "2.6.7" - } - }, - "node_modules/@decentralized-identity/ion-pow-sdk/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/@decentralized-identity/ion-sdk": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@decentralized-identity/ion-sdk/-/ion-sdk-1.0.1.tgz", - "integrity": "sha512-+P+DXcRSFjsEsI5KIqUmVjpzgUT28B2lWpTO+IxiBcfibAN/1Sg20NebGTO/+serz2CnSZf95N2a1OZ6eXypGQ==", - "dependencies": { - "@noble/ed25519": "^2.0.0", - "@noble/secp256k1": "^2.0.0", - "canonicalize": "^2.0.0", - "multiformats": "^12.0.1", - "multihashes": "^4.0.3", - "uri-js": "^4.4.1" - } - }, - "node_modules/@decentralized-identity/ion-sdk/node_modules/multiformats": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", - "integrity": "sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", - "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", - "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", - "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", - "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", - "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", - "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", - "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", - "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", - "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", - "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", - "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", - "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", - "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", - "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", - "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", - "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", - "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", - "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", - "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", - "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", - "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", - "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", - "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@hono/node-server": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.4.0.tgz", - "integrity": "sha512-bhDkhldW7w9VgjrX0gG1vJ2YyvTxFWd5WG9nHjSR4UauhVECQZC3qy7mVVuQ054I5NWhKttHfKzYfoPzmUzAjw==", - "engines": { - "node": ">=18.14.1" - } - }, - "node_modules/@hono/zod-validator": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@hono/zod-validator/-/zod-validator-0.1.11.tgz", - "integrity": "sha512-PQXeHUP0+36qpRt8yfeD7N2jbK3ETlGvSN6dMof/HwUC/APRokQRjpXZm4rrlG71Ft0aWE01+Bm4XejqPie5Uw==", - "peerDependencies": { - "hono": ">=3.9.0", - "zod": "^3.19.1" - } - }, - "node_modules/@ipld/dag-cbor": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-9.0.3.tgz", - "integrity": "sha512-A2UFccS0+sARK9xwXiVZIaWbLbPxLGP3UZOjBeOMWfDY04SXi8h1+t4rHBzOlKYF/yWNm3RbFLyclWO7hZcy4g==", - "dependencies": { - "cborg": "^2.0.1", - "multiformats": "^12.0.1" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@ipld/dag-cbor/node_modules/multiformats": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", - "integrity": "sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@ipld/dag-pb": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.0.7.tgz", - "integrity": "sha512-EqJtSAcELiYbp9K0Y5ckbg+W0pD5cSy5PnE/QsCrpKvoq+u0E8Vi07chNGDLaShd5AjDq0AMtnuudKUUuEuSjg==", - "dependencies": { - "multiformats": "^13.0.0" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@ipld/dag-pb/node_modules/multiformats": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.0.0.tgz", - "integrity": "sha512-xiIB0p7EKmETm3wyKedOg/xuyQ18PoWwXCzzgpZAiDxL9ktl3XTh8AqoDT5kAqRg+DU48XAGPsUJL2Rn6Bx3Lw==" - }, - "node_modules/@js-temporal/polyfill": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@js-temporal/polyfill/-/polyfill-0.4.4.tgz", - "integrity": "sha512-2X6bvghJ/JAoZO52lbgyAPFj8uCflhTo2g7nkFzEQdXd/D8rEeD4HtmTEpmtGCva260fcd66YNXBOYdnmHqSOg==", - "dependencies": { - "jsbi": "^4.3.0", - "tslib": "^2.4.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" - }, - "node_modules/@multiformats/base-x": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" - }, - "node_modules/@multiformats/murmur3": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.8.tgz", - "integrity": "sha512-6vId1C46ra3R1sbJUOFCZnsUIveR9oF20yhPmAFxPm0JfrX3/ZRCgP3YDrBzlGoEppOXnA9czHeYc0T9mB6hbA==", - "dependencies": { - "multiformats": "^13.0.0", - "murmurhash3js-revisited": "^3.0.0" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@multiformats/murmur3/node_modules/multiformats": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.0.0.tgz", - "integrity": "sha512-xiIB0p7EKmETm3wyKedOg/xuyQ18PoWwXCzzgpZAiDxL9ktl3XTh8AqoDT5kAqRg+DU48XAGPsUJL2Rn6Bx3Lw==" - }, - "node_modules/@noble/ciphers": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.1.4.tgz", - "integrity": "sha512-d3ZR8vGSpy3v/nllS+bD/OMN5UZqusWiQqkyj7AwzTnhXFH72pF5oB4Ach6DQ50g5kXxC28LdaYBEpsyv9KOUQ==", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/curves": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", - "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", - "dependencies": { - "@noble/hashes": "1.3.1" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/ed25519": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-2.0.0.tgz", - "integrity": "sha512-/extjhkwFupyopDrt80OMWKdLgP429qLZj+z6sYJz90rF2Iz0gjZh2ArMKPImUl13Kx+0EXI2hN9T/KJV0/Zng==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@noble/hashes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", - "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/secp256k1": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.0.0.tgz", - "integrity": "sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@tbd54566975/dwn-sdk-js": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@tbd54566975/dwn-sdk-js/-/dwn-sdk-js-0.2.8.tgz", - "integrity": "sha512-oiKk+ekAQO94bUkt6yk+xkDY8uCGmNC+rKaYQLhAoTrhYrczeRSuDT04F5/vPBT5K6NfAoRcQsIyBmvgRCUvgA==", - "dependencies": { - "@ipld/dag-cbor": "9.0.3", - "@js-temporal/polyfill": "0.4.4", - "@noble/ed25519": "2.0.0", - "@noble/secp256k1": "2.0.0", - "abstract-level": "1.0.3", - "ajv": "8.12.0", - "blockstore-core": "4.2.0", - "cross-fetch": "4.0.0", - "eciesjs": "0.4.5", - "flat": "5.0.2", - "interface-blockstore": "5.2.3", - "interface-store": "5.1.2", - "ipfs-unixfs-exporter": "13.1.5", - "ipfs-unixfs-importer": "15.1.5", - "level": "8.0.0", - "lodash": "4.17.21", - "lru-cache": "9.1.2", - "ms": "2.1.3", - "multiformats": "11.0.2", - "randombytes": "2.1.0", - "readable-stream": "4.4.2", - "ulidx": "2.1.0", - "uuid": "8.3.2", - "varint": "6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@web5/agent": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@web5/agent/-/agent-0.2.5.tgz", - "integrity": "sha512-Z9JY/43Yrg0xKK26y/iZFdHNtVf/k9XLxw8mXP5zfYidrqfAgVR0i4LKA7qZKfUSxC7/uaD/STYYIKpNByd/cw==", - "dependencies": { - "@tbd54566975/dwn-sdk-js": "0.2.8", - "@web5/common": "0.2.2", - "@web5/crypto": "0.2.2", - "@web5/dids": "0.2.3", - "level": "8.0.0", - "readable-stream": "4.4.2", - "readable-web-to-node-stream": "3.0.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web5/api": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@web5/api/-/api-0.8.3.tgz", - "integrity": "sha512-YXQ++ZShtd5LeFRqEMGlhVqJ7Zg5P6bMequpaLl068bCGjtjCwiFFgDtM1KeL36IAzQ4pFLFyj9aTGZ/JgCXHA==", - "dependencies": { - "@tbd54566975/dwn-sdk-js": "0.2.8", - "@web5/agent": "0.2.5", - "@web5/common": "0.2.2", - "@web5/crypto": "0.2.2", - "@web5/dids": "0.2.3", - "@web5/user-agent": "0.2.5", - "level": "8.0.0", - "ms": "2.1.3", - "readable-stream": "4.4.2", - "readable-web-to-node-stream": "3.0.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web5/common": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@web5/common/-/common-0.2.2.tgz", - "integrity": "sha512-dRn6SmALExeTLMTK/W5ozGarfaddK+Lraf5OjuIGLAaLfcX1RWx3oDMoY5Hr9LjfxHJC8mGXB8DnKflbeYJRgA==", - "dependencies": { - "level": "8.0.0", - "multiformats": "11.0.2", - "readable-stream": "4.4.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web5/crypto": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@web5/crypto/-/crypto-0.2.2.tgz", - "integrity": "sha512-vHFg0wXQSQXrwuBNQyDHnmSZchfTfO6/Sv+7rDsNkvofs+6lGTE8CZ02cwUYMeIwTRMLer12c+fMfzYrXokEUQ==", - "dependencies": { - "@noble/ciphers": "0.1.4", - "@noble/curves": "1.1.0", - "@noble/hashes": "1.3.1", - "@web5/common": "0.2.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web5/crypto/node_modules/@web5/common": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@web5/common/-/common-0.2.1.tgz", - "integrity": "sha512-Tt5P17HgQCx+Epw0IHnhRKqp5UU3E4xtsE8PkdghOBnvntBB0op5P6efvR1WqmJft5+VunDHt3yZAZstuqQkNg==", - "dependencies": { - "level": "8.0.0", - "multiformats": "11.0.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web5/dids": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@web5/dids/-/dids-0.2.3.tgz", - "integrity": "sha512-Y3PHOavNkSyjBxZQEpKE6XueaqemBO5w0UMOnFh4xH6+5B43ENEE4LHIqVyn2bCpfEBGLXENgDZYqyJphBu0pA==", - "dependencies": { - "@decentralized-identity/ion-pow-sdk": "1.0.17", - "@decentralized-identity/ion-sdk": "1.0.1", - "@web5/common": "0.2.2", - "@web5/crypto": "0.2.2", - "did-resolver": "4.1.0", - "dns-packet": "5.6.1", - "level": "8.0.0", - "ms": "2.1.3", - "pkarr": "1.1.1", - "z32": "1.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web5/user-agent": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@web5/user-agent/-/user-agent-0.2.5.tgz", - "integrity": "sha512-qv5M698C5HSvq30xUgLWtcsbZppjfOH5qZthpTRx4ItL5UWA/eQ9DsQiQeb4vet3uIUy3NHRDIQezclOdwYErw==", - "dependencies": { - "@web5/agent": "0.2.5", - "@web5/common": "0.2.2", - "@web5/crypto": "0.2.2", - "@web5/dids": "0.2.3" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", - "dependencies": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" - }, - "node_modules/base64-arraybuffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", - "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bencode": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bencode/-/bencode-3.1.1.tgz", - "integrity": "sha512-btsxX9201yoWh45TdqYg6+OZ5O1xTYKTYSGvJndICDFtznE/9zXgow8yjMvvhOqKKuzuL7h+iiCMpfkG8+QuBA==", - "dependencies": { - "uint8-util": "^2.1.6" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/bittorrent-dht": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-11.0.5.tgz", - "integrity": "sha512-R09D6uNaziRqsc+B/j5QzkjceTak+wH9vcNLnkmt8A52EWF9lQwBP0vvCKgSA3AJOYYl+41n3osA2KYYn/z5uQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "bencode": "^4.0.0", - "debug": "^4.3.4", - "k-bucket": "^5.1.0", - "k-rpc": "^5.1.0", - "last-one-wins": "^1.0.4", - "lru": "^3.1.0", - "randombytes": "^2.1.0", - "record-cache": "^1.2.0" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/bittorrent-dht/node_modules/bencode": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/bencode/-/bencode-4.0.0.tgz", - "integrity": "sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==", - "dependencies": { - "uint8-util": "^2.2.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/blake2b": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.4.tgz", - "integrity": "sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==", - "dependencies": { - "blake2b-wasm": "^2.4.0", - "nanoassert": "^2.0.0" - } - }, - "node_modules/blake2b-wasm": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", - "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", - "dependencies": { - "b4a": "^1.0.1", - "nanoassert": "^2.0.0" - } - }, - "node_modules/blockstore-core": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/blockstore-core/-/blockstore-core-4.2.0.tgz", - "integrity": "sha512-F8BCobc75D+9/+hUD+5cixbU6zmZA+lBgNiuBkNlJqRgmAaBBvLOQF6Ad9Jei0Nvmy2a1jaF4CiN76W1apIghA==", - "dependencies": { - "err-code": "^3.0.1", - "interface-blockstore": "^5.0.0", - "interface-store": "^5.0.0", - "multiformats": "^11.0.2" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/canonicalize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.0.0.tgz", - "integrity": "sha512-ulDEYPv7asdKvqahuAY35c1selLdzDwHqugK92hfkzvlDCwXRRelDkR+Er33md/PtnpqHemgkuDPanZ4fiYZ8w==" - }, - "node_modules/catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cborg": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cborg/-/cborg-2.0.5.tgz", - "integrity": "sha512-xVW1rSIw1ZXbkwl2XhJ7o/jAv0vnVoQv/QlfQxV8a7V5PlA4UU/AcIiXqmpyybwNWy/GPQU1m/aBVNIWr7/T0w==", - "bin": { - "cborg": "cli.js" - } - }, - "node_modules/chacha20-universal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chacha20-universal/-/chacha20-universal-1.0.4.tgz", - "integrity": "sha512-/IOxdWWNa7nRabfe7+oF+jVkGjlr2xUL4J8l/OvzZhj+c9RpMqoo3Dq+5nU1j/BflRV4BKnaQ4+4oH1yBpQG1Q==", - "dependencies": { - "nanoassert": "^2.0.0" - } - }, - "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chrome-dgram": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/chrome-dgram/-/chrome-dgram-3.0.6.tgz", - "integrity": "sha512-bqBsUuaOiXiqxXt/zA/jukNJJ4oaOtc7ciwqJpZVEaaXwwxqgI2/ZdG02vXYWUhHGziDlvGMQWk0qObgJwVYKA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "inherits": "^2.0.4", - "run-series": "^1.1.9" - } - }, - "node_modules/chrome-dns": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chrome-dns/-/chrome-dns-1.0.1.tgz", - "integrity": "sha512-HqsYJgIc8ljJJOqOzLphjAs79EUuWSX3nzZi2LNkzlw3GIzAeZbaSektC8iT/tKvLqZq8yl1GJu5o6doA4TRbg==", - "dependencies": { - "chrome-net": "^3.3.2" - } - }, - "node_modules/chrome-net": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/chrome-net/-/chrome-net-3.3.4.tgz", - "integrity": "sha512-Jzy2EnzmE+ligqIZUsmWnck9RBXLuUy6CaKyuNMtowFG3ZvLt8d+WBJCTPEludV0DHpIKjAOlwjFmTaEdfdWCw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "inherits": "^2.0.1" - } - }, - "node_modules/classic-level": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", - "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", - "hasInstallScript": true, - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "^2.2.2", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/did-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/did-resolver/-/did-resolver-4.1.0.tgz", - "integrity": "sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==" - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eciesjs": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.5.tgz", - "integrity": "sha512-2zSRIygO48LpdS95Rwt9ryIkJNO37IdbkjRsnYyAn7gx7e4WPBNimnk6jGNdx2QQYr/VJRPnSVdwQpO5bycYZw==", - "dependencies": { - "@noble/ciphers": "^0.3.0", - "@noble/curves": "^1.2.0", - "@noble/hashes": "^1.3.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/eciesjs/node_modules/@noble/ciphers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.3.0.tgz", - "integrity": "sha512-ldbrnOjmNRwFdXcTM6uXDcxpMIFrbzAWNnpBPp4oTJTFF0XByGD6vf45WrehZGXRQTRVV+Zm8YP+EgEf+e4cWA==", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/eciesjs/node_modules/@noble/curves": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", - "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", - "dependencies": { - "@noble/hashes": "1.3.3" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/eciesjs/node_modules/@noble/hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", - "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/err-code": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", - "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" - }, - "node_modules/esbuild": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", - "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.11", - "@esbuild/android-arm": "0.19.11", - "@esbuild/android-arm64": "0.19.11", - "@esbuild/android-x64": "0.19.11", - "@esbuild/darwin-arm64": "0.19.11", - "@esbuild/darwin-x64": "0.19.11", - "@esbuild/freebsd-arm64": "0.19.11", - "@esbuild/freebsd-x64": "0.19.11", - "@esbuild/linux-arm": "0.19.11", - "@esbuild/linux-arm64": "0.19.11", - "@esbuild/linux-ia32": "0.19.11", - "@esbuild/linux-loong64": "0.19.11", - "@esbuild/linux-mips64el": "0.19.11", - "@esbuild/linux-ppc64": "0.19.11", - "@esbuild/linux-riscv64": "0.19.11", - "@esbuild/linux-s390x": "0.19.11", - "@esbuild/linux-x64": "0.19.11", - "@esbuild/netbsd-x64": "0.19.11", - "@esbuild/openbsd-x64": "0.19.11", - "@esbuild/sunos-x64": "0.19.11", - "@esbuild/win32-arm64": "0.19.11", - "@esbuild/win32-ia32": "0.19.11", - "@esbuild/win32-x64": "0.19.11" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/graceful-goodbye": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/graceful-goodbye/-/graceful-goodbye-1.3.0.tgz", - "integrity": "sha512-hcZOs20emYlTM7MmUE0FpuZcjlk2GPsR+UYTHDeWxtGjXcbh2CawGi8vlzqsIvspqAbot7mRv3sC/uhgtKc4hQ==", - "dependencies": { - "safety-catch": "^1.0.2" - } - }, - "node_modules/hamt-sharding": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.2.tgz", - "integrity": "sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw==", - "dependencies": { - "sparse-array": "^1.3.1", - "uint8arrays": "^4.0.2" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/hash-wasm": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.9.0.tgz", - "integrity": "sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==" - }, - "node_modules/hono": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/hono/-/hono-3.12.0.tgz", - "integrity": "sha512-UPEtZuLY7Wo7g0mqKWSOjLFdT8t7wJ60IYEcxKl3AQNU4u+R2QqU2fJMPmSu24C+/ag20Z8mOTQOErZzK4DMvA==", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/interface-blockstore": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-5.2.3.tgz", - "integrity": "sha512-15cN+ZFdcVXdXo6I/SrSzFDsuJyDTyEI52XuvXQlR/G5fe3cK8p0tvVjfu5diRQH1XqNgmJEdMPixyt0xgjtvQ==", - "dependencies": { - "interface-store": "^5.0.0", - "multiformats": "^11.0.2" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/interface-store": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-5.1.2.tgz", - "integrity": "sha512-q2sLoqC+UdaWnjwGyghsH0jwqqVk226lsG207e3QwPB8sAZYmYIWUnJwJH3JjFNNRV9e6CUTmm+gDO0Xg4KRiw==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/ipfs-unixfs": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.1.2.tgz", - "integrity": "sha512-HVjrACOhU8RgMskcrfydk+FDAE9pFKr8tneKLaVYQ2f81HUKXoiSdgsAJY/jt7Ieyj4tE12TZGduIeWtNpScOw==", - "dependencies": { - "err-code": "^3.0.1", - "protons-runtime": "^5.0.0", - "uint8arraylist": "^2.4.3" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/ipfs-unixfs-exporter": { - "version": "13.1.5", - "resolved": "https://registry.npmjs.org/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-13.1.5.tgz", - "integrity": "sha512-O5aMawsHoe4DaYk5FFil2EPrNOaU3pkHC6qUR5JMnW7es93W3b/RjJoO7AyDL1rpb+M3K0oRu86Yc5wLNQQ8jg==", - "dependencies": { - "@ipld/dag-cbor": "^9.0.0", - "@ipld/dag-pb": "^4.0.0", - "@multiformats/murmur3": "^2.0.0", - "err-code": "^3.0.1", - "hamt-sharding": "^3.0.0", - "interface-blockstore": "^5.0.0", - "ipfs-unixfs": "^11.0.0", - "it-filter": "^3.0.2", - "it-last": "^3.0.2", - "it-map": "^3.0.3", - "it-parallel": "^3.0.0", - "it-pipe": "^3.0.1", - "it-pushable": "^3.1.0", - "multiformats": "^11.0.0", - "p-queue": "^7.3.0", - "progress-events": "^1.0.0", - "uint8arrays": "^4.0.2" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/ipfs-unixfs-importer": { - "version": "15.1.5", - "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-15.1.5.tgz", - "integrity": "sha512-TXaOI0M5KNpq2+qLw8AIYd0Lnc0gWTKCBqUd9eErBUwaP3Fna4qauF+JX9Rj2UrwaOvG/1xbF8Vm+92eOcKWMA==", - "dependencies": { - "@ipld/dag-pb": "^4.0.0", - "@multiformats/murmur3": "^2.0.0", - "err-code": "^3.0.1", - "hamt-sharding": "^3.0.0", - "interface-blockstore": "^5.0.0", - "interface-store": "^5.0.1", - "ipfs-unixfs": "^11.0.0", - "it-all": "^3.0.2", - "it-batch": "^3.0.2", - "it-first": "^3.0.2", - "it-parallel-batch": "^3.0.1", - "multiformats": "^11.0.0", - "progress-events": "^1.0.0", - "rabin-wasm": "^0.1.4", - "uint8arraylist": "^2.4.3", - "uint8arrays": "^4.0.2" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/it-all": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/it-all/-/it-all-3.0.4.tgz", - "integrity": "sha512-UMiy0i9DqCHBdWvMbzdYvVGa5/w4t1cc4nchpbnjdLhklglv8mQeEYnii0gvKESJuL1zV32Cqdb33R6/GPfxpQ==" - }, - "node_modules/it-batch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-3.0.4.tgz", - "integrity": "sha512-WRu2mqOYIs+T9k7+yxSK9VJdk0UE4R0jKQsWQcti5c6vhb1FhjC2+yCB5XBrctQ9edNfCMU/wVzdDj8qSwimbA==" - }, - "node_modules/it-filter": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/it-filter/-/it-filter-3.0.4.tgz", - "integrity": "sha512-e0sz+st4sudK/zH6GZ/gRTRP8A/ADuJFCYDmRgMbZvR79y5+v4ZXav850bBZk5wL9zXaYZFxS1v/6Qi+Vjwh5g==", - "dependencies": { - "it-peekable": "^3.0.0" - } - }, - "node_modules/it-first": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/it-first/-/it-first-3.0.4.tgz", - "integrity": "sha512-FtQl84iTNxN5EItP/JgL28V2rzNMkCzTUlNoj41eVdfix2z1DBuLnBqZ0hzYhGGa1rMpbQf0M7CQSA2adlrLJg==" - }, - "node_modules/it-last": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/it-last/-/it-last-3.0.4.tgz", - "integrity": "sha512-Ns+KTsQWhs0KCvfv5X3Ck3lpoYxHcp4zUp4d+AOdmC8cXXqDuoZqAjfWhgCbxJubXyIYWdfE2nRcfWqgvZHP8Q==" - }, - "node_modules/it-map": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/it-map/-/it-map-3.0.5.tgz", - "integrity": "sha512-hB0TDXo/h4KSJJDSRLgAPmDroiXP6Fx1ck4Bzl3US9hHfZweTKsuiP0y4gXuTMcJlS6vj0bb+f70rhkD47ZA3w==", - "dependencies": { - "it-peekable": "^3.0.0" - } - }, - "node_modules/it-merge": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/it-merge/-/it-merge-3.0.3.tgz", - "integrity": "sha512-FYVU15KC5pb/GQX1Ims+lee8d4pdqGVCpWr0lkNj8o4xuNo7jY71k6GuEiWdP+T7W1bJqewSxX5yoTy5yZpRVA==", - "dependencies": { - "it-pushable": "^3.2.0" - } - }, - "node_modules/it-parallel": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/it-parallel/-/it-parallel-3.0.6.tgz", - "integrity": "sha512-i7UM7I9LTkDJw3YIqXHFAPZX6CWYzGc+X3irdNrVExI4vPazrJdI7t5OqrSVN8CONXLAunCiqaSV/zZRbQR56A==", - "dependencies": { - "p-defer": "^4.0.0" - } - }, - "node_modules/it-parallel-batch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-3.0.4.tgz", - "integrity": "sha512-O1omh8ss8+UtXiMjE+8kM5C20DT0Ma4VtKVfrSHOJU0UHZ+iWBXarabzPYEp+WiuQmrv+klDPPlTZ9KaLN9xOA==", - "dependencies": { - "it-batch": "^3.0.0" - } - }, - "node_modules/it-peekable": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/it-peekable/-/it-peekable-3.0.3.tgz", - "integrity": "sha512-Wx21JX/rMzTEl9flx3DGHuPV1KQFGOl8uoKfQtmZHgPQtGb89eQ6RyVd82h3HuP9Ghpt0WgBDlmmdWeHXqyx7w==" - }, - "node_modules/it-pipe": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/it-pipe/-/it-pipe-3.0.1.tgz", - "integrity": "sha512-sIoNrQl1qSRg2seYSBH/3QxWhJFn9PKYvOf/bHdtCBF0bnghey44VyASsWzn5dAx0DCDDABq1hZIuzKmtBZmKA==", - "dependencies": { - "it-merge": "^3.0.0", - "it-pushable": "^3.1.2", - "it-stream-types": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/it-pushable": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/it-pushable/-/it-pushable-3.2.3.tgz", - "integrity": "sha512-gzYnXYK8Y5t5b/BnJUr7glfQLO4U5vyb05gPx/TyTw+4Bv1zM9gFk4YsOrnulWefMewlphCjKkakFvj1y99Tcg==", - "dependencies": { - "p-defer": "^4.0.0" - } - }, - "node_modules/it-stream-types": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-stream-types/-/it-stream-types-2.0.1.tgz", - "integrity": "sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/jsbi": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-4.3.0.tgz", - "integrity": "sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g==" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/k-bucket": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/k-bucket/-/k-bucket-5.1.0.tgz", - "integrity": "sha512-Fac7iINEovXIWU20GPnOMLUbjctiS+cnmyjC4zAUgvs3XPf1vo9akfCHkigftSic/jiKqKl+KA3a/vFcJbHyCg==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/k-rpc": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/k-rpc/-/k-rpc-5.1.0.tgz", - "integrity": "sha512-FGc+n70Hcjoa/X2JTwP+jMIOpBz+pkRffHnSl9yrYiwUxg3FIgD50+u1ePfJUOnRCnx6pbjmVk5aAeB1wIijuQ==", - "dependencies": { - "k-bucket": "^5.0.0", - "k-rpc-socket": "^1.7.2", - "randombytes": "^2.0.5" - } - }, - "node_modules/k-rpc-socket": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/k-rpc-socket/-/k-rpc-socket-1.11.1.tgz", - "integrity": "sha512-8xtA8oqbZ6v1Niryp2/g4GxW16EQh5MvrUylQoOG+zcrDff5CKttON2XUXvMwlIHq4/2zfPVFiinAccJ+WhxoA==", - "dependencies": { - "bencode": "^2.0.0", - "chrome-dgram": "^3.0.2", - "chrome-dns": "^1.0.0", - "chrome-net": "^3.3.2" - } - }, - "node_modules/k-rpc-socket/node_modules/bencode": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz", - "integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==" - }, - "node_modules/last-one-wins": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/last-one-wins/-/last-one-wins-1.0.4.tgz", - "integrity": "sha512-t+KLJFkHPQk8lfN6WBOiGkiUXoub+gnb2XTYI2P3aiISL+94xgZ1vgz1SXN/N4hthuOoLXarXfBZPUruyjQtfA==" - }, - "node_modules/layerr": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/layerr/-/layerr-2.0.1.tgz", - "integrity": "sha512-z0730CwG/JO24evdORnyDkwG1Q7b7mF2Tp1qRQ0YvrMMARbt1DFG694SOv439Gm7hYKolyZyaB49YIrYIfZBdg==" - }, - "node_modules/level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dependencies": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/level" - } - }, - "node_modules/level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dependencies": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lru": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lru/-/lru-3.1.0.tgz", - "integrity": "sha512-5OUtoiVIGU4VXBOshidmtOsvBIvcQR6FD/RzWSvaeHyxCGB+PCUCu+52lqMfdc0h/2CLvHhZS4TwUmMQrrMbBQ==", - "dependencies": { - "inherits": "^2.0.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/lru-cache": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", - "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/module-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", - "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/multibase": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-4.0.6.tgz", - "integrity": "sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==", - "deprecated": "This module has been superseded by the multiformats module", - "dependencies": { - "@multiformats/base-x": "^4.0.1" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=6.0.0" - } - }, - "node_modules/multiformats": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz", - "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/multihashes": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-4.0.3.tgz", - "integrity": "sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA==", - "dependencies": { - "multibase": "^4.0.1", - "uint8arrays": "^3.0.0", - "varint": "^5.0.2" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=6.0.0" - } - }, - "node_modules/multihashes/node_modules/multiformats": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" - }, - "node_modules/multihashes/node_modules/uint8arrays": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz", - "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==", - "dependencies": { - "multiformats": "^9.4.2" - } - }, - "node_modules/multihashes/node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" - }, - "node_modules/murmurhash3js-revisited": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz", - "integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/nanoassert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", - "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==" - }, - "node_modules/napi-macros": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", - "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-gyp-build": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz", - "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/p-defer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.0.tgz", - "integrity": "sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-queue": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.4.1.tgz", - "integrity": "sha512-vRpMXmIkYF2/1hLBKisKeVYJZ8S2tZ0zEAmIJgdVKP2nq0nh4qCdf8bgw+ZgKrkh71AOCaqzwbJJk1WtdcF3VA==", - "dependencies": { - "eventemitter3": "^5.0.1", - "p-timeout": "^5.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-timeout": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkarr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pkarr/-/pkarr-1.1.1.tgz", - "integrity": "sha512-X27LKqf83X3WuJd2Z9qdfVxkmfOu6HUbY0pm11LqeBbFmgmZRPgOxJG8bKiIsmmD6Vjc25j45KHYflF2lfodyQ==", - "dependencies": { - "bencode": "^3.0.3", - "bittorrent-dht": "^11.0.4", - "chalk": "^5.2.0", - "dns-packet": "^5.6.1", - "graceful-goodbye": "^1.3.0", - "sodium-universal": "^4.0.0", - "z32": "^1.0.0" - }, - "bin": { - "pkarr": "bin.js" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/progress-events": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.0.tgz", - "integrity": "sha512-zIB6QDrSbPfRg+33FZalluFIowkbV5Xh1xSuetjG+rlC5he6u2dc6VQJ0TbMdlN3R1RHdpOqxEFMKTnQ+itUwA==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/protons-runtime": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-5.2.1.tgz", - "integrity": "sha512-Rt4ORm1WR62ysrXX5sCV32a5jPwVoIpU90XUzrdAfMIOSNTizvqlx/7wedNpogvZjUUY/gLJp3VftpA+ebx/og==", - "dependencies": { - "uint8arraylist": "^2.4.3", - "uint8arrays": "^5.0.1" - } - }, - "node_modules/protons-runtime/node_modules/multiformats": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.0.0.tgz", - "integrity": "sha512-xiIB0p7EKmETm3wyKedOg/xuyQ18PoWwXCzzgpZAiDxL9ktl3XTh8AqoDT5kAqRg+DU48XAGPsUJL2Rn6Bx3Lw==" - }, - "node_modules/protons-runtime/node_modules/uint8arrays": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.0.1.tgz", - "integrity": "sha512-ND5RpJAnPgHmZT7hWD/2T4BwRp04j8NLKvMKC/7bhiEwEjUMkQ4kvBKiH6hOqbljd6qJ2xS8reL3vl1e33grOQ==", - "dependencies": { - "multiformats": "^13.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/rabin-wasm": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/rabin-wasm/-/rabin-wasm-0.1.5.tgz", - "integrity": "sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA==", - "dependencies": { - "@assemblyscript/loader": "^0.9.4", - "bl": "^5.0.0", - "debug": "^4.3.1", - "minimist": "^1.2.5", - "node-fetch": "^2.6.1", - "readable-stream": "^3.6.0" - }, - "bin": { - "rabin-wasm": "cli/bin.js" - } - }, - "node_modules/rabin-wasm/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "dependencies": { - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/record-cache": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/record-cache/-/record-cache-1.2.0.tgz", - "integrity": "sha512-kyy3HWCez2WrotaL3O4fTn0rsIdfRKOdQQcEJ9KpvmKmbffKVvwsloX063EgRUlpJIXHiDQFhJcTbZequ2uTZw==", - "dependencies": { - "b4a": "^1.3.1" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-series": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", - "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safety-catch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/safety-catch/-/safety-catch-1.0.2.tgz", - "integrity": "sha512-C1UYVZ4dtbBxEtvOcpjBaaD27nP8MlvyAQEp2fOTOEe6pfUpk1cDUxij6BR1jZup6rSyUTaBBplK7LanskrULA==" - }, - "node_modules/sha256-universal": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sha256-universal/-/sha256-universal-1.2.1.tgz", - "integrity": "sha512-ghn3muhdn1ailCQqqceNxRgkOeZSVfSE13RQWEg6njB+itsFzGVSJv+O//2hvNXZuxVIRyNzrgsZ37SPDdGJJw==", - "dependencies": { - "b4a": "^1.0.1", - "sha256-wasm": "^2.2.1" - } - }, - "node_modules/sha256-wasm": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/sha256-wasm/-/sha256-wasm-2.2.2.tgz", - "integrity": "sha512-qKSGARvao+JQlFiA+sjJZhJ/61gmW/3aNLblB2rsgIxDlDxsJPHo8a1seXj12oKtuHVgJSJJ7QEGBUYQN741lQ==", - "dependencies": { - "b4a": "^1.0.1", - "nanoassert": "^2.0.0" - } - }, - "node_modules/sha512-universal": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sha512-universal/-/sha512-universal-1.2.1.tgz", - "integrity": "sha512-kehYuigMoRkIngCv7rhgruLJNNHDnitGTBdkcYbCbooL8Cidj/bS78MDxByIjcc69M915WxcQTgZetZ1JbeQTQ==", - "dependencies": { - "b4a": "^1.0.1", - "sha512-wasm": "^2.3.1" - } - }, - "node_modules/sha512-wasm": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/sha512-wasm/-/sha512-wasm-2.3.4.tgz", - "integrity": "sha512-akWoxJPGCB3aZCrZ+fm6VIFhJ/p8idBv7AWGFng/CZIrQo51oQNsvDbTSRXWAzIiZJvpy16oIDiCCPqTe21sKg==", - "dependencies": { - "b4a": "^1.0.1", - "nanoassert": "^2.0.0" - } - }, - "node_modules/siphash24": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/siphash24/-/siphash24-1.3.1.tgz", - "integrity": "sha512-moemC3ZKiTzH29nbFo3Iw8fbemWWod4vNs/WgKbQ54oEs6mE6XVlguxvinYjB+UmaE0PThgyED9fUkWvirT8hA==", - "dependencies": { - "nanoassert": "^2.0.0" - } - }, - "node_modules/sodium-javascript": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/sodium-javascript/-/sodium-javascript-0.8.0.tgz", - "integrity": "sha512-rEBzR5mPxPES+UjyMDvKPIXy9ImF17KOJ32nJNi9uIquWpS/nfj+h6m05J5yLJaGXjgM72LmQoUbWZVxh/rmGg==", - "dependencies": { - "blake2b": "^2.1.1", - "chacha20-universal": "^1.0.4", - "nanoassert": "^2.0.0", - "sha256-universal": "^1.1.0", - "sha512-universal": "^1.1.0", - "siphash24": "^1.0.1", - "xsalsa20": "^1.0.0" - } - }, - "node_modules/sodium-native": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.0.4.tgz", - "integrity": "sha512-faqOKw4WQKK7r/ybn6Lqo1F9+L5T6NlBJJYvpxbZPetpWylUVqz449mvlwIBKBqxEHbWakWuOlUt8J3Qpc4sWw==", - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.6.0" - } - }, - "node_modules/sodium-universal": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", - "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", - "dependencies": { - "blake2b": "^2.1.1", - "chacha20-universal": "^1.0.4", - "nanoassert": "^2.0.0", - "sha256-universal": "^1.1.0", - "sha512-universal": "^1.1.0", - "siphash24": "^1.0.1", - "sodium-javascript": "~0.8.0", - "sodium-native": "^4.0.0", - "xsalsa20": "^1.0.0" - } - }, - "node_modules/sparse-array": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/sparse-array/-/sparse-array-1.3.2.tgz", - "integrity": "sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg==" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/true-myth": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/true-myth/-/true-myth-5.4.0.tgz", - "integrity": "sha512-MonJqkJf+VOXZ2msbpvAI1uJWoyfCN7nirR8/fNK+IlFDWYNLb9iqeAc2uhIbAQBynHtM02azZgepQDQclOwAw==", - "engines": { - "node": "12.* || 14.* || 16.* || >= 18.*" - } - }, - "node_modules/tsconfig-paths": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/tsx": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", - "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", - "dev": true, - "dependencies": { - "esbuild": "~0.19.10", - "get-tsconfig": "^4.7.2" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/uint8-util": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/uint8-util/-/uint8-util-2.2.4.tgz", - "integrity": "sha512-uEI5lLozmKQPYEevfEhP9LY3Je5ZmrQhaWXrzTVqrLNQl36xsRh8NiAxYwB9J+2BAt99TRbmCkROQB2ZKhx4UA==", - "dependencies": { - "base64-arraybuffer": "^1.0.2" - } - }, - "node_modules/uint8arraylist": { - "version": "2.4.8", - "resolved": "https://registry.npmjs.org/uint8arraylist/-/uint8arraylist-2.4.8.tgz", - "integrity": "sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ==", - "dependencies": { - "uint8arrays": "^5.0.1" - } - }, - "node_modules/uint8arraylist/node_modules/multiformats": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.0.0.tgz", - "integrity": "sha512-xiIB0p7EKmETm3wyKedOg/xuyQ18PoWwXCzzgpZAiDxL9ktl3XTh8AqoDT5kAqRg+DU48XAGPsUJL2Rn6Bx3Lw==" - }, - "node_modules/uint8arraylist/node_modules/uint8arrays": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.0.1.tgz", - "integrity": "sha512-ND5RpJAnPgHmZT7hWD/2T4BwRp04j8NLKvMKC/7bhiEwEjUMkQ4kvBKiH6hOqbljd6qJ2xS8reL3vl1e33grOQ==", - "dependencies": { - "multiformats": "^13.0.0" - } - }, - "node_modules/uint8arrays": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-4.0.10.tgz", - "integrity": "sha512-AnJNUGGDJAgFw/eWu/Xb9zrVKEGlwJJCaeInlf3BkecE/zcTobk5YXYIPNQJO1q5Hh1QZrQQHf0JvcHqz2hqoA==", - "dependencies": { - "multiformats": "^12.0.1" - } - }, - "node_modules/uint8arrays/node_modules/multiformats": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-12.1.3.tgz", - "integrity": "sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==", - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/ulidx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ulidx/-/ulidx-2.1.0.tgz", - "integrity": "sha512-DlMi97oP9HASI3kLCjBlOhAG1SoisUrEqC2PJ7itiFbq9q5Zo0JejupXeu2Gke99W62epNzA4MFNToNiq8A5LA==", - "dependencies": { - "layerr": "^2.0.1" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/varint": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", - "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/xsalsa20": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/xsalsa20/-/xsalsa20-1.2.0.tgz", - "integrity": "sha512-FIr/DEeoHfj7ftfylnoFt3rAIRoWXpx2AoDfrT2qD2wtp7Dp+COajvs/Icb7uHqRW9m60f5iXZwdsJJO3kvb7w==" - }, - "node_modules/z32": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/z32/-/z32-1.0.1.tgz", - "integrity": "sha512-Uytfqf6VEVchHKZDw0NRdCViOARHP84uzvOw0CXCMLOwhgHZUL9XibpEPLLQN10mCVLxOlGCQWbkV7km7yNYcw==", - "dependencies": { - "b4a": "^1.5.3" - } - }, - "node_modules/zod": { - "version": "3.22.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", - "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/server/package.json b/server/package.json deleted file mode 100644 index ce20a8d..0000000 --- a/server/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "scripts": { - "dev": "tsx --watch server.ts" - }, - "dependencies": { - "@hono/node-server": "^1.4.0", - "@hono/zod-validator": "^0.1.11", - "@web5/api": "^0.8.3", - "hono": "^3.12.0", - "true-myth": "5", - "tsconfig-paths": "^4.2.0", - "zod": "^3.22.4" - }, - "devDependencies": { - "tsx": "^4.7.0", - "typescript": "^5.3.3" - } -} diff --git a/server/script.ts b/server/script.ts deleted file mode 100644 index e58a7e5..0000000 --- a/server/script.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Web5 } from "@web5/api"; -import { protocols } from "@frontend/utils/protocols"; -import DocumentUtils from "@frontend/utils/document"; -import { Agent } from "@backend/utils"; - -async function configureProtocols(agent: Agent) { - console.log("=== CONFIGURE PROTOCOL ===") - - for (const protocol of protocols) { - const { protocols } = await agent.web5.dwn.protocols.query({ - message: { - filter: { - protocol: protocol.protocol, - } - } - }) - - if (protocols.length > 0) { - console.log("Protocol already exists:", protocol.protocol) - continue - } - - const { protocol: configuredProtocol, status: localProtocolConfigurationStatus } = await agent.web5.dwn.protocols.configure({ - message: { - definition: Object.assign({ ...protocol }), - } - }); - - if (!configuredProtocol) { - console.log("Failed to configure protocol:", localProtocolConfigurationStatus) - return - } - - console.log("Configured protocol on local DWN:", protocol.protocol) - const { status: remoteProtocolConfigurationStatus } = await configuredProtocol.send(agent.did) - - console.log("Sent protocol to remote DWN") - console.log(protocol.protocol, remoteProtocolConfigurationStatus) - } - - console.log("=== END CONFIGURE PROTOCOL ===") -} - -async function queryConditions(agent: Agent) { - console.log("=== QUERY CONDITIONS ===") - - const records = await DocumentUtils.fetchDocumentRecords(agent) - if (!records) { - console.log("No records found") - return - } - - if (records.length > 0) { - for (const record of records) { - // console.log("author:", record.author) - // console.log("recipient:", record.recipient) - // Bun.write("records/" + record.id + ".json", JSON.stringify(record)) - // console.log(record.author === record.target) - console.log(await record.data.json()) - } - } - - console.log("=== END QUERY CONDITIONS ===") -} - -async function createCondition(agent: Agent) { - console.log("=== CREATE CONDITION ===") - - const record = await DocumentUtils.createDocumentRecord(agent, { name: "test", condition: "command", file: new File([], "", { type: "image/png" }) }) - - if (!record) return false - - console.log("=== END CREATE CONDITION ===") -} - -async function connect() { - console.log("=== CONNECT ===") - const agent = await Web5.connect({ - sync: "5s", - }); - - console.log("=== END CONNECT ===") - - return agent -} -async function main() { - const agent = await connect() - await configureProtocols(agent) - await queryConditions(agent) - // await createCondition(agent) - // await queryConditions(agent) -} - -main() diff --git a/server/server.ts b/server/server.ts deleted file mode 100644 index f321b00..0000000 --- a/server/server.ts +++ /dev/null @@ -1,9 +0,0 @@ -import app from "./src/app"; -import { serve } from '@hono/node-server' - -serve({ - fetch: app.fetch, - port: process.env.PORT || 5000, -}, (addr) => { - console.log("Server running on port:", addr.port) -}) diff --git a/server/src/app.ts b/server/src/app.ts deleted file mode 100644 index 9344854..0000000 --- a/server/src/app.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Hono } from "hono"; -import { fetchConditions } from "./utils"; -import { agentMiddleware } from "./middleware"; -import { zValidator } from '@hono/zod-validator' -import { z } from 'zod' -import { logger } from "hono/logger" -import { cors } from 'hono/cors' - -const app = new Hono() - .basePath("/api") - .use("*", cors()) - .use("*", logger()) - .get("/conditions", - zValidator( - 'query', - z.object({ - condition: z.string() - })), - agentMiddleware, async (c) => { - const { condition } = c.req.valid("query") - const res = await fetchConditions(c.get("agent")) - if (res.isErr) - return c.json({ error: res.error }) - - // @ts-ignore - const conditions = res.value.filter(record => record.condition === condition) - return c.json(conditions) - }) - -export type App = typeof app - -export default app diff --git a/server/src/middleware.ts b/server/src/middleware.ts deleted file mode 100644 index e6503bc..0000000 --- a/server/src/middleware.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { type Agent, configureProtocol, setupAgent } from "./utils"; -import { MiddlewareHandler } from "hono" - -let agent: Agent - -export const agentMiddleware: MiddlewareHandler<{ - Variables: { - agent: Agent - } -}> = async (c, next) => { - if (!agent) - agent = await setupAgent() - - const connectionResult = await configureProtocol(agent) - if (connectionResult.isErr) { - console.log(connectionResult.error) - process.exit() - } - - c.set('agent', agent) - await next() -} diff --git a/server/src/utils.ts b/server/src/utils.ts deleted file mode 100644 index 4a9c280..0000000 --- a/server/src/utils.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Web5 } from "@web5/api"; -import ConditionsProtocol, { type Record, did as ConditionsProtocolDID } from "@frontend/utils/protocols/conditions" -// @ts-ignore -import Result, { ok, err } from "true-myth/result" - -export type Agent = { - web5: Web5, - did: string -} - -export type Status = { - code: number, - detail: string, -} - -// @ts-ignore -export async function configureProtocol(agent: Agent): Promise> { - const { protocols } = await agent.web5.dwn.protocols.query({ - message: { - filter: { - protocol: ConditionsProtocol.protocol, - } - } - }) - - if (protocols.length > 0) - return ok(undefined) - - const { protocol, status: localProtocolConfigurationStatus } = await agent.web5.dwn.protocols.configure({ - message: { - definition: ConditionsProtocol, - } - }); - - if (!protocol) - return err({ - type: "LOCAL_PROTOCOL_CONFIGURATION_FAILED", - status: localProtocolConfigurationStatus, - }) - - const { status: remoteProtocolConfigurationStatus } = await protocol.send(ConditionsProtocolDID) - - if (remoteProtocolConfigurationStatus.code !== 202) - return err({ - type: "REMOTE_PROTOCOL_CONFIGURATION_FAILED", - status: remoteProtocolConfigurationStatus, - }) - - return ok(undefined) -} - -// @ts-ignore -export async function fetchConditions(agent: Agent): Promise> { - const { records, status } = await agent.web5.dwn.records.query({ - from: ConditionsProtocolDID, - message: { - filter: { - protocolPath: 'condition', - schema: ConditionsProtocol.types.condition.schema, - protocol: ConditionsProtocol.protocol, - }, - // @ts-ignore - dateSort: "createdAscending", - } - }) - - if (!records) { - if (status.code !== 200) - return err(status) - - return ok([]) - } - - const conditions: Record.Condition[] = [] - for (const record of records) { - conditions.push(await record.data.json()) - } - - return ok(conditions) -} - -// @ts-ignore -export async function setupAgent(): Promise { - const { web5, did } = await Web5.connect({ - sync: "5s", - }); - - return { web5, did } -} diff --git a/server/tsconfig.json b/server/tsconfig.json deleted file mode 100644 index 880f229..0000000 --- a/server/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "noEmit": true, - "strict": false, - "noImplicitAny": true, - "noFallthroughCasesInSwitch": true, - "module": "CommonJS", - "target": "ES2020", - "baseUrl": ".", - "paths": { - "@backend/*": ["./src/*"], - "@frontend/*": ["../tauri-app/src/*"] - } - }, - "include": [ - "*.ts", - "./src/**/*.ts" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/tauri-app/package-lock.json b/tauri-app/package-lock.json index e01b1d3..5bfe707 100644 --- a/tauri-app/package-lock.json +++ b/tauri-app/package-lock.json @@ -19,6 +19,7 @@ "axios": "^1.6.3", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", + "date-fns": "^3.1.0", "hono": "^3.12.0", "lodash": "^4.17.21", "lucide-react": "^0.298.0", @@ -27,6 +28,7 @@ "react-dropzone": "^14.2.3", "react-easy-crop": "^5.0.4", "react-hook-form": "^7.49.2", + "react-hot-toast": "^2.4.1", "react-pdf": "^7.6.0", "react-router-dom": "^6.21.1", "react-spinners": "^0.13.8", @@ -44,6 +46,7 @@ "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@types/react-window": "^1.8.8", + "@types/readable-stream": "^4.0.10", "@vitejs/plugin-react": "^4.0.3", "autoprefixer": "^10.4.16", "postcss": "^8.4.32", @@ -2095,6 +2098,22 @@ "@types/react": "*" } }, + "node_modules/@types/readable-stream": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.10.tgz", + "integrity": "sha512-AbUKBjcC8SHmImNi4yK2bbjogQlkFSg7shZCcicxPQapniOlajG8GCc39lvXzCWX4lLRRs7DM3VAeSlqmEVZUA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", @@ -2991,8 +3010,16 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/date-fns": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.1.0.tgz", + "integrity": "sha512-ZO7yefXV/wCWzd3I9haCHmfzlfA3i1a2HHO7ZXjtJrRjXt8FULKJ2Vl8wji3XYF4dQ0ZJ/tokXDZeYlFvgms9Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } }, "node_modules/debug": { "version": "4.3.4", @@ -3458,6 +3485,14 @@ "node": ">=4" } }, + "node_modules/goober": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.13.tgz", + "integrity": "sha512-jFj3BQeleOoy7t93E9rZ2de+ScC4lQICLwiAQmKMg9F6roKGaLSHoCDYKkWlSafg138jejvq/mTdvmnwDQgqoQ==", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, "node_modules/graceful-goodbye": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/graceful-goodbye/-/graceful-goodbye-1.3.0.tgz", @@ -4870,6 +4905,21 @@ "react": "^16.8.0 || ^17 || ^18" } }, + "node_modules/react-hot-toast": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", + "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==", + "dependencies": { + "goober": "^2.1.10" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/tauri-app/src/pages/chat.tsx b/tauri-app/src/pages/chat.tsx new file mode 100644 index 0000000..fbd5444 --- /dev/null +++ b/tauri-app/src/pages/chat.tsx @@ -0,0 +1,278 @@ +import { Web5 } from "@web5/api"; +import { useState, useEffect } from "react"; + +export default function Home() { + + const [web5, setWeb5] = useState(null); + const [myDid, setMyDid] = useState(null); + const [activeRecipient, setActiveRecipient] = useState(null); + + const [noteValue, setNoteValue] = useState(""); + const [errorMessage, setErrorMessage] = useState(''); + const [recipientDid, setRecipientDid] = useState(""); + + const [didCopied, setDidCopied] = useState(false); + const [showNewChatInput, setShowNewChatInput] = useState(false); + + const [allDings, setAllDings] = useState([]); + + const sortedDings = allDings.sort( + //@ts-ignore + (a, b) => new Date(a.timestampWritten) - new Date(b.timestampWritten) + ); + + const groupedDings = allDings.reduce((acc, ding) => { + //@ts-ignore + const recipient = ding.sender === myDid ? ding.recipient : ding.sender; + //@ts-ignore + if (!acc[recipient]) acc[recipient] = []; + //@ts-ignore + acc[recipient].push(ding); + return acc; + }, {}); + + useEffect(() => { + const initWeb5 = async () => { + const { web5, did } = await Web5.connect(); + //@ts-ignore + setWeb5(web5); + //@ts-ignore + setMyDid(did); + + if (web5 && did) { + await configureProtocol(web5, did); + await fetchDings(web5, did); + } + }; + initWeb5(); + }, []); + + useEffect(() => { + if (!web5 || !myDid) return; + const intervalId = setInterval(async () => { + await fetchDings(web5, myDid); + }, 2000); + + return () => clearInterval(intervalId); + }, [web5, myDid]); + + const createProtocolDefinition = () => { + const dingerProtocolDefinition = { + protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", + published: true, + types: { + ding: { + schema: "https://blackgirlbytes.dev/ding", + dataFormats: ["application/json"], + }, + }, + structure: { + ding: { + $actions: [ + { who: "anyone", can: "write" }, + { who: "author", of: "ding", can: "read" }, + { who: "recipient", of: "ding", can: "read" }, + ], + }, + }, + }; + return dingerProtocolDefinition; + }; + + //@ts-ignore + const queryForProtocol = async (web5) => { + return await web5.dwn.protocols.query({ + message: { + filter: { + protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", + }, + }, + }); + }; + + //@ts-ignore + const installProtocolLocally = async (web5, protocolDefinition) => { + return await web5.dwn.protocols.configure({ + message: { + definition: protocolDefinition, + }, + }); + }; + + //@ts-ignore + const configureProtocol = async (web5, did) => { + const protocolDefinition = await createProtocolDefinition(); + + const { protocols: localProtocol, status: localProtocolStatus } = + await queryForProtocol(web5); + console.log({ localProtocol, localProtocolStatus }); + if (localProtocolStatus.code !== 200 || localProtocol.length === 0) { + + const { protocol, status } = await installProtocolLocally(web5, protocolDefinition); + console.log("Protocol installed locally", protocol, status); + + const { status: configureRemoteStatus } = await protocol.send(did); + console.log("Did the protocol install on the remote DWN?", configureRemoteStatus); + } else { + console.log("Protocol already installed"); + } + }; + + + const constructDing = () => { + const currentDate = new Date().toLocaleDateString(); + const currentTime = new Date().toLocaleTimeString(); + const ding = { + sender: myDid, + note: noteValue, + recipient: recipientDid, + timestampWritten: `${currentDate} ${currentTime}`, + }; + return ding; + }; + + //@ts-ignore + const writeToDwn = async (ding) => { + //@ts-ignore + const { record } = await web5.dwn.records.write({ + data: ding, + message: { + protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", + protocolPath: "ding", + schema: "https://blackgirlbytes.dev/ding", + recipient: recipientDid, + }, + }); + return record; + }; + + //@ts-ignore + const sendRecord = async (record) => { + return await record.send(recipientDid); + }; + //@ts-ignore + const handleSubmit = async (e) => { + e.preventDefault(); + + if (!noteValue.trim()) { + setErrorMessage('Please type a message before sending.'); + return; + } + + const ding = constructDing(); + const record = await writeToDwn(ding); + const { status } = await sendRecord(record); + + console.log("Send record status", status); + + await fetchDings(web5, myDid); + setNoteValue(""); + }; + + const handleCopyDid = async () => { + if (myDid) { + try { + await navigator.clipboard.writeText(myDid); + setDidCopied(true); + console.log("DID copied to clipboard"); + + setTimeout(() => { + setDidCopied(false); + }, 3000); + } catch (err) { + console.log("Failed to copy DID: " + err); + } + } + }; + + //@ts-ignore + const fetchSentMessages = async (web5, did) => { + const response = await web5.dwn.records.query({ + message: { + filter: { + protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", + }, + }, + }); + + if (response.status.code === 200) { + const sentDings = await Promise.all( + //@ts-ignore + response.records.map(async (record) => { + const data = await record.data.json(); + return data; + }) + ); + console.log(sentDings, "I sent these dings"); + return sentDings; + } else { + console.log("error", response.status); + } + }; + + //@ts-ignore + const fetchReceivedMessages = async (web5, did) => { + const response = await web5.dwn.records.query({ + from: did, + message: { + filter: { + protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", + schema: "https://blackgirlbytes.dev/ding", + }, + }, + }); + + if (response.status.code === 200) { + const receivedDings = await Promise.all( + //@ts-ignore + response.records.map(async (record) => { + const data = await record.data.json(); + return data; + }) + ); + console.log(receivedDings, "I received these dings"); + return receivedDings; + } else { + console.log("error", response.status); + } + }; + + //@ts-ignore + const fetchDings = async (web5, did) => { + const sentMessages = await fetchSentMessages(web5, did); + const receivedMessages = await fetchReceivedMessages(web5, did); + const allMessages = [...(sentMessages || []), ...(receivedMessages || [])]; + //@ts-ignore + setAllDings(allMessages); + + }; + + const handleStartNewChat = () => { + setActiveRecipient(null); + setShowNewChatInput(true); + }; + + //@ts-ignore + const handleSetActiveRecipient = (recipient) => { + setRecipientDid(recipient); + setActiveRecipient(recipient); + setShowNewChatInput(false); + }; + + const handleConfirmNewChat = () => { + //@ts-ignore + setActiveRecipient(recipientDid); + //@ts-ignore + setActiveRecipient(recipientDid); + setShowNewChatInput(false); + //@ts-ignore + if (!groupedDings[recipientDid]) { + //@ts-ignore + groupedDings[recipientDid] = []; + } + }; + + return ( +
+ ); +} \ No newline at end of file From 9276266508034a74b3b2255a56ffe073ae66d1fe Mon Sep 17 00:00:00 2001 From: koko_codes <58889001+EnebeliEmmanuel@users.noreply.github.com> Date: Sun, 7 Jan 2024 14:02:41 +0100 Subject: [PATCH 084/120] Update README.md --- README.md | 136 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 123 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 5c39ce2..1d306c8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,34 @@ -# PulsePal 🌟 - -Safely store medical records with decentralized identifiers and web nodes, ensuring data security. Connect with similar conditions, share home remedies with a rating system, and access specialized doctors based on your location. PulsePal – where advanced technology meets user-friendly design for your secure, connected health journey. - -## What it does +# Pulsepal-MVP 🌟 + +## Welcome to the Pulsepal MVP repository + +

+ site +

+ +> ## Table of contents +- [Overview](#overview) +- [Core Features Implemented](#core-features-implemented) +- [Technologies](#technologies) +- [Repo Setup](#repo-setup) +- [Requirements](#requirements) +- [Setup the Project](#setup-the-project) +- [Setup the Frontend](#setup-the-frontend) + - [Install Dependencies](#install-dependencies) + - [Steps to host the live site on Vercel](#steps-to-host-the-live-site-on-vercel) +- [Live Link](#live-link) +- [Contributors](#contributors) +- [Contributing to the project](#contributing-to-the-project) +# +> ## Overview +

+Welcome to PulsePal, your health guardian in WEB5. Safely store medical records with decentralized identifiers and web nodes, ensuring data security. Connect with similar conditions, share home remedies with a rating system, and access specialized doctors based on your location. PulsePal – where advanced technology meets user-friendly design for your secure, connected health journey. +

+ + + +# +> ## Core Features Implemented 1. Secure Medical Record Storage: - Users can securely store their medical records using decentralized identifiers (DIDs) in the app. @@ -18,8 +44,43 @@ Safely store medical records with decentralized identifiers and web nodes, ensur 4. Recommend specialized doctors in your nearby areas, based on your current location -## Setting up Local Development + +

+ +# +> ## Technologies +| Stack | Usage | +| :------------------ | :------------------ | +| **`Web5`** | Backend | +| **`React JS + tauri + tailwind`** | Frontend | + +# +> ## Repo Setup + +

+To setup the repo, first fork the Web5-hack Repo, then clone the forked repository to create a copy on the local machine. +

+ + $ git clone https://github.com/coder12git/Web5-Hack.git + +

+Change directory to the cloned repo and set the original Web5-Hack repository as the "upstream" and your forked repository as the "origin" using gitbash. and make sure to switch to dev branch +

+ + $ git remote add upstream https://github.com/coder12git/Web5-Hack.git + +# + +> ## Requirements +# +- [Cors extension](https://chromewebstore.google.com/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf) +- Node JS + +# +> ## Setup the Frontend +- First run the frontend on your local server to ensure it's fully functional before building for production. +# 1. Clone the repository ``` @@ -44,16 +105,65 @@ npm install npm run dev ``` -## What's next for Pulsepal -1. Personalized Health Insights: "Our plan includes integrating AI-driven analytics to offer personalized health insights, assessing individual health risks and predicting future health trends based on users' medical records." +# + +## Useful links + +## View attribution files here + + + +## Explainer video (User POV) + + + +## Demo Video (Clients POV) + + + + +- [Pitch Deck](https://github.com/coder12git/Web5-Hack/files/13853501/PULSEPal.pdf) +- [Frontend Deployment](https://web5-hack-413v.vercel.app/#/) + + + +> ## Contributors + +This Project was created by these awesome dedicated members + +

+ Team +

+ + +> ## What's next for Pulsepal + +- Personalized Health Insights: "Our plan includes integrating AI-driven analytics to offer personalized health insights, assessing individual health risks and predicting future health trends based on users' medical records." + +- Natural Language Processing (NLP) Chatbot: "We aim to implement an NLP-powered chatbot that assists users in comprehending medical terminology, interpreting test results, and providing preliminary guidance in emergencies based on entered symptoms." + +- AI-Driven Diagnostics: "Incorporating an AI system for preliminary diagnostics, we intend to analyze symptoms and user-entered data to provide suggestive measures or identify potential health issues, prompting users to seek professional medical advice." + +- Augmented Reality (AR) for First Aid Guidance: "Our future plan involves integrating AR technology to guide users through basic first aid procedures by overlaying instructional visuals onto real-time surroundings." + +- Health Gamification and Incentivization: "To encourage healthy habits, we plan to introduce gamification within PulsePal, utilizing AI to personalize challenges, rewards, and reminders aligned with individual health goals." + +- Predictive Appointment Scheduling: "Utilizing AI algorithms, we aim to predict potential health concerns or follow-up appointments based on stored medical records, proactively suggesting relevant appointments or check-ups." + -2. Natural Language Processing (NLP) Chatbot: "We aim to implement an NLP-powered chatbot that assists users in comprehending medical terminology, interpreting test results, and providing preliminary guidance in emergencies based on entered symptoms." +# +> ## Contributing to the project -3. AI-Driven Diagnostics: "Incorporating an AI system for preliminary diagnostics, we intend to analyze symptoms and user-entered data to provide suggestive measures or identify potential health issues, prompting users to seek professional medical advice." +If you find something worth contributing, please fork the repo, make a pull request and add valid and well-reasoned explanations about your changes or comments. -4. Augmented Reality (AR) for First Aid Guidance: "Our future plan involves integrating AR technology to guide users through basic first aid procedures by overlaying instructional visuals onto real-time surroundings." +Before adding a pull request, please note: -5. Health Gamification and Incentivization: "To encourage healthy habits, we plan to introduce gamification within PulsePal, utilizing AI to personalize challenges, rewards, and reminders aligned with individual health goals." +- This is an open source project. +- Your contributions should be inviting and clear. +- Any additions should be relevant. +- New features should be easy to contribute to. -6. Predictive Appointment Scheduling: "Utilizing AI algorithms, we aim to predict potential health concerns or follow-up appointments based on stored medical records, proactively suggesting relevant appointments or check-ups." +All **`suggestions`** are welcome! +# +> ##### README Created by `Enebeli Emmanuel` for Pulsepal From bbee27406a1ea4d5a3b7fd350c099243fb3c4cf4 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 13:02:41 +0000 Subject: [PATCH 085/120] updated the protocols --- .../src/components/AddCardComponent/index.tsx | 9 +++- tauri-app/src/pages/Home/SignUpForm.tsx | 4 +- tauri-app/src/stores/profile.ts | 50 +++++++++++++++---- tauri-app/src/utils/protocols/defns.ts | 2 +- tauri-app/src/utils/protocols/user.ts | 1 + 5 files changed, 50 insertions(+), 16 deletions(-) diff --git a/tauri-app/src/components/AddCardComponent/index.tsx b/tauri-app/src/components/AddCardComponent/index.tsx index a30753f..f939403 100644 --- a/tauri-app/src/components/AddCardComponent/index.tsx +++ b/tauri-app/src/components/AddCardComponent/index.tsx @@ -6,7 +6,7 @@ import { useForm } from "react-hook-form" import toast from "react-hot-toast"; import DocumentUtils from "@/utils/document"; import { Agent } from "../Auth/types"; -import { ProfileState } from "@/stores/profile"; +import { ProfileState, useProfile } from "@/stores/profile"; const possibleConditions = [ "Cancer", @@ -64,7 +64,8 @@ const formSchema = z.object({ otherFiles: z.array(z.instanceof(File)) }) -const index: FunctionComponent<{profile: ProfileState, agent: Agent, onClose: () => void}> = ({ profile, agent, onClose }) => { +const index: FunctionComponent<{ agent: Agent, onClose: () => void }> = ({ agent, onClose }) => { + const { profile, addCondition } = useProfile(store => ({ profile: store.state.profile!, addCondition: store.addCondition })) const [numFileUploaders, setNumFileUploaders] = useState(0) const form = useForm>({ @@ -86,6 +87,10 @@ const index: FunctionComponent<{profile: ProfileState, agent: Agent, onClose: () return } + const hasAddedCondition = await addCondition(agent, data.condition) + if (hasAddedCondition) + console.log("Added condition to profile") + toast.success('Successfully created record!') onClose() diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index b232969..fd4254f 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -7,7 +7,7 @@ import { z } from "zod" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import toast from "react-hot-toast"; -import { CreatePayload } from "@/utils/user"; +import { SignUpPayload } from "@/stores/profile"; const formSchema = z.object({ firstName: z.string().min(1), @@ -68,7 +68,7 @@ export default function SignUpForm() { } }) - const createProfile = async (agent: Agent, payload: CreatePayload) => { + const createProfile = async (agent: Agent, payload: SignUpPayload) => { const hasSignedUpSuccessfully = await signUp(agent, payload) if (!hasSignedUpSuccessfully) { diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index 69aa213..f332ecb 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -4,27 +4,27 @@ import { Record as UserDetailsProtocolRecord } from "@/utils/protocols/user"; import { Agent } from "@/components/Auth/types"; import UserDetailsUtils, { CreatePayload } from "@/utils/user"; import BlobUtils from "@/utils/blob"; +import { Record as Web5Record } from "@web5/api/browser" -export type ProfileState = { +export type SignUpPayload = Omit + +export type ProfileState = Omit & +{ id: string // username: string - firstName: string, - lastName: string, profilePictureUrl: string } type State = { profile: ProfileState, isSignedIn: true + record: Web5Record } | { profile: null, + record: null, isSignedIn: false } -type Payload = Omit & { - profilePicture: File -} - export const useProfile = create( combine({ state: { @@ -41,6 +41,7 @@ export const useProfile = create( set({ state: { isSignedIn: false, + record: null, profile: null } }) @@ -62,10 +63,10 @@ export const useProfile = create( set({ state: { isSignedIn: true, + record: profileRecord, profile: { + ...profile, id: profileRecord.id, - firstName: profile.firstName, - lastName: profile.lastName, profilePictureUrl } } @@ -73,8 +74,35 @@ export const useProfile = create( return true }, - signUp: async (agent: Agent, payload: CreatePayload) => { - const profile = await UserDetailsUtils.createUserDetailsRecord(agent, payload) + addCondition: async (agent: Agent, condition: string) => { + const state = get().state + if (!state.isSignedIn) return false + + const { profilePictureUrl, ...payload } = state.profile + if (payload.conditions.indexOf(condition) < -1) return + + payload.conditions.push(condition) + + const updatedRecord = await UserDetailsUtils.updateUserDetailsRecord(agent, state.record, payload) + if (!updatedRecord) return false + const profile = await updatedRecord.data.json() + + set({ + state: { + isSignedIn: true, + record: updatedRecord, + profile: { + ...profile, + id: updatedRecord.id, + profilePictureUrl + } + } + }) + + return updatedRecord + }, + signUp: async (agent: Agent, payload: SignUpPayload) => { + const profile = await UserDetailsUtils.createUserDetailsRecord(agent, { ...payload, conditions: [] }) if (!profile) return false return profile diff --git a/tauri-app/src/utils/protocols/defns.ts b/tauri-app/src/utils/protocols/defns.ts index b1ffec6..3a26bbd 100644 --- a/tauri-app/src/utils/protocols/defns.ts +++ b/tauri-app/src/utils/protocols/defns.ts @@ -1 +1 @@ -export const url = "https://dschema.org/v0.0.8" as const +export const url = "https://dschema.org/v0.0.10a" as const diff --git a/tauri-app/src/utils/protocols/user.ts b/tauri-app/src/utils/protocols/user.ts index 95967af..7f63622 100644 --- a/tauri-app/src/utils/protocols/user.ts +++ b/tauri-app/src/utils/protocols/user.ts @@ -33,6 +33,7 @@ export namespace Record { firstName: string lastName: string profilePictureId: string + conditions: string[] description: string dateCreated: string } From dc87ecf3b986ed62bdeeca87d1f8d29254b488cb Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 13:28:03 +0000 Subject: [PATCH 086/120] updated the schema --- tauri-app/src/stores/profile.ts | 4 ++-- tauri-app/src/utils/protocols/defns.ts | 2 +- tauri-app/src/utils/protocols/user.ts | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index f332ecb..9740536 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -6,7 +6,7 @@ import UserDetailsUtils, { CreatePayload } from "@/utils/user"; import BlobUtils from "@/utils/blob"; import { Record as Web5Record } from "@web5/api/browser" -export type SignUpPayload = Omit +export type SignUpPayload = Omit export type ProfileState = Omit & { @@ -102,7 +102,7 @@ export const useProfile = create( return updatedRecord }, signUp: async (agent: Agent, payload: SignUpPayload) => { - const profile = await UserDetailsUtils.createUserDetailsRecord(agent, { ...payload, conditions: [] }) + const profile = await UserDetailsUtils.createUserDetailsRecord(agent, { ...payload, conditions: [], did: agent.did }) if (!profile) return false return profile diff --git a/tauri-app/src/utils/protocols/defns.ts b/tauri-app/src/utils/protocols/defns.ts index 3a26bbd..0614789 100644 --- a/tauri-app/src/utils/protocols/defns.ts +++ b/tauri-app/src/utils/protocols/defns.ts @@ -1 +1 @@ -export const url = "https://dschema.org/v0.0.10a" as const +export const url = "https://dschema.org/v0.0.10b" as const diff --git a/tauri-app/src/utils/protocols/user.ts b/tauri-app/src/utils/protocols/user.ts index 7f63622..0fd726f 100644 --- a/tauri-app/src/utils/protocols/user.ts +++ b/tauri-app/src/utils/protocols/user.ts @@ -30,6 +30,7 @@ const UserDetailsProtocol = { export namespace Record { export type Details = { + did: string firstName: string lastName: string profilePictureId: string From f09be33892f5d96a86e2d61f380aa7778c052632 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Sun, 7 Jan 2024 13:28:15 +0000 Subject: [PATCH 087/120] added guard to the remedies page --- tauri-app/src/App.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index fd55a1b..02ae5d6 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -25,7 +25,13 @@ const router = createHashRouter([ ) }, { path: "/connect", element: }, - { path: "/remedies", element: }, + { + path: "/remedies", element: ( + }> + + + ) + }, { path: "/contact", element: }, { path: "/chat", element: }, ], From 42a729136a95767d52a98c04e26ef24de4d5f9d6 Mon Sep 17 00:00:00 2001 From: koko_codes <58889001+EnebeliEmmanuel@users.noreply.github.com> Date: Sun, 7 Jan 2024 14:59:08 +0100 Subject: [PATCH 088/120] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1d306c8..c0625bb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Pulsepal-MVP 🌟 +# PulsePal-MVP 🌟 -## Welcome to the Pulsepal MVP repository +## Welcome to the PulsePal MVP repository

site @@ -137,7 +137,7 @@ This Project was created by these awesome dedicated members

-> ## What's next for Pulsepal +> ## What's next for PulsePal - Personalized Health Insights: "Our plan includes integrating AI-driven analytics to offer personalized health insights, assessing individual health risks and predicting future health trends based on users' medical records." @@ -166,4 +166,4 @@ Before adding a pull request, please note: All **`suggestions`** are welcome! # -> ##### README Created by `Enebeli Emmanuel` for Pulsepal +> ##### README Created by `Enebeli Emmanuel` for PulsePal From 402d66ccee7417a3b8bf1521291c3d95ef82ec69 Mon Sep 17 00:00:00 2001 From: coder12git Date: Sun, 7 Jan 2024 21:37:51 +0530 Subject: [PATCH 089/120] added toast for alert and fix slice in record for text Signed-off-by: coder12git --- tauri-app/src/components/Card/index.tsx | 2 +- tauri-app/src/pages/chat.tsx | 6 +++++- tauri-app/src/pages/remedy.tsx | 5 +++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tauri-app/src/components/Card/index.tsx b/tauri-app/src/components/Card/index.tsx index 994dabd..c1b8abf 100644 --- a/tauri-app/src/components/Card/index.tsx +++ b/tauri-app/src/components/Card/index.tsx @@ -48,7 +48,7 @@ const index: FC = ({

{title ? title : file_name}

-

{desc.slice(0, 150)}

+

{desc.substring(0, 50) + "..."}

{date} diff --git a/tauri-app/src/pages/chat.tsx b/tauri-app/src/pages/chat.tsx index fbd5444..7ac018d 100644 --- a/tauri-app/src/pages/chat.tsx +++ b/tauri-app/src/pages/chat.tsx @@ -273,6 +273,10 @@ export default function Home() { }; return ( -
+
+

{myDid}

+ + +
); } \ No newline at end of file diff --git a/tauri-app/src/pages/remedy.tsx b/tauri-app/src/pages/remedy.tsx index eb39b90..ac456cf 100644 --- a/tauri-app/src/pages/remedy.tsx +++ b/tauri-app/src/pages/remedy.tsx @@ -1,6 +1,7 @@ import { FunctionComponent, useEffect, useRef, useState } from "react"; import useWeb5Store, { schemaOrgProtocolDefinition } from "@/stores/useWeb5Store"; import { useRemedies } from "@/stores/useRemedy"; +import toast from "react-hot-toast"; import Remedies from './Remedies'; const cards = [ @@ -76,10 +77,10 @@ const Remedy: FunctionComponent = () => { console.log(res) if (res) { - alert(`Remedy record saved: ${res}`) + toast.success('Successfully created remedy!') } else { - alert("Failed to save record") + toast.error('Failed to create remedy!') console.error(); } } From 0ea5c26ae74d86daacf6233a01c7b2983230f74a Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Sun, 7 Jan 2024 23:06:29 +0100 Subject: [PATCH 090/120] partially done awating reviews --- tauri-app/package.json | 1 + tauri-app/src/App.tsx | 5 +- tauri-app/src/components/Chat/index.css | 2 +- tauri-app/src/components/MobileChat/index.css | 101 ++++++++++++ tauri-app/src/components/MobileChat/index.tsx | 70 +++++++++ tauri-app/src/components/Navbar/index.css | 31 ++++ tauri-app/src/components/Navbar/index.tsx | 41 +++-- .../src/components/UserFriendList/index.css | 19 ++- .../src/components/UserFriendList/index.tsx | 12 +- .../components/UserMobileFriendList/index.css | 69 +++++++++ .../components/UserMobileFriendList/index.tsx | 79 ++++++++++ .../components/UserMobileProfile/index.css | 53 +++++++ .../components/UserMobileProfile/index.tsx | 42 +++++ tauri-app/src/index.css | 2 +- tauri-app/src/pages/Chat/index.css | 21 ++- tauri-app/src/pages/Chat/index.tsx | 54 ++++++- tauri-app/src/pages/Home/SignUpForm.tsx | 89 ++++++----- tauri-app/src/pages/Home/index.tsx | 11 +- tauri-app/src/pages/Records/index.css | 44 ++++++ tauri-app/src/pages/Records/index.tsx | 98 ++++++++---- tauri-app/src/pages/Remedies/index.tsx | 31 +++- tauri-app/src/stores/profile.ts | 146 ++++++++++-------- 22 files changed, 846 insertions(+), 175 deletions(-) create mode 100644 tauri-app/src/components/MobileChat/index.css create mode 100644 tauri-app/src/components/MobileChat/index.tsx create mode 100644 tauri-app/src/components/UserMobileFriendList/index.css create mode 100644 tauri-app/src/components/UserMobileFriendList/index.tsx create mode 100644 tauri-app/src/components/UserMobileProfile/index.css create mode 100644 tauri-app/src/components/UserMobileProfile/index.tsx diff --git a/tauri-app/package.json b/tauri-app/package.json index 63472a0..f90ccef 100644 --- a/tauri-app/package.json +++ b/tauri-app/package.json @@ -34,6 +34,7 @@ "react-pdf": "^7.6.0", "react-router-dom": "^6.21.1", "react-spinners": "^0.13.8", + "react-toastify": "^9.1.3", "react-virtualized-auto-sizer": "^1.0.20", "react-window": "^1.8.10", "tailwind-merge": "^2.1.0", diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index fd55a1b..5b8ba6c 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -18,11 +18,12 @@ const router = createHashRouter([ children: [ { path: "/", element: }, { - path: "/records", element: ( + path: "/records", + element: ( }> - ) + ), }, { path: "/connect", element: }, { path: "/remedies", element: }, diff --git a/tauri-app/src/components/Chat/index.css b/tauri-app/src/components/Chat/index.css index a5a6d6c..4ecba23 100644 --- a/tauri-app/src/components/Chat/index.css +++ b/tauri-app/src/components/Chat/index.css @@ -64,7 +64,7 @@ .chats-container::-webkit-scrollbar-thumb { width: 2px; background: var(--color-blue); - border-radius: 5px; + border-radius: 0 5px 5px 0; margin: 0 3px; } diff --git a/tauri-app/src/components/MobileChat/index.css b/tauri-app/src/components/MobileChat/index.css new file mode 100644 index 0000000..3113d50 --- /dev/null +++ b/tauri-app/src/components/MobileChat/index.css @@ -0,0 +1,101 @@ +.m-chat-m-container { + width: 320px; + height: 440px; + background: var(--color-white); + border-radius: 15px; + padding: 8px; +} + +.m-chat-component-container { + box-shadow: var(--box-shadow-black); + border-radius: 15px; + padding: 20px; + width: 80%; + height: 100%; + min-height: 500px; +} + +.m-chat-message-input-container { + width: 100%; + padding: 15px 0px; + display: flex; + justify-content: space-around; + align-items: center; +} + +.m-chat-message-input-container input { + width: 65%; + padding: 8px 5px; + background: var(--color-slate-accent); + border: none; + border-radius: 25px; + outline: none; + font-family: "Roboto"; + font-size: 20px; + text-indent: 8px; +} + +.m-chat-message-input-container button { + width: 40px; + height: 40px; + border: none; + border-radius: 50%; + color: var(--color-white); + background: var(--color-blue); + box-shadow: var(--box-shadow-blue); + font-size: 20px; + outline: none; +} + +.m-chats-container { + width: 90%; + background: var(--color-light-grey); + padding: 12px; + border-radius: 15px 5px 5px 15px; + margin: 0 auto; + overflow-y: scroll; + overflow-x: hidden; + height: 350px; +} + +.m-chats-container::-webkit-scrollbar { + width: 6px; +} + +.m-chats-container::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1); + border-radius: 0 15px 15px 0; + transform: translateX(-4px); +} + +.m-chats-container::-webkit-scrollbar-thumb { + width: 2px; + background: var(--color-blue); + border-radius: 0 5px 5px 0; + margin: 0 3px; +} + +.msg-container { + width: 100%; + margin: 25px 2px; +} + +.msg-f { + width: max-content; + background: var(--color-light-green); + font-family: "Open Sans"; + padding: 4px 10px; + border-radius: 8px 8px 8px 0px; + margin-right: auto; + max-width: 200px; +} + +.msg-t { + width: max-content; + background: var(--color-light-blue); + font-family: "Open Sans"; + padding: 4px 10px; + border-radius: 8px 8px 0px 8px; + margin-left: auto; + max-width: 200px; +} diff --git a/tauri-app/src/components/MobileChat/index.tsx b/tauri-app/src/components/MobileChat/index.tsx new file mode 100644 index 0000000..b462dc6 --- /dev/null +++ b/tauri-app/src/components/MobileChat/index.tsx @@ -0,0 +1,70 @@ +import "./index.css"; +import React, { FC } from "react"; + +interface MessageProp { + message: string; + isLeft: boolean; +} + +const Message: FC = ({ message, isLeft }) => { + return ( +
+
+

{message}

+
+
+ ); +}; + +const index: FC = ({ setHideChat, hideChat }) => { + return ( +
+
+ + + + + + +
+
+ + + +
+
+ ); +}; + +export default index; diff --git a/tauri-app/src/components/Navbar/index.css b/tauri-app/src/components/Navbar/index.css index b433b8d..0227c4f 100644 --- a/tauri-app/src/components/Navbar/index.css +++ b/tauri-app/src/components/Navbar/index.css @@ -104,6 +104,37 @@ margin-left: 10px; } +.did-container { + width: 200px; + height: 150px; + background: var(--color-white); + box-shadow: var(--box-shadow-black); + position: absolute; + top: 100px; + right: 45px; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + padding: 8px; + border-radius: 5px; +} + +.did-container .auth_container { + background: var(--color-red); + box-shadow: var(--box-shadow-red); +} + +.did-container input { + background: var(--color-slate-accent); + border-radius: 5px; + border: none; + font-family: "Roboto"; + outline: none; + padding: 8px 4px; + margin: 14px 0px; +} + @media (max-width: 750px) { .main_navbar_container { padding: 15px 25px; diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index 7482576..a6b8649 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -4,23 +4,28 @@ import { NavLink } from "react-router-dom"; import useWeb5Store from "@/stores/useWeb5Store.ts"; import { Agent } from "../Auth/types"; import { useProfile } from "@/stores/profile.ts"; +import { useState } from "react"; const index = () => { - const { web5, did } = useWeb5Store((state) => ({ web5: state.web5, did: state.did })); - const { signIn, setShowAuthModal, signOut } = useProfile(state => ({ + const { web5, did } = useWeb5Store((state) => ({ + web5: state.web5, + did: state.did, + })); + const { signIn, setShowAuthModal, signOut } = useProfile((state) => ({ signIn: state.signIn, signOut: state.signOut, - setShowAuthModal: state.setShowAuthModal - })) + setShowAuthModal: state.setShowAuthModal, + })); const beginAuthFlow = async (agent: Agent) => { - const signedIn = await signIn(agent) + const signedIn = await signIn(agent); if (!signedIn) { - console.log("displaying auth modal") - setShowAuthModal(true) + console.log("displaying auth modal"); + setShowAuthModal(true); } - } + }; + const [showSignOutUtils, setShowSignOutUtils] = useState(false); return (
@@ -67,18 +72,32 @@ const index = () => { } > + {showSignOutUtils && ( +
+
+ DID: + +
+ +
+ )} + diff --git a/tauri-app/src/components/UserFriendList/index.css b/tauri-app/src/components/UserFriendList/index.css index 9082926..9fe13c0 100644 --- a/tauri-app/src/components/UserFriendList/index.css +++ b/tauri-app/src/components/UserFriendList/index.css @@ -20,6 +20,22 @@ border-radius: 5px; } +.friend-tag-container span { + font-family: "Roboto"; + background: var(--color-red); + border-radius: 3px; + padding: 2px 3px; + color: var(--color-white); + border: 2px solid var(--color-white); + border-radius: 8px; + + font-size: 8px; + position: relative; + left: -5px; + width: 20px; + height: 20px; +} + .friends-list-container hr { width: 60%; margin: 0 auto; @@ -42,7 +58,6 @@ } .friends-list-header { - background: var(--color-blue); padding: 8px 12px; border-radius: 10px; color: var(--color-white); @@ -52,7 +67,7 @@ .friend-main-list-container { overflow-y: scroll; - height: 300px; + height: 250px; margin: 15px 0; padding: 5px; } diff --git a/tauri-app/src/components/UserFriendList/index.tsx b/tauri-app/src/components/UserFriendList/index.tsx index 38833b0..210ade9 100644 --- a/tauri-app/src/components/UserFriendList/index.tsx +++ b/tauri-app/src/components/UserFriendList/index.tsx @@ -5,16 +5,21 @@ interface FriendTagProp { friendProfileImg: string; friendName: string; isFriendOnline: boolean; + newChat?: number; } const FriendTag: FC = ({ friendProfileImg, friendName, isFriendOnline, + newChat, }) => { return (
- +
+ + {newChat && {newChat}} +

{friendName.slice(0, 6) + "..."}

= ({ interface UserFriendListProp { friendList: FriendTagProp[]; + setHideChat: () => void; + hideChat: boolean; } -const index: FC = ({ friendList }) => { +const index: FC = ({ friendList, setHideChat, hideChat }) => { return (
@@ -46,6 +53,7 @@ const index: FC = ({ friendList }) => { friendProfileImg={friend.profile_pic} isFriendOnline={friend.isOnline} friendName={friend.username} + newChat={friend.newChat} />
diff --git a/tauri-app/src/components/UserMobileFriendList/index.css b/tauri-app/src/components/UserMobileFriendList/index.css new file mode 100644 index 0000000..68bbd6e --- /dev/null +++ b/tauri-app/src/components/UserMobileFriendList/index.css @@ -0,0 +1,69 @@ +.m-friend-tag-container { + display: flex; + justify-content: space-around; + align-items: center; + border-radius: 15px; + padding: 2px 8px; + transition: 0.3s; + margin: 15px 20px; + background: var(--color-slate-accent); + box-shadow: var(--box-shadow-black); + height: 80px; +} + +.m-friend-tag-container h1 { + font-size: 15px; + font-family: "Roboto"; +} + +.m-friend-tag-container img { + width: 60px; + height: 60px; + border-radius: 50%; +} + +.m-friend-tag-container span { + font-family: "Roboto"; + background: var(--color-red); + border-radius: 3px; + padding: 2px 3px; + color: var(--color-white); + border: 2px solid var(--color-white); + border-radius: 8px; + font-size: 8px; + position: relative; + left: -15px; + top: -4px; + width: 40px; + height: 40px; +} + +.m-friends-list-container hr { + width: 80%; + margin: 0 auto; +} + +.m-friends-list-container hr:last-child { + display: none; +} + +.m-friends-list-container { + border-radius: 15px; +} + +.m-friends-list-header { + padding: var(--padding-mobile); + font-family: "Roboto"; + text-align: left; +} + +.m-friend-main-list-container { + overflow: hidden; +} + +.m-header { + background: var(--color-blue); + color: var(--color-white); + font-family: "Roboto"; + padding: 8px 25px; +} diff --git a/tauri-app/src/components/UserMobileFriendList/index.tsx b/tauri-app/src/components/UserMobileFriendList/index.tsx new file mode 100644 index 0000000..2d22492 --- /dev/null +++ b/tauri-app/src/components/UserMobileFriendList/index.tsx @@ -0,0 +1,79 @@ +import "./index.css"; +import React, { FC, useState } from "react"; + +interface FriendTagProp { + friendProfileImg: string; + friendName: string; + isFriendOnline: boolean; + newChat?: number; + setHideChat: () => void; + hideChat: boolean; +} + +interface UserFriendListProp { + friendList: FriendTagProp[]; +} + +const FriendTag: FC = ({ + friendProfileImg, + friendName, + isFriendOnline, + newChat, + setHideChat, + hideChat, +}) => { + return ( +
setHideChat(!hideChat)} + className="m-friend-tag-container" + > +
+ + {newChat && {newChat}} +
+
+

{friendName.slice(0, 20) + "..."}

+
+ +
+ ); +}; + +const index: FC = ({ + friendList, + hideChat, + setHideChat, +}) => { + return ( +
+
+

Friends

+
+
+ {friendList.map((friend) => { + return ( + <> + + + ); + })} +
+
+ ); +}; + +export default index; diff --git a/tauri-app/src/components/UserMobileProfile/index.css b/tauri-app/src/components/UserMobileProfile/index.css new file mode 100644 index 0000000..2704664 --- /dev/null +++ b/tauri-app/src/components/UserMobileProfile/index.css @@ -0,0 +1,53 @@ +.m-userprofile-container { + box-shadow: var(--box-shadow-black); + text-align: center; + position: relative; + padding-bottom: 15px; +} + +.m-userprofile-info-container img { + width: 80px; + height: 80px; + border-radius: 50%; + background: var(--color-white); + padding: 10px; + position: absolute; + top: 80px; + right: 20px; +} + +.m-userprofile-info-container p { + font-family: "Open Sans"; + margin-top: 50px; +} + +.m-cover-container { + height: 130px; + width: auto; + text-align: left; + padding-right: 6px; +} + +.m-cover-container h3 { + color: var(--color-white); + font-family: "Roboto"; + font-size: 18px; + position: relative; + left: 6px; + top: 10px; +} + +.m-cover-container p { + color: var(--color-white); + font-family: "Open Sans"; + font-size: 14px; + position: relative; + left: 6px; + top: 25px; +} + +@media (max-width: 750px) { + .m-userprofile-container { + width: auto; + } +} diff --git a/tauri-app/src/components/UserMobileProfile/index.tsx b/tauri-app/src/components/UserMobileProfile/index.tsx new file mode 100644 index 0000000..e25db19 --- /dev/null +++ b/tauri-app/src/components/UserMobileProfile/index.tsx @@ -0,0 +1,42 @@ +import React, { FC } from "react"; + +import "./index.css"; + +interface UserProfileProps { + username: String; + profile_pic: String; + cover_pic: String; + about_user: String; + friends: Number; +} +const index: FC = ({ + username, + profile_pic, + cover_pic, + about_user, + friends, +}) => { + return ( +
+
+

@{username}

+

+ Friends | {friends} +

+
+
+ +

{about_user}

+
+
+ ); +}; + +export default index; diff --git a/tauri-app/src/index.css b/tauri-app/src/index.css index 5bfae8d..1696928 100644 --- a/tauri-app/src/index.css +++ b/tauri-app/src/index.css @@ -5,7 +5,7 @@ --box-shadow-red: 0 5px 12px rgba(239, 68, 68, 0.5); --color-blue: #0ea5e9; --box-shadow-blue: 0 5px 12px rgba(14, 165, 233, 0.3); - --box-shadow-black: 0 3px 12px rgba(0, 0, 0, 0.2); + --box-shadow-black: 0 3px 12px rgba(0, 0, 0, 0.1); --color-slate-accent: #f1f5f9; --color-white: #fff; --color-black: #000; diff --git a/tauri-app/src/pages/Chat/index.css b/tauri-app/src/pages/Chat/index.css index 4632a88..866178c 100644 --- a/tauri-app/src/pages/Chat/index.css +++ b/tauri-app/src/pages/Chat/index.css @@ -1,14 +1,14 @@ .main-chat-container { padding: var(--padding-desktop); display: flex; - justify-content: space-between; + justify-content: space-around; align-items: flex-start; position: relative; max-height: 100%; } .utils-container { - width: 30%; + width: 25%; } .chat-container { @@ -16,8 +16,17 @@ height: 100%; } -@media (max-width: 750px) { - .main-chat-container { - padding: var(--padding-mobile); - } +.data-container { + background: rgba(0, 0, 0, 0.3); + position: fixed; + width: 100%; + height: 100vh; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + z-index: 7; } + +@media (max-width: 750px) {} diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index 560826e..307e28b 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -1,18 +1,64 @@ import "./index.css"; import UserProfile from "../../components/UserProfile/"; import UserFriendList from "../../components/UserFriendList/"; + import Chat from "../../components/Chat/"; -import { useState } from "react"; +import UserMobileProfile from "../../components/UserMobileProfile/"; +import UserMobileFriendList from "../../components/UserMobileFriendList/"; +import MobileChat from "../../components/MobileChat"; + +import { useEffect, useState } from "react"; const index = () => { const [friends, setFriends] = useState([ { profile_pic: "/pg.jpg", username: "@scriptkidd", isOnline: false }, - { profile_pic: "/pg.jpg", username: "@nikki", isOnline: false }, - { profile_pic: "/pm.jpg", username: "@gregidd", isOnline: true }, - { profile_pic: "/pic.jpg", username: "@scdd", isOnline: false }, + { profile_pic: "/pg.jpg", username: "@nikki", isOnline: false, newChat: 1 }, + { + profile_pic: "/pm.jpg", + username: "@gregidd", + isOnline: true, + newChat: 7, + }, + { profile_pic: "/pic.jpg", username: "@scdd", isOnline: false, newChat: 4 }, ]); + const [isMobile, setIsMobile] = useState(false); + const [hideChat, setHideChat] = useState(false); + + useEffect(() => { + if (window.innerWidth < 750) { + setIsMobile(true); + return; + } + + setIsMobile(false); + }, []); + if (isMobile) { + return ( +
+ + + {hideChat && ( +
+ +
+ )} +
+ ); + } return (
diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index 68a1fe6..95e7547 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -3,9 +3,9 @@ import useWeb5Store from "@/stores/useWeb5Store"; import { useProfile } from "@/stores/profile"; import { Agent } from "@/components/Auth/types"; import { FunctionComponent, useRef, useState } from "react"; -import { z } from "zod" -import { zodResolver } from "@hookform/resolvers/zod" -import { useForm } from "react-hook-form" +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; import toast from "react-hot-toast"; import { CreatePayload } from "@/utils/user"; @@ -13,14 +13,16 @@ const formSchema = z.object({ firstName: z.string().min(1), lastName: z.string().min(1), description: z.string().min(1), - profilePicture: z.instanceof(File) -}) + profilePicture: z.instanceof(File), +}); interface FileProp { file: File | null | undefined; } -const FileUploader: FunctionComponent<{ onChange: (file: File | null) => void }> = ({ onChange }) => { +const FileUploader: FunctionComponent<{ + onChange: (file: File | null) => void; +}> = ({ onChange }) => { const [file, setFile] = useState({ file: null }); return ( @@ -29,8 +31,8 @@ const FileUploader: FunctionComponent<{ onChange: (file: File | null) => void }>
{ - const file = e?.target?.files?.[0] - onChange(file ? file : null) + const file = e?.target?.files?.[0]; + onChange(file ? file : null); setFile({ file: e?.target?.files?.[0] }); }} type="file" @@ -41,58 +43,64 @@ const FileUploader: FunctionComponent<{ onChange: (file: File | null) => void }> }; export default function SignUpForm() { - console.log("kfjle") - const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })); + console.log("kfjle"); + const { web5, did } = useWeb5Store((state) => ({ + web5: state.web5!, + did: state.did!, + })); const submitBtnRef = useRef(null); - const { setShowAuthModal, signUp, signIn } = useProfile( - (state) => ({ signUp: state.signUp, signIn: state.signIn, setShowAuthModal: state.setShowAuthModal }), - ); + const { setShowAuthModal, signUp, signIn } = useProfile((state) => ({ + signUp: state.signUp, + signIn: state.signIn, + setShowAuthModal: state.setShowAuthModal, + })); const form = useForm>({ - resolver: zodResolver(formSchema) - }) + resolver: zodResolver(formSchema), + }); form.watch((value) => { - if (!submitBtnRef.current) return + if (!submitBtnRef.current) return; - const isValid = formSchema.safeParse(value).success + const isValid = formSchema.safeParse(value).success; if (isValid) { - submitBtnRef.current.classList.remove("not-filled-btn") - submitBtnRef.current.classList.add("filled-btn") - submitBtnRef.current.disabled = false - } - else { - submitBtnRef.current.classList.add("not-filled-btn") - submitBtnRef.current.classList.remove("filled-btn") - submitBtnRef.current.disabled = true + submitBtnRef.current.classList.remove("not-filled-btn"); + submitBtnRef.current.classList.add("filled-btn"); + submitBtnRef.current.disabled = false; + } else { + submitBtnRef.current.classList.add("not-filled-btn"); + submitBtnRef.current.classList.remove("filled-btn"); + submitBtnRef.current.disabled = true; } - }) + }); const createProfile = async (agent: Agent, payload: CreatePayload) => { - const hasSignedUpSuccessfully = await signUp(agent, payload) + const hasSignedUpSuccessfully = await signUp(agent, payload); if (!hasSignedUpSuccessfully) { - toast.error('Sorry an error occurred!') - return + toast.error("Sorry an error occurred!"); + return; } - if (!await signIn(agent)) return - - toast.success('Successfully signed up!') + if (!(await signIn(agent))) return; + toast.success("Successfully signed up!"); - setShowAuthModal(false) - } + setShowAuthModal(false); + }; const onSubmit = (value: z.infer) => { - if (web5 && did) createProfile({ web5, did }, value) - } + if (web5 && did) createProfile({ web5, did }, value); + }; return ( -
-
+
setShowAuthModal(false)}> + e.stopPropagation()} + onSubmit={form.handleSubmit(onSubmit)} + > form.setValue("profilePicture", file as File)} /> @@ -124,6 +132,5 @@ export default function SignUpForm() {
- ) + ); } - diff --git a/tauri-app/src/pages/Home/index.tsx b/tauri-app/src/pages/Home/index.tsx index 867031f..6e99dae 100644 --- a/tauri-app/src/pages/Home/index.tsx +++ b/tauri-app/src/pages/Home/index.tsx @@ -4,7 +4,7 @@ import SignUpForm from "./SignUpForm"; import AuthGuard from "@/components/Auth/Guard"; export default function HomePage() { - const showAuthModal = useProfile(state => state.showAuthModal); + const showAuthModal = useProfile((state) => state.showAuthModal); return ( <> @@ -219,13 +219,8 @@ export default function HomePage() {
- {showAuthModal && ( - - {console.log("fjekkfle") || null} - - - )} -
+ {showAuthModal && } +
); } diff --git a/tauri-app/src/pages/Records/index.css b/tauri-app/src/pages/Records/index.css index f1bf303..fc6c53d 100644 --- a/tauri-app/src/pages/Records/index.css +++ b/tauri-app/src/pages/Records/index.css @@ -70,6 +70,50 @@ position: relative; } +.no-records { + font-family: "Open Sans"; +} + +.connect-wallet-container { + width: 300px; + height: 200px; + background: var(--color-white); + border-radius: 15px; + padding: 18px 8px; + text-align: center; +} + +.connect-wallet-container h1 { + font-family: "Roboto"; + font-size: 25px; + margin-top: 30px; +} + +.connect-wallet-container button { + padding: 8px 20px; + border-radius: 8px; + background: var(--color-green); + box-shadow: var(--box-shadow-green); + color: var(--color-white); + font-family: "Roboto"; + cursor: pointer; + font-weight: 800; + border: none; + min-width: 180px; + font-size: 25px; + text-align: center; + margin-top: 40px; + outline: none; +} + +.connect-wallet-container button i { + background: var(--color-white); + padding: 10px 12px; + border-radius: 50%; + color: var(--color-black); + margin-left: 10px; +} + @media (max-width: 750px) { .main-records-container { padding: var(--padding-mobile); diff --git a/tauri-app/src/pages/Records/index.tsx b/tauri-app/src/pages/Records/index.tsx index 6a3c4ef..5d53c6f 100644 --- a/tauri-app/src/pages/Records/index.tsx +++ b/tauri-app/src/pages/Records/index.tsx @@ -9,32 +9,46 @@ import Card from "../../components/Card"; import { useProfile } from "@/stores/profile"; import useWeb5Store from "@/stores/useWeb5Store"; import { CardData, fetchRecords } from "./utils"; +import toast, { Toaster } from "react-hot-toast"; const index = () => { - const agent = useWeb5Store(state => ({ web5: state.web5!, did: state.did! })) - const profile = useProfile(state => state.state.profile!) + const agent = useWeb5Store((state) => ({ + web5: state.web5!, + did: state.did!, + })); + const profile = useProfile((state) => state.state.profile!); + const isSignedIn = useProfile((state) => state.state.isSignedIn); + const [showConnectWalletComponent, setShowConnectWalletComponent] = + useState(false); const [cardsData, setCardsData] = useState([]); useEffect(() => { - refetchRecords() - }, []) + refetchRecords(); + }, []); const refetchRecords = async () => { - const records = await fetchRecords(agent, profile) - console.log('records:', records) + const records = await fetchRecords(agent, profile); + console.log("records:", records); - if (!records) return + if (!records) return; - setCardsData(records) + setCardsData(records); - return - } + return; + }; const [isAddCardActive, setIsAddCardActive] = useState(false); const [isCardDetailActive, setIsCardDetailActive] = useState(false); const [activeCard, setActiveCard] = useState(null); + const SignedInCheck = () => { + if (isSignedIn) { + setIsAddCardActive(!isAddCardActive); + } else { + setShowConnectWalletComponent(true); + } + }; // @ts-ignore const isCardClicked = (cardDetail) => { setIsCardDetailActive(!isCardDetailActive); @@ -50,24 +64,28 @@ const index = () => { className={ !isAddCardActive ? "add-records-btn" : "close-add-records-btn" } - onClick={() => setIsAddCardActive(!isAddCardActive)} + onClick={() => SignedInCheck()} >
- {cardsData.length > 0 ? cardsData.map((card) => { - return ( - - ); - }) :
No Records Found
} + {cardsData.length > 0 ? ( + cardsData.map((card) => { + return ( + + ); + }) + ) : ( +
No Records Found
+ )}
{(isAddCardActive || isCardDetailActive) && (
{ style={{ zIndex: `${isCardDetailActive ? "7" : "6"}` }} >
- {isAddCardActive && { - setIsAddCardActive(false) - refetchRecords() - }} /> - } + {isAddCardActive && ( + { + setIsAddCardActive(false); + refetchRecords(); + }} + /> + )} {isCardDetailActive && ( {
)} + {showConnectWalletComponent && ( +
setShowConnectWalletComponent(false)} + className="add-card-container" + > +
{ + e.stopPropagation(); + }} + > +

Unauthorized - Please Sign in

+ +
+
+ )}
); }; diff --git a/tauri-app/src/pages/Remedies/index.tsx b/tauri-app/src/pages/Remedies/index.tsx index c4ca609..f126edb 100644 --- a/tauri-app/src/pages/Remedies/index.tsx +++ b/tauri-app/src/pages/Remedies/index.tsx @@ -1,5 +1,6 @@ import "./index.css"; import { useState } from "react"; +import { useProfile } from "@/stores/profile"; import Ratings from "../../components/Ratings"; import RemedyCard from "../../components/RemedyCard/"; @@ -45,6 +46,10 @@ const index = ({ save, formFunc, form, remediesData, docsWithImageUrls }) => { }, ]); + const isSignedIn = useProfile((state) => state.state.isSignedIn); + const [showConnectWalletComponent, setShowConnectWalletComponent] = + useState(false); + const [isDetailRemedyActive, setIsDetailRemedyActive] = useState(false); const [activeRemedy, setActiveRemedy] = useState(null); @@ -83,6 +88,13 @@ const index = ({ save, formFunc, form, remediesData, docsWithImageUrls }) => { }; const [isAddRemedyActive, setIsAddRemedyActive] = useState(false); + const SignedInCheck = () => { + if (isSignedIn) { + setIsAddRemedyActive(!isAddRemedyActive); + } else { + setShowConnectWalletComponent(true); + } + }; return (
@@ -92,7 +104,7 @@ const index = ({ save, formFunc, form, remediesData, docsWithImageUrls }) => { className={ !isAddRemedyActive ? "add-records-btn" : "close-add-records-btn" } - onClick={() => setIsAddRemedyActive(!isAddRemedyActive)} + onClick={() => SignedInCheck()} >
@@ -205,6 +217,23 @@ const index = ({ save, formFunc, form, remediesData, docsWithImageUrls }) => { />
)} + + {showConnectWalletComponent && ( +
setShowConnectWalletComponent(false)} + className="add-remedy-container" + > +
{ + e.stopPropagation(); + }} + > +

Unauthorized - Please Sign in

+ +
+
+ )}
); }; diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index bce5670..8c3670b 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -1,4 +1,4 @@ -import { create } from "zustand" +import { create } from "zustand"; import { combine } from "zustand/middleware"; import { Record as UserDetailsProtocolRecord } from "@/utils/protocols/user"; import { Agent } from "@/components/Auth/types"; @@ -6,78 +6,94 @@ import UserDetailsUtils, { CreatePayload } from "@/utils/user"; import DocumentUtils from "@/utils/document"; export type ProfileState = { - id: string + id: string; // username: string - firstName: string, - lastName: string, - profilePictureUrl: string -} + firstName: string; + lastName: string; + profilePictureUrl: string; +}; -type State = { - profile: ProfileState, - isSignedIn: true -} | { - profile: null, - isSignedIn: false -} +type State = + | { + profile: ProfileState; + isSignedIn: true; + } + | { + profile: null; + isSignedIn: false; + }; -type Payload = Omit & { - profilePicture: File -} +type Payload = Omit< + UserDetailsProtocolRecord.Details, + "dateCreated" | "profilePictureUrl" +> & { + profilePicture: File; +}; export const useProfile = create( - combine({ - state: { - profile: null, - isSignedIn: false - } as State, - showAuthModal: false - }, (set, get) => ({ - setShowAuthModal: (showAuthModal: boolean) => { - set({ showAuthModal }) - }, - signOut: () => { - if (get().state.isSignedIn) { - set({ - state: { - isSignedIn: false, - profile: null - } - }) - } + combine( + { + state: { + profile: null, + isSignedIn: false, + } as State, + showAuthModal: false, }, - signIn: async (agent: Agent) => { - const profileRecord = await UserDetailsUtils.fetchUserDetailsRecord(agent) - if (!profileRecord) return false - - const profile: UserDetailsProtocolRecord.Details = await profileRecord.data.json() + (set, get) => ({ + setShowAuthModal: (showAuthModal: boolean) => { + set({ showAuthModal }); + }, + signOut: () => { + if (get().state.isSignedIn) { + set({ + state: { + isSignedIn: false, + profile: null, + }, + }); + } + }, + signIn: async (agent: Agent) => { + const profileRecord = + await UserDetailsUtils.fetchUserDetailsRecord(agent); + if (!profileRecord) return false; - const profilePicture = await DocumentUtils.fetchBlobRecord(agent, profile.profilePictureId) - let profilePictureUrl = "" - if (profilePicture) { - const profilePictureBlob = await profilePicture.data.blob() - profilePictureUrl = URL.createObjectURL(profilePictureBlob) - } + const profile: UserDetailsProtocolRecord.Details = + await profileRecord.data.json(); - set({ - state: { - isSignedIn: true, - profile: { - id: profileRecord.id, - firstName: profile.firstName, - lastName: profile.lastName, - profilePictureUrl - } + const profilePicture = await DocumentUtils.fetchBlobRecord( + agent, + profile.profilePictureId, + ); + let profilePictureUrl = ""; + if (profilePicture) { + const profilePictureBlob = await profilePicture.data.blob(); + profilePictureUrl = URL.createObjectURL(profilePictureBlob); } - }) - return true - }, - signUp: async (agent: Agent, payload: CreatePayload) => { - const profile = await UserDetailsUtils.createUserDetailsRecord(agent, payload) - if (!profile) return false + set({ + state: { + isSignedIn: true, + profile: { + id: profileRecord.id, + firstName: profile.firstName, + lastName: profile.lastName, + profilePictureUrl, + }, + }, + }); - return true - } - })) -) + return true; + }, + signUp: async (agent: Agent, payload: CreatePayload) => { + const profile = await UserDetailsUtils.createUserDetailsRecord( + agent, + payload, + ); + if (!profile) return false; + + return true; + }, + }), + ), +); From 99dd61bd10b3ad6a62d10b80e6ec0bf62f343a0c Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 00:29:20 +0100 Subject: [PATCH 091/120] resolved errors --- tauri-app/src/pages/Home/SignUpForm.tsx | 11 +- tauri-app/src/pages/Home/index.tsx | 376 ++++++++++++------------ tauri-app/src/stores/profile.ts | 180 ++++++------ 3 files changed, 281 insertions(+), 286 deletions(-) diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index 6b3a019..dd58adb 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -43,15 +43,12 @@ const FileUploader: FunctionComponent<{ }; export default function SignUpForm() { -<<<<<<< HEAD console.log("kfjle"); const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did!, })); -======= - const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })); ->>>>>>> 402d66ccee7417a3b8bf1521291c3d95ef82ec69 + const submitBtnRef = useRef(null); const { setShowAuthModal, signUp, signIn } = useProfile((state) => ({ signUp: state.signUp, @@ -79,8 +76,8 @@ export default function SignUpForm() { } }); - const createProfile = async (agent: Agent, payload: SignUpPayload) => { - const hasSignedUpSuccessfully = await signUp(agent, payload) + const createProfile = async (agent: Agent, payload: SignUpPayload) => { + const hasSignedUpSuccessfully = await signUp(agent, payload); if (!hasSignedUpSuccessfully) { toast.error("Sorry an error occurred!"); @@ -93,8 +90,6 @@ export default function SignUpForm() { setShowAuthModal(false); }; - setShowAuthModal(false) - } const onSubmit = (value: z.infer) => { if (web5 && did) createProfile({ web5, did }, value); diff --git a/tauri-app/src/pages/Home/index.tsx b/tauri-app/src/pages/Home/index.tsx index aa0fc24..5e65db7 100644 --- a/tauri-app/src/pages/Home/index.tsx +++ b/tauri-app/src/pages/Home/index.tsx @@ -7,219 +7,219 @@ export default function HomePage() { const showAuthModal = useProfile((state) => state.showAuthModal); return ( - <> -
-
-
- - Hi welcome to, - - pulsePal - +
+
+
+ + Hi welcome to, + + pulsePal -

Stay up & running while connected

+
+

Stay up & running while connected

+

+ Welcome to PulsePal, your health guardian in WEB5. Safely store + medical records with decentralized identifiers and web nodes, + ensuring data security. Connect with similar conditions, share home + remedies with a rating system, and access specialized doctors based + on your location. PulsePal – where advanced technology meets + user-friendly design for your secure, connected health journey. +

+ +
+
+
+ + + +
+

Major Technologies

+
+
+ +

WEB5

- Welcome to PulsePal, your health guardian in WEB5. Safely store - medical records with decentralized identifiers and web nodes, - ensuring data security. Connect with similar conditions, share - home remedies with a rating system, and access specialized doctors - based on your location. PulsePal – where advanced technology meets - user-friendly design for your secure, connected health journey. + PulsePal utililizes WEB5 to ensure the immutability of user data + stored making it a breeze to safely store medical data and + records.

-
-
-
- - - -
-

Major Technologies

-
-
- -

WEB5

-

- PulsePal utililizes WEB5 to ensure the immutability of user data - stored making it a breeze to safely store medical data and - records. -

-
-
- -

A.I

-

- PulsePal uses artificial intelligence to aid users with similiar - medical conditions, find matches who can relate with them and - also find doctors/specialist within there regions on such - condition. -

-
-
- -

React

-

- PulsePal employes react a frontend framework to power our - frontend along with typescript enabling better user experience - and smoother and faster development,updates and feature roll - outs giving quality product delivery. -

-
+
+ +

A.I

+

+ PulsePal uses artificial intelligence to aid users with similiar + medical conditions, find matches who can relate with them and also + find doctors/specialist within there regions on such condition. +

-
- - - -
-
-
-

- "Our Culture" -

+
+ +

React

- A culture where innovation and empathy converge to create - impactful solutions. Team members are driven by a shared - commitment to improving healthcare outcomes through cutting-edge - technology. + PulsePal employes react a frontend framework to power our frontend + along with typescript enabling better user experience and smoother + and faster development,updates and feature roll outs giving + quality product delivery.

- - - -
-

Testimonials

-
-
-
-
- -

Dave

-
-
-

- PulsePal has being awesome so far making it a breeze - to keep track of my medical history coupled with guidance - have made staying healthy so much more accessible. The - user-friendly interface and helpful home remedies{" "} - keep me on prepared for emergency breakouts.{" "} - Thank you -

-
+
+ + + +
+
+
+

+ "Our Culture" +

+

+ A culture where innovation and empathy converge to create impactful + solutions. Team members are driven by a shared commitment to + improving healthcare outcomes through cutting-edge technology. +

+
+
+ + + +
+

Testimonials

+
+
+
+
+ +

Dave

-
-
- -

Greg

-
-
-

- Knowing that blockchain is being used and it's - immutaility makes feel safer from losing such vital records - and there - chat functionality is quite great feel's nice to know - others with the same condition as me.Great job -

-
+
+

+ PulsePal has being awesome so far making it a breeze to + keep track of my medical history coupled with guidance have + made staying healthy so much more accessible. The + user-friendly interface and helpful home remedies keep + me on prepared for emergency breakouts. Thank you +

-
+
- -

Nikki

+ +

Greg

- Using it for quite a while now and it had being nice - especially a beta feature,i heard it can find out what - is wrong with your just from your - finger print it is cool can't wait for the roll - out,talk about a.i in action + Knowing that blockchain is being used and it's + immutaility makes feel safer from losing such vital records + and there + chat functionality is quite great feel's nice to know + others with the same condition as me.Great job

-
- - - -
-

Major Features

-
-
- -

Secure Storage

-

- Medical records are stored with the utmost security using WEB5, - guaranteeing data integrity and user control over their personal - health information. -

-
-
- -

Find Your Tribe

-

- Our platform goes beyond conventional networking by employing a - sophisticated algorithm to match users based on their medical - records. PulsePal becomes a virtual community where individuals - can share experiences, insights, and support each other on their - health journeys. -

-
-
- -

Home Remedies

-

- PulsePal empowers users to contribute and share simple yet - effective home remedies. A user-driven rating system ensures the - most beneficial remedies rise to the top, creating a - community-driven repository of wellness solutions. -

+
+
+ +

Nikki

-
- -

Find Specialist

+

- Wherever you are, PulsePal provides a seamless experience by - recommending specialized doctors in your nearby areas based on - your current location, enhancing accessibility to healthcare - professionals. + Using it for quite a while now and it had being nice especially + a beta feature,i heard it can find out what is wrong with + your just from your + finger print it is cool can't wait for the roll out,talk + about a.i in action

- {showAuthModal && } - +
+ + + +
+

Major Features

+
+
+ +

Secure Storage

+

+ Medical records are stored with the utmost security using WEB5, + guaranteeing data integrity and user control over their personal + health information. +

+
+
+ +

Find Your Tribe

+

+ Our platform goes beyond conventional networking by employing a + sophisticated algorithm to match users based on their medical + records. PulsePal becomes a virtual community where individuals + can share experiences, insights, and support each other on their + health journeys. +

+
+
+ +

Home Remedies

+

+ PulsePal empowers users to contribute and share simple yet + effective home remedies. A user-driven rating system ensures the + most beneficial remedies rise to the top, creating a + community-driven repository of wellness solutions. +

+
+
+ +

Find Specialist

+

+ Wherever you are, PulsePal provides a seamless experience by + recommending specialized doctors in your nearby areas based on + your current location, enhancing accessibility to healthcare + professionals. +

+
+
+
+ {showAuthModal && ( + + + + )} +
); } diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index 551144c..069f337 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -4,9 +4,8 @@ import { Record as UserDetailsProtocolRecord } from "@/utils/protocols/user"; import { Agent } from "@/components/Auth/types"; import UserDetailsUtils, { CreatePayload } from "@/utils/user"; import BlobUtils from "@/utils/blob"; -import { Record as Web5Record } from "@web5/api/browser" +import { Record as Web5Record } from "@web5/api/browser"; -<<<<<<< HEAD export type ProfileState = { id: string; // username: string @@ -32,24 +31,28 @@ type Payload = Omit< profilePicture: File; }; -export type SignUpPayload = Omit +export type SignUpPayload = Omit; -export type ProfileState = Omit & -{ - id: string +export type ProfileState = Omit< + UserDetailsProtocolRecord.Details, + "profilePictureId" +> & { + id: string; // username: string - profilePictureUrl: string -} - -type State = { - profile: ProfileState, - isSignedIn: true - record: Web5Record -} | { - profile: null, - record: null, - isSignedIn: false -} + profilePictureUrl: string; +}; + +type State = + | { + profile: ProfileState; + isSignedIn: true; + record: Web5Record; + } + | { + profile: null; + record: null; + isSignedIn: false; + }; export const useProfile = create( combine( @@ -94,7 +97,6 @@ export const useProfile = create( set({ state: { -<<<<<<< HEAD isSignedIn: true, profile: { id: profileRecord.id, @@ -104,18 +106,11 @@ export const useProfile = create( }, }, }); -======= - isSignedIn: false, - record: null, - profile: null - } - }) - } - }, - signIn: async (agent: Agent) => { - const profileRecord = await UserDetailsUtils.fetchUserDetailsRecord(agent) - if (!profileRecord) return false ->>>>>>> 402d66ccee7417a3b8bf1521291c3d95ef82ec69 + }, + signIn: async (agent: Agent) => { + const profileRecord = + await UserDetailsUtils.fetchUserDetailsRecord(agent); + if (!profileRecord) return false; return true; }, @@ -126,67 +121,72 @@ export const useProfile = create( ); if (!profile) return false; -<<<<<<< HEAD return true; - }, - }), - ), -); -======= - const profilePicture = await BlobUtils.fetchBlobRecord(agent, { recordId: profile.profilePictureId }) - let profilePictureUrl = "" - if (profilePicture) { - const profilePictureBlob = await profilePicture.data.blob() - profilePictureUrl = URL.createObjectURL(profilePictureBlob) - } - - set({ - state: { - isSignedIn: true, - record: profileRecord, - profile: { - ...profile, - id: profileRecord.id, - profilePictureUrl - } - } - }) - return true - }, - addCondition: async (agent: Agent, condition: string) => { - const state = get().state - if (!state.isSignedIn) return false - - const { profilePictureUrl, ...payload } = state.profile - if (payload.conditions.indexOf(condition) < -1) return - - payload.conditions.push(condition) - - const updatedRecord = await UserDetailsUtils.updateUserDetailsRecord(agent, state.record, payload) - if (!updatedRecord) return false - const profile = await updatedRecord.data.json() - - set({ - state: { - isSignedIn: true, - record: updatedRecord, - profile: { - ...profile, - id: updatedRecord.id, - profilePictureUrl - } + const profilePicture = await BlobUtils.fetchBlobRecord(agent, { + recordId: profile.profilePictureId, + }); + let profilePictureUrl = ""; + if (profilePicture) { + const profilePictureBlob = await profilePicture.data.blob(); + profilePictureUrl = URL.createObjectURL(profilePictureBlob); } - }) - return updatedRecord - }, - signUp: async (agent: Agent, payload: SignUpPayload) => { - const profile = await UserDetailsUtils.createUserDetailsRecord(agent, { ...payload, conditions: [], did: agent.did }) - if (!profile) return false + set({ + state: { + isSignedIn: true, + record: profileRecord, + profile: { + ...profile, + id: profileRecord.id, + profilePictureUrl, + }, + }, + }); - return profile - } - })) -) ->>>>>>> 402d66ccee7417a3b8bf1521291c3d95ef82ec69 + return true; + }, + addCondition: async (agent: Agent, condition: string) => { + const state = get().state; + if (!state.isSignedIn) return false; + + const { profilePictureUrl, ...payload } = state.profile; + if (payload.conditions.indexOf(condition) < -1) return; + + payload.conditions.push(condition); + + const updatedRecord = await UserDetailsUtils.updateUserDetailsRecord( + agent, + state.record, + payload, + ); + if (!updatedRecord) return false; + const profile = await updatedRecord.data.json(); + + set({ + state: { + isSignedIn: true, + record: updatedRecord, + profile: { + ...profile, + id: updatedRecord.id, + profilePictureUrl, + }, + }, + }); + + return updatedRecord; + }, + signUp: async (agent: Agent, payload: SignUpPayload) => { + const profile = await UserDetailsUtils.createUserDetailsRecord(agent, { + ...payload, + conditions: [], + did: agent.did, + }); + if (!profile) return false; + + return profile; + }, + }), + ), +); From 8beb0b5fe663506ce7d2a9ac82cb09f388b32d3e Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 01:18:13 +0100 Subject: [PATCH 092/120] minor bugs fixed --- tauri-app/src/App.tsx | 5 ----- tauri-app/src/components/Chat/index.css | 4 ++-- tauri-app/src/components/Navbar/index.tsx | 4 ++-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index e924f54..ced8e50 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -9,7 +9,6 @@ import SharedLayout from "./pages/SharedLayout/"; import Records from "./pages/Records"; import Chat from "./pages/Chat/"; import { Toaster } from "react-hot-toast"; -import ProfileGuard from "./components/Auth/Profile/Guard"; const router = createHashRouter([ { @@ -20,17 +19,13 @@ const router = createHashRouter([ { path: "/records", element: ( - }> - ), }, { path: "/connect", element: }, { path: "/remedies", element: ( - }> - ) }, { path: "/contact", element: }, diff --git a/tauri-app/src/components/Chat/index.css b/tauri-app/src/components/Chat/index.css index 4ecba23..dd76343 100644 --- a/tauri-app/src/components/Chat/index.css +++ b/tauri-app/src/components/Chat/index.css @@ -80,7 +80,7 @@ padding: 4px 10px; border-radius: 8px 8px 8px 0px; margin-right: auto; - max-width: 400px; + max-width: 600px; } .msg-t { @@ -90,5 +90,5 @@ padding: 4px 10px; border-radius: 8px 8px 0px 8px; margin-left: auto; - max-width: 400px; + max-width: 600px; } diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index a6b8649..c0d7567 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -72,7 +72,7 @@ const index = () => { + + +
From 087f38d6bcba4c770739ad3c7f881329adcd81e4 Mon Sep 17 00:00:00 2001 From: koko_codes <58889001+EnebeliEmmanuel@users.noreply.github.com> Date: Mon, 8 Jan 2024 01:35:18 +0100 Subject: [PATCH 095/120] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c0625bb..0d7151e 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ npm run dev ## Explainer video (User POV) +https://github.com/coder12git/Web5-Hack/assets/58889001/b5c4aa11-426c-492b-88fb-37425991ab47 ## Demo Video (Clients POV) From cb67de2089f3b58efc21dc911a19651a99c91346 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 00:29:20 +0100 Subject: [PATCH 096/120] resolved errors --- tauri-app/src/pages/Home/SignUpForm.tsx | 11 +- tauri-app/src/pages/Home/index.tsx | 376 ++++++++++++------------ 2 files changed, 191 insertions(+), 196 deletions(-) diff --git a/tauri-app/src/pages/Home/SignUpForm.tsx b/tauri-app/src/pages/Home/SignUpForm.tsx index 6b3a019..dd58adb 100644 --- a/tauri-app/src/pages/Home/SignUpForm.tsx +++ b/tauri-app/src/pages/Home/SignUpForm.tsx @@ -43,15 +43,12 @@ const FileUploader: FunctionComponent<{ }; export default function SignUpForm() { -<<<<<<< HEAD console.log("kfjle"); const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did!, })); -======= - const { web5, did } = useWeb5Store((state) => ({ web5: state.web5!, did: state.did! })); ->>>>>>> 402d66ccee7417a3b8bf1521291c3d95ef82ec69 + const submitBtnRef = useRef(null); const { setShowAuthModal, signUp, signIn } = useProfile((state) => ({ signUp: state.signUp, @@ -79,8 +76,8 @@ export default function SignUpForm() { } }); - const createProfile = async (agent: Agent, payload: SignUpPayload) => { - const hasSignedUpSuccessfully = await signUp(agent, payload) + const createProfile = async (agent: Agent, payload: SignUpPayload) => { + const hasSignedUpSuccessfully = await signUp(agent, payload); if (!hasSignedUpSuccessfully) { toast.error("Sorry an error occurred!"); @@ -93,8 +90,6 @@ export default function SignUpForm() { setShowAuthModal(false); }; - setShowAuthModal(false) - } const onSubmit = (value: z.infer) => { if (web5 && did) createProfile({ web5, did }, value); diff --git a/tauri-app/src/pages/Home/index.tsx b/tauri-app/src/pages/Home/index.tsx index aa0fc24..5e65db7 100644 --- a/tauri-app/src/pages/Home/index.tsx +++ b/tauri-app/src/pages/Home/index.tsx @@ -7,219 +7,219 @@ export default function HomePage() { const showAuthModal = useProfile((state) => state.showAuthModal); return ( - <> -
-
-
- - Hi welcome to, - - pulsePal - +
+
+
+ + Hi welcome to, + + pulsePal -

Stay up & running while connected

+
+

Stay up & running while connected

+

+ Welcome to PulsePal, your health guardian in WEB5. Safely store + medical records with decentralized identifiers and web nodes, + ensuring data security. Connect with similar conditions, share home + remedies with a rating system, and access specialized doctors based + on your location. PulsePal – where advanced technology meets + user-friendly design for your secure, connected health journey. +

+ +
+
+
+ + + +
+

Major Technologies

+
+
+ +

WEB5

- Welcome to PulsePal, your health guardian in WEB5. Safely store - medical records with decentralized identifiers and web nodes, - ensuring data security. Connect with similar conditions, share - home remedies with a rating system, and access specialized doctors - based on your location. PulsePal – where advanced technology meets - user-friendly design for your secure, connected health journey. + PulsePal utililizes WEB5 to ensure the immutability of user data + stored making it a breeze to safely store medical data and + records.

-
-
-
- - - -
-

Major Technologies

-
-
- -

WEB5

-

- PulsePal utililizes WEB5 to ensure the immutability of user data - stored making it a breeze to safely store medical data and - records. -

-
-
- -

A.I

-

- PulsePal uses artificial intelligence to aid users with similiar - medical conditions, find matches who can relate with them and - also find doctors/specialist within there regions on such - condition. -

-
-
- -

React

-

- PulsePal employes react a frontend framework to power our - frontend along with typescript enabling better user experience - and smoother and faster development,updates and feature roll - outs giving quality product delivery. -

-
+
+ +

A.I

+

+ PulsePal uses artificial intelligence to aid users with similiar + medical conditions, find matches who can relate with them and also + find doctors/specialist within there regions on such condition. +

-
- - - -
-
-
-

- "Our Culture" -

+
+ +

React

- A culture where innovation and empathy converge to create - impactful solutions. Team members are driven by a shared - commitment to improving healthcare outcomes through cutting-edge - technology. + PulsePal employes react a frontend framework to power our frontend + along with typescript enabling better user experience and smoother + and faster development,updates and feature roll outs giving + quality product delivery.

- - - -
-

Testimonials

-
-
-
-
- -

Dave

-
-
-

- PulsePal has being awesome so far making it a breeze - to keep track of my medical history coupled with guidance - have made staying healthy so much more accessible. The - user-friendly interface and helpful home remedies{" "} - keep me on prepared for emergency breakouts.{" "} - Thank you -

-
+
+ + + +
+
+
+

+ "Our Culture" +

+

+ A culture where innovation and empathy converge to create impactful + solutions. Team members are driven by a shared commitment to + improving healthcare outcomes through cutting-edge technology. +

+
+
+ + + +
+

Testimonials

+
+
+
+
+ +

Dave

-
-
- -

Greg

-
-
-

- Knowing that blockchain is being used and it's - immutaility makes feel safer from losing such vital records - and there - chat functionality is quite great feel's nice to know - others with the same condition as me.Great job -

-
+
+

+ PulsePal has being awesome so far making it a breeze to + keep track of my medical history coupled with guidance have + made staying healthy so much more accessible. The + user-friendly interface and helpful home remedies keep + me on prepared for emergency breakouts. Thank you +

-
+
- -

Nikki

+ +

Greg

- Using it for quite a while now and it had being nice - especially a beta feature,i heard it can find out what - is wrong with your just from your - finger print it is cool can't wait for the roll - out,talk about a.i in action + Knowing that blockchain is being used and it's + immutaility makes feel safer from losing such vital records + and there + chat functionality is quite great feel's nice to know + others with the same condition as me.Great job

-
- - - -
-

Major Features

-
-
- -

Secure Storage

-

- Medical records are stored with the utmost security using WEB5, - guaranteeing data integrity and user control over their personal - health information. -

-
-
- -

Find Your Tribe

-

- Our platform goes beyond conventional networking by employing a - sophisticated algorithm to match users based on their medical - records. PulsePal becomes a virtual community where individuals - can share experiences, insights, and support each other on their - health journeys. -

-
-
- -

Home Remedies

-

- PulsePal empowers users to contribute and share simple yet - effective home remedies. A user-driven rating system ensures the - most beneficial remedies rise to the top, creating a - community-driven repository of wellness solutions. -

+
+
+ +

Nikki

-
- -

Find Specialist

+

- Wherever you are, PulsePal provides a seamless experience by - recommending specialized doctors in your nearby areas based on - your current location, enhancing accessibility to healthcare - professionals. + Using it for quite a while now and it had being nice especially + a beta feature,i heard it can find out what is wrong with + your just from your + finger print it is cool can't wait for the roll out,talk + about a.i in action

- {showAuthModal && } - +
+ + + +
+

Major Features

+
+
+ +

Secure Storage

+

+ Medical records are stored with the utmost security using WEB5, + guaranteeing data integrity and user control over their personal + health information. +

+
+
+ +

Find Your Tribe

+

+ Our platform goes beyond conventional networking by employing a + sophisticated algorithm to match users based on their medical + records. PulsePal becomes a virtual community where individuals + can share experiences, insights, and support each other on their + health journeys. +

+
+
+ +

Home Remedies

+

+ PulsePal empowers users to contribute and share simple yet + effective home remedies. A user-driven rating system ensures the + most beneficial remedies rise to the top, creating a + community-driven repository of wellness solutions. +

+
+
+ +

Find Specialist

+

+ Wherever you are, PulsePal provides a seamless experience by + recommending specialized doctors in your nearby areas based on + your current location, enhancing accessibility to healthcare + professionals. +

+
+
+
+ {showAuthModal && ( + + + + )} +
); } From 0421ca8b95136e6e794e9b9f2e94681553dbb377 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 01:18:13 +0100 Subject: [PATCH 097/120] minor bugs fixed --- tauri-app/src/App.tsx | 5 ----- tauri-app/src/components/Chat/index.css | 4 ++-- tauri-app/src/components/Navbar/index.tsx | 4 ++-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index e924f54..ced8e50 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -9,7 +9,6 @@ import SharedLayout from "./pages/SharedLayout/"; import Records from "./pages/Records"; import Chat from "./pages/Chat/"; import { Toaster } from "react-hot-toast"; -import ProfileGuard from "./components/Auth/Profile/Guard"; const router = createHashRouter([ { @@ -20,17 +19,13 @@ const router = createHashRouter([ { path: "/records", element: ( - }> - ), }, { path: "/connect", element: }, { path: "/remedies", element: ( - }> - ) }, { path: "/contact", element: }, diff --git a/tauri-app/src/components/Chat/index.css b/tauri-app/src/components/Chat/index.css index 4ecba23..dd76343 100644 --- a/tauri-app/src/components/Chat/index.css +++ b/tauri-app/src/components/Chat/index.css @@ -80,7 +80,7 @@ padding: 4px 10px; border-radius: 8px 8px 8px 0px; margin-right: auto; - max-width: 400px; + max-width: 600px; } .msg-t { @@ -90,5 +90,5 @@ padding: 4px 10px; border-radius: 8px 8px 0px 8px; margin-left: auto; - max-width: 400px; + max-width: 600px; } diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index a6b8649..c0d7567 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -72,7 +72,7 @@ const index = () => { +
+ )} + + + + ) +} + const index = () => { const { web5, did } = useWeb5Store((state) => ({ web5: state.web5, @@ -25,44 +62,43 @@ const index = () => { } }; - const [showSignOutUtils, setShowSignOutUtils] = useState(false); return (
- - + +
- +

Home

- +

Records

28
- +

Chats

5
- +

DIY Remedies

99+
- +

Contact

@@ -72,34 +108,14 @@ const index = () => { } > - {showSignOutUtils && ( -
-
- DID: - -
- -
- )} - - +
); diff --git a/tauri-app/src/stores/profile.ts b/tauri-app/src/stores/profile.ts index 069f337..9740536 100644 --- a/tauri-app/src/stores/profile.ts +++ b/tauri-app/src/stores/profile.ts @@ -1,192 +1,111 @@ -import { create } from "zustand"; +import { create } from "zustand" import { combine } from "zustand/middleware"; import { Record as UserDetailsProtocolRecord } from "@/utils/protocols/user"; import { Agent } from "@/components/Auth/types"; import UserDetailsUtils, { CreatePayload } from "@/utils/user"; import BlobUtils from "@/utils/blob"; -import { Record as Web5Record } from "@web5/api/browser"; +import { Record as Web5Record } from "@web5/api/browser" -export type ProfileState = { - id: string; - // username: string - firstName: string; - lastName: string; - profilePictureUrl: string; -}; - -type State = - | { - profile: ProfileState; - isSignedIn: true; - } - | { - profile: null; - isSignedIn: false; - }; - -type Payload = Omit< - UserDetailsProtocolRecord.Details, - "dateCreated" | "profilePictureUrl" -> & { - profilePicture: File; -}; +export type SignUpPayload = Omit -export type SignUpPayload = Omit; - -export type ProfileState = Omit< - UserDetailsProtocolRecord.Details, - "profilePictureId" -> & { - id: string; +export type ProfileState = Omit & +{ + id: string // username: string - profilePictureUrl: string; -}; - -type State = - | { - profile: ProfileState; - isSignedIn: true; - record: Web5Record; - } - | { - profile: null; - record: null; - isSignedIn: false; - }; + profilePictureUrl: string +} + +type State = { + profile: ProfileState, + isSignedIn: true + record: Web5Record +} | { + profile: null, + record: null, + isSignedIn: false +} export const useProfile = create( - combine( - { - state: { - profile: null, - isSignedIn: false, - } as State, - showAuthModal: false, + combine({ + state: { + profile: null, + isSignedIn: false + } as State, + showAuthModal: false + }, (set, get) => ({ + setShowAuthModal: (showAuthModal: boolean) => { + set({ showAuthModal }) }, - (set, get) => ({ - setShowAuthModal: (showAuthModal: boolean) => { - set({ showAuthModal }); - }, - signOut: () => { - if (get().state.isSignedIn) { - set({ - state: { - isSignedIn: false, - profile: null, - }, - }); - } - }, - signIn: async (agent: Agent) => { - const profileRecord = - await UserDetailsUtils.fetchUserDetailsRecord(agent); - if (!profileRecord) return false; - - const profile: UserDetailsProtocolRecord.Details = - await profileRecord.data.json(); - - const profilePicture = await DocumentUtils.fetchBlobRecord( - agent, - profile.profilePictureId, - ); - let profilePictureUrl = ""; - if (profilePicture) { - const profilePictureBlob = await profilePicture.data.blob(); - profilePictureUrl = URL.createObjectURL(profilePictureBlob); - } - + signOut: () => { + if (get().state.isSignedIn) { set({ state: { - isSignedIn: true, - profile: { - id: profileRecord.id, - firstName: profile.firstName, - lastName: profile.lastName, - profilePictureUrl, - }, - }, - }); - }, - signIn: async (agent: Agent) => { - const profileRecord = - await UserDetailsUtils.fetchUserDetailsRecord(agent); - if (!profileRecord) return false; - - return true; - }, - signUp: async (agent: Agent, payload: CreatePayload) => { - const profile = await UserDetailsUtils.createUserDetailsRecord( - agent, - payload, - ); - if (!profile) return false; - - return true; - - const profilePicture = await BlobUtils.fetchBlobRecord(agent, { - recordId: profile.profilePictureId, - }); - let profilePictureUrl = ""; - if (profilePicture) { - const profilePictureBlob = await profilePicture.data.blob(); - profilePictureUrl = URL.createObjectURL(profilePictureBlob); + isSignedIn: false, + record: null, + profile: null + } + }) + } + }, + signIn: async (agent: Agent) => { + const profileRecord = await UserDetailsUtils.fetchUserDetailsRecord(agent) + if (!profileRecord) return false + + const profile: UserDetailsProtocolRecord.Details = await profileRecord.data.json() + + const profilePicture = await BlobUtils.fetchBlobRecord(agent, { recordId: profile.profilePictureId }) + let profilePictureUrl = "" + if (profilePicture) { + const profilePictureBlob = await profilePicture.data.blob() + profilePictureUrl = URL.createObjectURL(profilePictureBlob) + } + + set({ + state: { + isSignedIn: true, + record: profileRecord, + profile: { + ...profile, + id: profileRecord.id, + profilePictureUrl + } } + }) - set({ - state: { - isSignedIn: true, - record: profileRecord, - profile: { - ...profile, - id: profileRecord.id, - profilePictureUrl, - }, - }, - }); - - return true; - }, - addCondition: async (agent: Agent, condition: string) => { - const state = get().state; - if (!state.isSignedIn) return false; - - const { profilePictureUrl, ...payload } = state.profile; - if (payload.conditions.indexOf(condition) < -1) return; - - payload.conditions.push(condition); - - const updatedRecord = await UserDetailsUtils.updateUserDetailsRecord( - agent, - state.record, - payload, - ); - if (!updatedRecord) return false; - const profile = await updatedRecord.data.json(); - - set({ - state: { - isSignedIn: true, - record: updatedRecord, - profile: { - ...profile, - id: updatedRecord.id, - profilePictureUrl, - }, - }, - }); + return true + }, + addCondition: async (agent: Agent, condition: string) => { + const state = get().state + if (!state.isSignedIn) return false + + const { profilePictureUrl, ...payload } = state.profile + if (payload.conditions.indexOf(condition) < -1) return + + payload.conditions.push(condition) + + const updatedRecord = await UserDetailsUtils.updateUserDetailsRecord(agent, state.record, payload) + if (!updatedRecord) return false + const profile = await updatedRecord.data.json() + + set({ + state: { + isSignedIn: true, + record: updatedRecord, + profile: { + ...profile, + id: updatedRecord.id, + profilePictureUrl + } + } + }) - return updatedRecord; - }, - signUp: async (agent: Agent, payload: SignUpPayload) => { - const profile = await UserDetailsUtils.createUserDetailsRecord(agent, { - ...payload, - conditions: [], - did: agent.did, - }); - if (!profile) return false; + return updatedRecord + }, + signUp: async (agent: Agent, payload: SignUpPayload) => { + const profile = await UserDetailsUtils.createUserDetailsRecord(agent, { ...payload, conditions: [], did: agent.did }) + if (!profile) return false - return profile; - }, - }), - ), -); + return profile + } + })) +) From 421449b24ccbd3a4feffa8481cd43dcaff3d8327 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Mon, 8 Jan 2024 02:08:04 +0000 Subject: [PATCH 100/120] added code to sync profile updates with remote dwn --- tauri-app/src/pages/connect.tsx | 1 - tauri-app/src/utils/user.ts | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tauri-app/src/pages/connect.tsx b/tauri-app/src/pages/connect.tsx index 5bd976a..d3dcc6b 100644 --- a/tauri-app/src/pages/connect.tsx +++ b/tauri-app/src/pages/connect.tsx @@ -12,7 +12,6 @@ const fetchProfilesWithCondition = async (agent: Agent, condition: string) => { const matchingProfiles = [] for (const record of profileRecords) { const profile: UserDetailsProtocolRecord.Details = await record.data.json() - console.log(profile) if (profile.conditions.indexOf(condition) > -1 && profile.did !== agent.did) { matchingProfiles.push(profile) diff --git a/tauri-app/src/utils/user.ts b/tauri-app/src/utils/user.ts index 73b8238..4c0c46c 100644 --- a/tauri-app/src/utils/user.ts +++ b/tauri-app/src/utils/user.ts @@ -172,6 +172,11 @@ async function updateUserDetailsRecord(agent: Agent, idOrRecord: string | Web5Re return false } + const { status: protocolDwnSyncStatus } = await record.send(UserDetailsProtocolDID) + if (protocolDwnSyncStatus.code !== 202) { + console.log("Failed to sync document record update with protocol remote DWN:", protocolDwnSyncStatus) + } + return record } From 5c3204db28d5f8d7613c9bf4a453df0a356d27f9 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Mon, 8 Jan 2024 02:08:24 +0000 Subject: [PATCH 101/120] updated gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a873b84..b5fa95f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ pnpm-lock.yaml *.tsbuildinfo -utils/ +server/ From 0c4eef1c047b81f9d98f597153ff7abe26abb982 Mon Sep 17 00:00:00 2001 From: coder12git Date: Mon, 8 Jan 2024 09:53:27 +0530 Subject: [PATCH 102/120] add chat feature Signed-off-by: coder12git --- tauri-app/src/App.tsx | 2 + tauri-app/src/pages/chat.tsx | 485 ++++++++++++++++------------------- 2 files changed, 220 insertions(+), 267 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index ced8e50..14be1c1 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -9,6 +9,7 @@ import SharedLayout from "./pages/SharedLayout/"; import Records from "./pages/Records"; import Chat from "./pages/Chat/"; import { Toaster } from "react-hot-toast"; +import ChatConnect from "./pages/chat"; const router = createHashRouter([ { @@ -30,6 +31,7 @@ const router = createHashRouter([ }, { path: "/contact", element: }, { path: "/chat", element: }, + { path: "/chatConnect", element: }, ], }, ]); diff --git a/tauri-app/src/pages/chat.tsx b/tauri-app/src/pages/chat.tsx index 7ac018d..f886fe0 100644 --- a/tauri-app/src/pages/chat.tsx +++ b/tauri-app/src/pages/chat.tsx @@ -1,282 +1,233 @@ -import { Web5 } from "@web5/api"; -import { useState, useEffect } from "react"; - -export default function Home() { - - const [web5, setWeb5] = useState(null); - const [myDid, setMyDid] = useState(null); - const [activeRecipient, setActiveRecipient] = useState(null); - - const [noteValue, setNoteValue] = useState(""); - const [errorMessage, setErrorMessage] = useState(''); - const [recipientDid, setRecipientDid] = useState(""); - - const [didCopied, setDidCopied] = useState(false); - const [showNewChatInput, setShowNewChatInput] = useState(false); - - const [allDings, setAllDings] = useState([]); - - const sortedDings = allDings.sort( - //@ts-ignore - (a, b) => new Date(a.timestampWritten) - new Date(b.timestampWritten) - ); - - const groupedDings = allDings.reduce((acc, ding) => { - //@ts-ignore - const recipient = ding.sender === myDid ? ding.recipient : ding.sender; - //@ts-ignore - if (!acc[recipient]) acc[recipient] = []; - //@ts-ignore - acc[recipient].push(ding); - return acc; - }, {}); - - useEffect(() => { - const initWeb5 = async () => { - const { web5, did } = await Web5.connect(); - //@ts-ignore - setWeb5(web5); +// Import necessary libraries and modules +import React, { useEffect } from 'react'; +import { Web5 } from "@web5/api/browser"; +import { dingerProtocolDefinition } from '@/stores/useWeb5Store'; + +// Define your dingerProtocolDefinition object + +const ChatConnect: React.FC = () => { + useEffect(() => { + const initDinger = async () => { + const copyDidElement = document.querySelector('#copy-did'); + const dingForm = document.querySelector('#ding-form'); + const dingErrorElement = document.querySelector('#ding-error'); + const dingProgressElement = document.querySelector('#ding-progress'); + const dingedList = document.querySelector('#dinged-list'); + const dingedByList = document.querySelector('#dinged-by-list'); + + const { web5, did: myDid } = await Web5.connect(); + await configureProtocol(web5); + + setInterval(async () => { + await renderDings(web5, myDid, dingedList, dingedByList); + }, 2000); + + //@ts-ignore + copyDidElement.addEventListener('click', async () => { + try { + await navigator.clipboard.writeText(myDid); + } catch (err) { //@ts-ignore - setMyDid(did); - - if (web5 && did) { - await configureProtocol(web5, did); - await fetchDings(web5, did); - } - }; - initWeb5(); - }, []); - - useEffect(() => { - if (!web5 || !myDid) return; - const intervalId = setInterval(async () => { - await fetchDings(web5, myDid); - }, 2000); - - return () => clearInterval(intervalId); - }, [web5, myDid]); - - const createProtocolDefinition = () => { - const dingerProtocolDefinition = { - protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", - published: true, - types: { - ding: { - schema: "https://blackgirlbytes.dev/ding", - dataFormats: ["application/json"], - }, - }, - structure: { - ding: { - $actions: [ - { who: "anyone", can: "write" }, - { who: "author", of: "ding", can: "read" }, - { who: "recipient", of: "ding", can: "read" }, - ], - }, - }, - }; - return dingerProtocolDefinition; - }; - + alert('Failed to copy DID: ', err); + } + }); + + //@ts-ignore + dingForm.addEventListener('submit', async (event) => { + // ... (your existing form submission logic) + event.preventDefault(); + +//@ts-ignore + dingErrorElement.textContent = ''; + //@ts-ignore + dingProgressElement.textContent = ''; +//@ts-ignore + const did = document.querySelector('#did').value; + //@ts-ignore + const note = document.querySelector('#note').value; + + if (did.length === 0) { //@ts-ignore - const queryForProtocol = async (web5) => { - return await web5.dwn.protocols.query({ - message: { - filter: { - protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", - }, - }, - }); - }; + dingErrorElement.textContent = 'DID required'; + return; + } + const ding = { dinger: myDid }; + if (note) { //@ts-ignore - const installProtocolLocally = async (web5, protocolDefinition) => { - return await web5.dwn.protocols.configure({ - message: { - definition: protocolDefinition, - }, - }); - }; + ding.note = note; + } +//@ts-ignore + dingProgressElement.textContent = 'writing ding to local DWN...'; + + try { + const { record, status } = await web5.dwn.records.write({ + data: ding, + message: { + protocol: dingerProtocolDefinition.protocol, + protocolPath: 'ding', + schema: 'ding', + recipient: did + } + }); + + if (status.code !== 202) { + //@ts-ignore + dingErrorElement.textContent = `${status.code} - ${status.detail}`; + return; + } + const shortenedDid = did.substr(0, 22); //@ts-ignore - const configureProtocol = async (web5, did) => { - const protocolDefinition = await createProtocolDefinition(); - - const { protocols: localProtocol, status: localProtocolStatus } = - await queryForProtocol(web5); - console.log({ localProtocol, localProtocolStatus }); - if (localProtocolStatus.code !== 200 || localProtocol.length === 0) { - - const { protocol, status } = await installProtocolLocally(web5, protocolDefinition); - console.log("Protocol installed locally", protocol, status); - - const { status: configureRemoteStatus } = await protocol.send(did); - console.log("Did the protocol install on the remote DWN?", configureRemoteStatus); - } else { - console.log("Protocol already installed"); - } - }; - - - const constructDing = () => { - const currentDate = new Date().toLocaleDateString(); - const currentTime = new Date().toLocaleTimeString(); - const ding = { - sender: myDid, - note: noteValue, - recipient: recipientDid, - timestampWritten: `${currentDate} ${currentTime}`, - }; - return ding; - }; + dingProgressElement.textContent = `Ding written locally! Dinging ${shortenedDid}...`; +//@ts-ignore + const { status: sendStatus } = await record.send(did); + console.log('send status', sendStatus); - //@ts-ignore - const writeToDwn = async (ding) => { + if (sendStatus.code !== 202) { //@ts-ignore - const { record } = await web5.dwn.records.write({ - data: ding, - message: { - protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", - protocolPath: "ding", - schema: "https://blackgirlbytes.dev/ding", - recipient: recipientDid, - }, - }); - return record; - }; - + dingErrorElement.textContent = `${sendStatus.code} - ${sendStatus.detail}`; + return; + } +//@ts-ignore + dingProgressElement.textContent = `Dinged ${shortenedDid}!`; + } catch (e) { //@ts-ignore - const sendRecord = async (record) => { - return await record.send(recipientDid); + dingErrorElement.textContent = e.message; + return; + } + }); }; - //@ts-ignore - const handleSubmit = async (e) => { - e.preventDefault(); - - if (!noteValue.trim()) { - setErrorMessage('Please type a message before sending.'); - return; - } - - const ding = constructDing(); - const record = await writeToDwn(ding); - const { status } = await sendRecord(record); - - console.log("Send record status", status); - await fetchDings(web5, myDid); - setNoteValue(""); - }; - - const handleCopyDid = async () => { - if (myDid) { - try { - await navigator.clipboard.writeText(myDid); - setDidCopied(true); - console.log("DID copied to clipboard"); + initDinger(); + }, []); - setTimeout(() => { - setDidCopied(false); - }, 3000); - } catch (err) { - console.log("Failed to copy DID: " + err); - } + const configureProtocol = async (web5: any) => { + // ... (your existing configureProtocol function) + const { protocols, status } = await web5.dwn.protocols.query({ + message: { + filter: { + protocol: 'https://dinger.app/protocol' } - }; - - //@ts-ignore - const fetchSentMessages = async (web5, did) => { - const response = await web5.dwn.records.query({ - message: { - filter: { - protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", - }, - }, - }); - - if (response.status.code === 200) { - const sentDings = await Promise.all( - //@ts-ignore - response.records.map(async (record) => { - const data = await record.data.json(); - return data; - }) - ); - console.log(sentDings, "I sent these dings"); - return sentDings; - } else { - console.log("error", response.status); + } + }); + + if (status.code !== 200) { + alert('Failed to query protocols. check console'); + console.error('Failed to query protocols', status); + + return; + } + + // protocol already exists + if (protocols.length > 0) { + console.log('protocol already exists'); + return; + } + + // create protocol + const { status: configureStatus } = await web5.dwn.protocols.configure({ + message: { + definition: dingerProtocolDefinition + } + }); + + console.log('configure protocol status', configureStatus); + }; + + const renderDings = async (web5: any, myDid: string, dingedList: any, dingedByList: any) => { + // ... (your existing renderDings function) + const { records, status } = await web5.dwn.records.query({ + message: { + filter: { + protocol: dingerProtocolDefinition.protocol } - }; - - //@ts-ignore - const fetchReceivedMessages = async (web5, did) => { - const response = await web5.dwn.records.query({ - from: did, - message: { - filter: { - protocol: "https://blackgirlbytes.dev/dinger-chat-protocol", - schema: "https://blackgirlbytes.dev/ding", - }, - }, + } + }); + + if (status.code !== 200) { + alert('Failed to query for dings. check console'); + console.error('Failed to query dings', status); + } + + for (let record of records) { + const recordExists = document.getElementById(record.id); + if (recordExists) { + continue; + } + + const { dinger, note } = await record.data.json(); + if (dinger === myDid) { + const shortenedDid = record.recipient.substr(0, 22); + const formattedDing = `[${new Date(record.dateCreated).toLocaleString()}] ${shortenedDid}... - ${note || ''}`; + + const dingElement = document.createElement('li'); + dingElement.id = record.id; + dingElement.textContent = formattedDing; + + const dingBackButton = document.createElement('button'); + dingBackButton.className = 'ding-back'; + dingBackButton.textContent = 'Ding agane'; + dingBackButton.dataset.toDing = record.recipient; + + dingBackButton.addEventListener('click', event => { + const didInput = document.querySelector('#did'); + //@ts-ignore + didInput.value = event.target.dataset.toDing; }); - - if (response.status.code === 200) { - const receivedDings = await Promise.all( - //@ts-ignore - response.records.map(async (record) => { - const data = await record.data.json(); - return data; - }) - ); - console.log(receivedDings, "I received these dings"); - return receivedDings; - } else { - console.log("error", response.status); - } - }; - - //@ts-ignore - const fetchDings = async (web5, did) => { - const sentMessages = await fetchSentMessages(web5, did); - const receivedMessages = await fetchReceivedMessages(web5, did); - const allMessages = [...(sentMessages || []), ...(receivedMessages || [])]; - //@ts-ignore - setAllDings(allMessages); - - }; - - const handleStartNewChat = () => { - setActiveRecipient(null); - setShowNewChatInput(true); - }; - - //@ts-ignore - const handleSetActiveRecipient = (recipient) => { - setRecipientDid(recipient); - setActiveRecipient(recipient); - setShowNewChatInput(false); - }; - - const handleConfirmNewChat = () => { - //@ts-ignore - setActiveRecipient(recipientDid); - //@ts-ignore - setActiveRecipient(recipientDid); - setShowNewChatInput(false); - //@ts-ignore - if (!groupedDings[recipientDid]) { - //@ts-ignore - groupedDings[recipientDid] = []; - } - }; - - return ( -
-

{myDid}

- - -
- ); -} \ No newline at end of file + + dingElement.appendChild(dingBackButton); + dingedList.appendChild(dingElement); + } else { + const shortenedDid = dinger.substr(0, 22); + const formattedDing = `[${new Date(record.dateCreated).toLocaleString()}] ${shortenedDid}... - ${note || ''}`; + + const dingElement = document.createElement('li'); + dingElement.id = record.id; + dingElement.textContent = formattedDing; + + const dingBackButton = document.createElement('button'); + dingBackButton.className = 'ding-back'; + dingBackButton.textContent = 'Ding Back'; + dingBackButton.dataset.toDing = dinger; + + dingBackButton.addEventListener('click', event => { + const didInput = document.querySelector('#did'); + //@ts-ignore + didInput.value = event.target.dataset.toDing; + }); + + dingElement.appendChild(dingBackButton); + dingedByList.appendChild(dingElement); + } + } + + }; + + return ( +
+ +
+

+ +
+ +
+ + +
+ +

You Dinged:

+
    + {/* List items will be added here dynamically */} +
+ +

You were Dinged by:

+
    + {/* List items will be added here dynamically */} +
+
+ ); +}; + +export default ChatConnect; From adf3eeca6884bcccd9f24cc91707d26be68007d6 Mon Sep 17 00:00:00 2001 From: coder12git Date: Mon, 8 Jan 2024 10:18:23 +0530 Subject: [PATCH 103/120] fixed err Signed-off-by: coder12git --- tauri-app/src/components/MobileChat/index.tsx | 2 +- tauri-app/src/pages/Chat/index.tsx | 9 +++- tauri-app/src/pages/chat.tsx | 41 +++++++++++++++++-- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/tauri-app/src/components/MobileChat/index.tsx b/tauri-app/src/components/MobileChat/index.tsx index b462dc6..617b14e 100644 --- a/tauri-app/src/components/MobileChat/index.tsx +++ b/tauri-app/src/components/MobileChat/index.tsx @@ -15,7 +15,7 @@ const Message: FC = ({ message, isLeft }) => {
); }; - +//@ts-ignore const index: FC = ({ setHideChat, hideChat }) => { return (
diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index 307e28b..eb2f26d 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -47,13 +47,16 @@ const index = () => { friends={45} /> {hideChat && (
- +
)}
@@ -71,7 +74,9 @@ const index = () => { cover_pic={"/pic.jpg"} friends={45} /> - +
diff --git a/tauri-app/src/pages/chat.tsx b/tauri-app/src/pages/chat.tsx index f886fe0..010a4bc 100644 --- a/tauri-app/src/pages/chat.tsx +++ b/tauri-app/src/pages/chat.tsx @@ -2,6 +2,7 @@ import React, { useEffect } from 'react'; import { Web5 } from "@web5/api/browser"; import { dingerProtocolDefinition } from '@/stores/useWeb5Store'; +import '../components/Chat/index.css'; // Define your dingerProtocolDefinition object @@ -167,7 +168,7 @@ const ChatConnect: React.FC = () => { const dingBackButton = document.createElement('button'); dingBackButton.className = 'ding-back'; - dingBackButton.textContent = 'Ding agane'; + // dingBackButton.textContent = 'Ding agane'; dingBackButton.dataset.toDing = record.recipient; dingBackButton.addEventListener('click', event => { @@ -188,7 +189,7 @@ const ChatConnect: React.FC = () => { const dingBackButton = document.createElement('button'); dingBackButton.className = 'ding-back'; - dingBackButton.textContent = 'Ding Back'; + // dingBackButton.textContent = 'Ding Back'; dingBackButton.dataset.toDing = dinger; dingBackButton.addEventListener('click', event => { @@ -211,9 +212,9 @@ const ChatConnect: React.FC = () => {


- +
- + @@ -231,3 +232,35 @@ const ChatConnect: React.FC = () => { }; export default ChatConnect; + + +interface MessageProp { + message: string; + isLeft: boolean; + } + //@ts-ignore + const Message: FC = ({ message, isLeft }) => { + return ( +
+
+

{message}

+
+
+ ); + }; + //@ts-ignore + export const index: FC = () => { + return ( +
+
+
+
+ + +
+
+ ); + }; + From 63e97d3a73d0870ab7c8b964ec1e995dcec964d8 Mon Sep 17 00:00:00 2001 From: coder12git Date: Mon, 8 Jan 2024 10:31:26 +0530 Subject: [PATCH 104/120] remove text Signed-off-by: coder12git --- tauri-app/src/pages/chat.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/pages/chat.tsx b/tauri-app/src/pages/chat.tsx index 010a4bc..41b8929 100644 --- a/tauri-app/src/pages/chat.tsx +++ b/tauri-app/src/pages/chat.tsx @@ -80,7 +80,7 @@ const ChatConnect: React.FC = () => { const shortenedDid = did.substr(0, 22); //@ts-ignore - dingProgressElement.textContent = `Ding written locally! Dinging ${shortenedDid}...`; + dingProgressElement.textContent = `Ding written! Dinging ${shortenedDid}...`; //@ts-ignore const { status: sendStatus } = await record.send(did); console.log('send status', sendStatus); From 3d76a1d0857f8a829e7a6418796692e880076aa2 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 15:36:01 +0100 Subject: [PATCH 105/120] minor.feature added --- tauri-app/src/App.tsx | 11 ++--- tauri-app/src/components/Navbar/index.css | 1 + tauri-app/src/components/Navbar/index.tsx | 40 +++++++++++++++---- .../src/components/UserFriendList/index.tsx | 2 +- .../components/UserMobileFriendList/index.tsx | 2 +- tauri-app/src/hooks/useCopy.tsx | 0 6 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 tauri-app/src/hooks/useCopy.tsx diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 14be1c1..f5fabe9 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -19,15 +19,12 @@ const router = createHashRouter([ { path: "/", element: }, { path: "/records", - element: ( - - ), + element: , }, { path: "/connect", element: }, { - path: "/remedies", element: ( - - ) + path: "/remedies", + element: , }, { path: "/contact", element: }, { path: "/chat", element: }, @@ -48,7 +45,7 @@ function App() { return ( <> <> - {web5 ? :
Connecting...
} + {true ? :
Connecting...
} diff --git a/tauri-app/src/components/Navbar/index.css b/tauri-app/src/components/Navbar/index.css index 0227c4f..50ace42 100644 --- a/tauri-app/src/components/Navbar/index.css +++ b/tauri-app/src/components/Navbar/index.css @@ -133,6 +133,7 @@ outline: none; padding: 8px 4px; margin: 14px 0px; + margin-right: 8px; } @media (max-width: 750px) { diff --git a/tauri-app/src/components/Navbar/index.tsx b/tauri-app/src/components/Navbar/index.tsx index ea02e2a..4ea6ab3 100644 --- a/tauri-app/src/components/Navbar/index.tsx +++ b/tauri-app/src/components/Navbar/index.tsx @@ -4,7 +4,7 @@ import { NavLink } from "react-router-dom"; import useWeb5Store from "@/stores/useWeb5Store.ts"; import { Agent } from "../Auth/types"; import { useProfile } from "@/stores/profile.ts"; -import { useState } from "react"; +import { useState, useRef } from "react"; const SignedInBtn = () => { const { profile, signOut } = useProfile((store) => ({ @@ -12,6 +12,8 @@ const SignedInBtn = () => { signOut: store.signOut, })); const [showSignOutUtils, setShowSignOutUtils] = useState(false); + const [isCopied, setIsCopied] = useState(false); + const copyRef = useRef(null); return ( <> @@ -19,12 +21,30 @@ const SignedInBtn = () => {
DID: - + + {!isCopied ? ( + { + copyRef.current.select(); + document.execCommand("copy"); + setIsCopied(true); + }} + className="fa-regular fa-copy" + > + ) : ( + + )}
@@ -34,14 +54,20 @@ const SignedInBtn = () => { - ) -} + ); +}; const index = () => { const { web5, did } = useWeb5Store((state) => ({ diff --git a/tauri-app/src/components/UserFriendList/index.tsx b/tauri-app/src/components/UserFriendList/index.tsx index 210ade9..b229d75 100644 --- a/tauri-app/src/components/UserFriendList/index.tsx +++ b/tauri-app/src/components/UserFriendList/index.tsx @@ -22,7 +22,7 @@ const FriendTag: FC = ({

{friendName.slice(0, 6) + "..."}

= ({

{friendName.slice(0, 20) + "..."}

Date: Mon, 8 Jan 2024 20:53:26 +0530 Subject: [PATCH 106/120] added chat to frontend Signed-off-by: coder12git --- tauri-app/src/components/Chat/index.tsx | 277 ++++++++++++++++++++++-- tauri-app/src/pages/Home/index.tsx | 5 - tauri-app/src/pages/chat.tsx | 51 +---- 3 files changed, 269 insertions(+), 64 deletions(-) diff --git a/tauri-app/src/components/Chat/index.tsx b/tauri-app/src/components/Chat/index.tsx index 4bc8898..64148bd 100644 --- a/tauri-app/src/components/Chat/index.tsx +++ b/tauri-app/src/components/Chat/index.tsx @@ -1,22 +1,231 @@ import "./index.css"; -import React, { FC } from "react"; +import React, { useEffect, FC } from "react"; -interface MessageProp { - message: string; - isLeft: boolean; -} +// Import necessary libraries and modules +// import React, { useEffect } from 'react'; +import { Web5 } from "@web5/api/browser"; +import { dingerProtocolDefinition } from '@/stores/useWeb5Store'; +// import Chat from '../components/Chat'; -const Message: FC = ({ message, isLeft }) => { - return ( -
-
-

{message}

+// Define your dingerProtocolDefinition object + +//@ts-ignore +const index: React.FC = () => { + useEffect(() => { + const initDinger = async () => { + // const copyDidElement = document.querySelector('#copy-did'); + const dingForm = document.querySelector('#ding-form'); + const dingErrorElement = document.querySelector('#ding-error'); + const dingProgressElement = document.querySelector('#ding-progress'); + const dingedList = document.querySelector('#dinged-list'); + const dingedByList = document.querySelector('#dinged-by-list'); + + const { web5, did: myDid } = await Web5.connect(); + await configureProtocol(web5); + + setInterval(async () => { + await renderDings(web5, myDid, dingedList, dingedByList); + }, 2000); + + //@ts-ignore + // copyDidElement.addEventListener('click', async () => { + // try { + // await navigator.clipboard.writeText(myDid); + // } catch (err) { + // //@ts-ignore + // alert('Failed to copy DID: ', err); + // } + // }); + + //@ts-ignore + dingForm.addEventListener('submit', async (event) => { + // ... (your existing form submission logic) + event.preventDefault(); + + //@ts-ignore + dingErrorElement.textContent = ''; + //@ts-ignore + dingProgressElement.textContent = ''; + //@ts-ignore + const did = document.querySelector('#did').value; + //@ts-ignore + const note = document.querySelector('#note').value; + + if (did.length === 0) { + //@ts-ignore + dingErrorElement.textContent = 'DID required'; + return; + } + + const ding = { dinger: myDid }; + if (note) { + //@ts-ignore + ding.note = note; + } + //@ts-ignore + dingProgressElement.textContent = 'writing ding to local DWN...'; + + try { + const { record, status } = await web5.dwn.records.write({ + data: ding, + message: { + protocol: dingerProtocolDefinition.protocol, + protocolPath: 'ding', + schema: 'ding', + recipient: did + } + }); + + if (status.code !== 202) { + //@ts-ignore + dingErrorElement.textContent = `${status.code} - ${status.detail}`; + return; + } + + const shortenedDid = did.substr(0, 22); + //@ts-ignore + dingProgressElement.textContent = `Ding written! Dinging ${shortenedDid}...`; + //@ts-ignore + const { status: sendStatus } = await record.send(did); + console.log('send status', sendStatus); + + if (sendStatus.code !== 202) { + //@ts-ignore + dingErrorElement.textContent = `${sendStatus.code} - ${sendStatus.detail}`; + return; + } + //@ts-ignore + dingProgressElement.textContent = `Dinged ${shortenedDid}!`; + } catch (e) { + //@ts-ignore + dingErrorElement.textContent = e.message; + return; + } + }); + }; + + initDinger(); + }, []); + + const configureProtocol = async (web5: any) => { + // ... (your existing configureProtocol function) + const { protocols, status } = await web5.dwn.protocols.query({ + message: { + filter: { + protocol: 'https://dinger.app/protocol' + } + } + }); + + if (status.code !== 200) { + alert('Failed to query protocols. check console'); + console.error('Failed to query protocols', status); + + return; + } + + // protocol already exists + if (protocols.length > 0) { + console.log('protocol already exists'); + return; + } + + // create protocol + const { status: configureStatus } = await web5.dwn.protocols.configure({ + message: { + definition: dingerProtocolDefinition + } + }); + + console.log('configure protocol status', configureStatus); + }; + + const renderDings = async (web5: any, myDid: string, dingedList: any, dingedByList: any) => { + // ... (your existing renderDings function) + const { records, status } = await web5.dwn.records.query({ + message: { + filter: { + protocol: dingerProtocolDefinition.protocol + } + } + }); + + if (status.code !== 200) { + alert('Failed to query for dings. check console'); + console.error('Failed to query dings', status); + } + + for (let record of records) { + const recordExists = document.getElementById(record.id); + if (recordExists) { + continue; + } + + const { dinger, note } = await record.data.json(); + if (dinger === myDid) { + const shortenedDid = record.recipient.substr(0, 22); + const formattedDing = `[${new Date(record.dateCreated).toLocaleString()}] ${shortenedDid}... - ${note || ''}`; + + const dingElement = document.createElement('li'); + dingElement.id = record.id; + dingElement.textContent = formattedDing; + + const dingBackButton = document.createElement('button'); + dingBackButton.className = 'ding-back'; + // dingBackButton.textContent = 'Ding agane'; + dingBackButton.dataset.toDing = record.recipient; + + dingBackButton.addEventListener('click', event => { + const didInput = document.querySelector('#did'); + //@ts-ignore + didInput.value = event.target.dataset.toDing; + }); + + dingElement.appendChild(dingBackButton); + dingedList.appendChild(dingElement); + } else { + const shortenedDid = dinger.substr(0, 22); + const formattedDing = `[${new Date(record.dateCreated).toLocaleString()}] ${shortenedDid}... - ${note || ''}`; + + const dingElement = document.createElement('li'); + dingElement.id = record.id; + dingElement.textContent = formattedDing; + + const dingBackButton = document.createElement('button'); + dingBackButton.className = 'ding-back'; + // dingBackButton.textContent = 'Ding Back'; + dingBackButton.dataset.toDing = dinger; + + dingBackButton.addEventListener('click', event => { + const didInput = document.querySelector('#did'); + //@ts-ignore + didInput.value = event.target.dataset.toDing; + }); + + dingElement.appendChild(dingBackButton); + dingedByList.appendChild(dingElement); + } + } + + }; + + + interface MessageProp { + message: string; + isLeft: boolean; + } + + const Message: FC = ({ message, isLeft }) => { + return ( +
+
+

{message}

+
-
- ); -}; + ); + }; -const index: FC = () => { + // const index: FC = () => { return (
@@ -46,13 +255,45 @@ const index: FC = () => { } isLeft={false} /> + + {/*

You Dinged:

*/} +
    + {/* List items will be added here dynamically */} +
+ + {/*

You were Dinged by:

*/} +
    + {/* List items will be added here dynamically */} +
- - + {/* */} +
{ + e.preventDefault(); + }} + id="ding-form"> +

+ {/*
*/} + + + {/*
*/} + + +
+ + {/*

You Dinged:

+
    */} + {/* List items will be added here dynamically */} + {/*
+ +

You were Dinged by:

*/} + {/*
    */} + {/* List items will be added here dynamically */} + {/*
*/}
); }; diff --git a/tauri-app/src/pages/Home/index.tsx b/tauri-app/src/pages/Home/index.tsx index 21c534a..467bf42 100644 --- a/tauri-app/src/pages/Home/index.tsx +++ b/tauri-app/src/pages/Home/index.tsx @@ -50,11 +50,6 @@ export default function HomePage() { stored making it a breeze to safely store medical data and records.

- - -
diff --git a/tauri-app/src/pages/chat.tsx b/tauri-app/src/pages/chat.tsx index 41b8929..0703ca4 100644 --- a/tauri-app/src/pages/chat.tsx +++ b/tauri-app/src/pages/chat.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from 'react'; import { Web5 } from "@web5/api/browser"; import { dingerProtocolDefinition } from '@/stores/useWeb5Store'; -import '../components/Chat/index.css'; +import Chat from '../components/Chat'; // Define your dingerProtocolDefinition object @@ -207,7 +207,8 @@ const ChatConnect: React.FC = () => { return (
- + + {/*

@@ -216,51 +217,19 @@ const ChatConnect: React.FC = () => {
-
+ */} -

You Dinged:

-
    + {/*

    You Dinged:

    +
      */} {/* List items will be added here dynamically */} -
    + {/*

You were Dinged by:

-
    +
      */} {/* List items will be added here dynamically */} -
    + {/*
*/}
); }; -export default ChatConnect; - - -interface MessageProp { - message: string; - isLeft: boolean; - } - //@ts-ignore - const Message: FC = ({ message, isLeft }) => { - return ( -
-
-

{message}

-
-
- ); - }; - //@ts-ignore - export const index: FC = () => { - return ( -
-
-
-
- - -
-
- ); - }; - +export default ChatConnect; \ No newline at end of file From 4a5b04d1e5f83752d5096846693d156a44c4705b Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 16:58:09 +0100 Subject: [PATCH 107/120] features added --- .../src/components/UserFriendList/index.css | 19 ++++++++++ .../src/components/UserFriendList/index.tsx | 36 +++++++++++++++++-- .../components/UserMobileFriendList/index.css | 24 ++++++++++--- .../components/UserMobileFriendList/index.tsx | 31 ++++++++++++++-- tauri-app/src/pages/Chat/index.tsx | 7 ++-- tauri-app/src/pages/Home/index.tsx | 7 +--- tauri-app/src/pages/Records/index.css | 28 ++------------- tauri-app/src/pages/Records/index.tsx | 1 - tauri-app/src/pages/Remedies/index.tsx | 1 - 9 files changed, 108 insertions(+), 46 deletions(-) diff --git a/tauri-app/src/components/UserFriendList/index.css b/tauri-app/src/components/UserFriendList/index.css index 9fe13c0..7cd7e00 100644 --- a/tauri-app/src/components/UserFriendList/index.css +++ b/tauri-app/src/components/UserFriendList/index.css @@ -65,8 +65,27 @@ text-align: center; } +.d-did-container { + display: flex; + justify-content: center; + align-items: center; +} + +.friend-tag-container input { + background: var(--color-light-grey); + border-radius: 5px; + border: none; + font-family: "Roboto"; + outline: none; + padding: 8px 4px; + margin: 14px 0px; + margin-right: 8px; + width: 40px; +} + .friend-main-list-container { overflow-y: scroll; + overflow-x: hidden; height: 250px; margin: 15px 0; padding: 5px; diff --git a/tauri-app/src/components/UserFriendList/index.tsx b/tauri-app/src/components/UserFriendList/index.tsx index b229d75..02676a3 100644 --- a/tauri-app/src/components/UserFriendList/index.tsx +++ b/tauri-app/src/components/UserFriendList/index.tsx @@ -1,11 +1,12 @@ import "./index.css"; -import React, { FC, useState } from "react"; +import React, { FC, useState, useRef } from "react"; interface FriendTagProp { friendProfileImg: string; friendName: string; isFriendOnline: boolean; newChat?: number; + did?: string; } const FriendTag: FC = ({ @@ -13,14 +14,42 @@ const FriendTag: FC = ({ friendName, isFriendOnline, newChat, + did, }) => { + const [isCopied, setIsCopied] = useState(false); + + const didRef = useRef(null); + return (
{newChat && {newChat}}
-

{friendName.slice(0, 6) + "..."}

+
+

{friendName.slice(0, 6) + "..."}

+
+ + + {!isCopied ? ( + { + e.stopPropagation(); + didRef.current.select(); + document.execCommand("copy"); + setIsCopied(true); + }} + className="fa-regular fa-copy" + > + ) : ( + + )} +
+
{ return (
-
+

Friends

@@ -54,6 +83,7 @@ const index: FC = ({ friendList, setHideChat, hideChat }) => { isFriendOnline={friend.isOnline} friendName={friend.username} newChat={friend.newChat} + did={friend.did} />
diff --git a/tauri-app/src/components/UserMobileFriendList/index.css b/tauri-app/src/components/UserMobileFriendList/index.css index 68bbd6e..5da9c63 100644 --- a/tauri-app/src/components/UserMobileFriendList/index.css +++ b/tauri-app/src/components/UserMobileFriendList/index.css @@ -26,18 +26,34 @@ font-family: "Roboto"; background: var(--color-red); border-radius: 3px; - padding: 2px 3px; + padding: 2px 4px; color: var(--color-white); border: 2px solid var(--color-white); border-radius: 8px; - font-size: 8px; + font-size: 10px; position: relative; - left: -15px; - top: -4px; width: 40px; + top: -25px; height: 40px; } +.m-friend-tag-container input { + background: var(--color-white); + border-radius: 5px; + border: none; + font-family: "Roboto"; + outline: none; + padding: 8px 4px; + margin: 14px 0px; + margin-right: 8px; +} + +.m-did-container { + display: flex; + justify-content: center; + align-items: center; +} + .m-friends-list-container hr { width: 80%; margin: 0 auto; diff --git a/tauri-app/src/components/UserMobileFriendList/index.tsx b/tauri-app/src/components/UserMobileFriendList/index.tsx index 39dc86f..7de5ce9 100644 --- a/tauri-app/src/components/UserMobileFriendList/index.tsx +++ b/tauri-app/src/components/UserMobileFriendList/index.tsx @@ -1,5 +1,5 @@ import "./index.css"; -import React, { FC, useState } from "react"; +import React, { FC, useState, useRef } from "react"; interface FriendTagProp { friendProfileImg: string; @@ -8,6 +8,7 @@ interface FriendTagProp { newChat?: number; setHideChat: () => void; hideChat: boolean; + didi?: string; } interface UserFriendListProp { @@ -21,7 +22,11 @@ const FriendTag: FC = ({ newChat, setHideChat, hideChat, + did, }) => { + const [isCopied, setIsCopied] = useState(false); + const didRef = useRef(null); + return (
setHideChat(!hideChat)} @@ -31,8 +36,29 @@ const FriendTag: FC = ({ {newChat && {newChat}}
-
+

{friendName.slice(0, 20) + "..."}

+
+ + + {!isCopied ? ( + { + e.stopPropagation(); + didRef.current.select(); + document.execCommand("copy"); + setIsCopied(true); + }} + className="fa-regular fa-copy" + > + ) : ( + + )} +
= ({ newChat={friend.newChat} setHideChat={setHideChat} hideChat={hideChat} + did={friend.did} /> ); diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index eb2f26d..04e3063 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -12,15 +12,16 @@ import { useEffect, useState } from "react"; const index = () => { const [friends, setFriends] = useState([ - { profile_pic: "/pg.jpg", username: "@scriptkidd", isOnline: false }, - { profile_pic: "/pg.jpg", username: "@nikki", isOnline: false, newChat: 1 }, + { profile_pic: "/pg.jpg", username: "@scriptkidd", isOnline: false ,did:"1020383*@(wppwsj)"}, + { profile_pic: "/pg.jpg", username: "@nikki", isOnline: false, newChat: 1,did:"apqpwpudrZpwpsAaap" }, { profile_pic: "/pm.jpg", username: "@gregidd", isOnline: true, newChat: 7, + did:"12340APDPDISavavagaAjd" }, - { profile_pic: "/pic.jpg", username: "@scdd", isOnline: false, newChat: 4 }, + { profile_pic: "/pic.jpg", username: "@scdd", isOnline: false, newChat: 4 ,did:"APSOWJEHDHaksosodoQPPE1O"}, ]); const [isMobile, setIsMobile] = useState(false); const [hideChat, setHideChat] = useState(false); diff --git a/tauri-app/src/pages/Home/index.tsx b/tauri-app/src/pages/Home/index.tsx index 21c534a..2f374bd 100644 --- a/tauri-app/src/pages/Home/index.tsx +++ b/tauri-app/src/pages/Home/index.tsx @@ -50,12 +50,7 @@ export default function HomePage() { stored making it a breeze to safely store medical data and records.

- - - -
+

A.I

diff --git a/tauri-app/src/pages/Records/index.css b/tauri-app/src/pages/Records/index.css index fc6c53d..8c0bd43 100644 --- a/tauri-app/src/pages/Records/index.css +++ b/tauri-app/src/pages/Records/index.css @@ -76,7 +76,6 @@ .connect-wallet-container { width: 300px; - height: 200px; background: var(--color-white); border-radius: 15px; padding: 18px 8px; @@ -87,31 +86,8 @@ font-family: "Roboto"; font-size: 25px; margin-top: 30px; -} - -.connect-wallet-container button { - padding: 8px 20px; - border-radius: 8px; - background: var(--color-green); - box-shadow: var(--box-shadow-green); - color: var(--color-white); - font-family: "Roboto"; - cursor: pointer; - font-weight: 800; - border: none; - min-width: 180px; - font-size: 25px; - text-align: center; - margin-top: 40px; - outline: none; -} - -.connect-wallet-container button i { - background: var(--color-white); - padding: 10px 12px; - border-radius: 50%; - color: var(--color-black); - margin-left: 10px; + color: var(--color-red); + margin: auto auto; } @media (max-width: 750px) { diff --git a/tauri-app/src/pages/Records/index.tsx b/tauri-app/src/pages/Records/index.tsx index 5d53c6f..3ef81dd 100644 --- a/tauri-app/src/pages/Records/index.tsx +++ b/tauri-app/src/pages/Records/index.tsx @@ -125,7 +125,6 @@ const index = () => { }} >

Unauthorized - Please Sign in

-
)} diff --git a/tauri-app/src/pages/Remedies/index.tsx b/tauri-app/src/pages/Remedies/index.tsx index f126edb..f70582a 100644 --- a/tauri-app/src/pages/Remedies/index.tsx +++ b/tauri-app/src/pages/Remedies/index.tsx @@ -230,7 +230,6 @@ const index = ({ save, formFunc, form, remediesData, docsWithImageUrls }) => { }} >

Unauthorized - Please Sign in

-
)} From 455d96c995f747dbe09efecf4fe7d9e8f8861499 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 17:02:52 +0100 Subject: [PATCH 108/120] fixed a minor typo --- tauri-app/src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index f5fabe9..9a6d57d 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -45,7 +45,7 @@ function App() { return ( <> <> - {true ? :
Connecting...
} + {web5 ? :
Connecting...
} From 78b7d13758bb2f9073058958f29b9a909cdca34d Mon Sep 17 00:00:00 2001 From: Adophilus Date: Mon, 8 Jan 2024 16:50:46 +0000 Subject: [PATCH 109/120] added profile guard to chat route --- tauri-app/src/App.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 9a6d57d..30924eb 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -10,6 +10,7 @@ import Records from "./pages/Records"; import Chat from "./pages/Chat/"; import { Toaster } from "react-hot-toast"; import ChatConnect from "./pages/chat"; +import ProfileGuard from "./components/Auth/Profile/Guard"; const router = createHashRouter([ { @@ -27,7 +28,7 @@ const router = createHashRouter([ element: , }, { path: "/contact", element: }, - { path: "/chat", element: }, + { path: "/chat", element: }, { path: "/chatConnect", element: }, ], }, From 43248891423ca6a2144bd72149bdb93c0df70631 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Mon, 8 Jan 2024 16:50:55 +0000 Subject: [PATCH 110/120] updated arguments to blob helper --- tauri-app/src/utils/blob.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tauri-app/src/utils/blob.ts b/tauri-app/src/utils/blob.ts index 67ea009..935c040 100644 --- a/tauri-app/src/utils/blob.ts +++ b/tauri-app/src/utils/blob.ts @@ -108,12 +108,12 @@ async function createBlobRecord(agent: Agent, payload: CreatePayload, remote?: b return record } -async function fetchBlobRecord(agent: Agent, filter: FilterObj) { +async function fetchBlobRecord(agent: Agent, filter: FilterObj, remote?: boolean) { const records = await fetchRecords(agent, { ...filter, protocolPath: "blob", schema: BlobProtocol.types.blob.schema, - }) + }, remote) if (!records || !records[0]) return false From 499f1964de53b184725503bcf7efa766f1394645 Mon Sep 17 00:00:00 2001 From: Adophilus Date: Mon, 8 Jan 2024 16:51:08 +0000 Subject: [PATCH 111/120] integrated the conntect feature to the chats integrated the connect feature to the chats --- .../src/components/UserFriendList/index.tsx | 7 +- tauri-app/src/pages/Chat/index.tsx | 140 ++++++++++++++---- 2 files changed, 112 insertions(+), 35 deletions(-) diff --git a/tauri-app/src/components/UserFriendList/index.tsx b/tauri-app/src/components/UserFriendList/index.tsx index 02676a3..05d80f7 100644 --- a/tauri-app/src/components/UserFriendList/index.tsx +++ b/tauri-app/src/components/UserFriendList/index.tsx @@ -1,3 +1,4 @@ +import { Friend } from "@/pages/Chat"; import "./index.css"; import React, { FC, useState, useRef } from "react"; @@ -68,7 +69,7 @@ interface UserFriendListProp { hideChat: boolean; } -const index: FC = ({ friendList, setHideChat, hideChat }) => { +const index: FC<{ friendList: Friend[]}> = ({ friendList, setHideChat, hideChat }) => { return (
@@ -79,10 +80,10 @@ const index: FC = ({ friendList, setHideChat, hideChat }) => { return ( <>
diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index 04e3063..e7e7e6d 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -9,23 +9,104 @@ import UserMobileFriendList from "../../components/UserMobileFriendList/"; import MobileChat from "../../components/MobileChat"; import { useEffect, useState } from "react"; +import { Agent } from "@/components/Auth/types"; +import UserDetailsUtils from "@/utils/user"; +import { Record as UserDetailsProtocolRecord } from "@/utils/protocols/user"; +import BlobUtils from "@/utils/blob"; +import { useProfile } from "@/stores/profile"; +import useWeb5Store from "@/stores/useWeb5Store"; + +const fetchProfilesWithConditions = async (agent: Agent, conditions: string[]) => { + const profileRecords = await UserDetailsUtils.fetchUserDetailsRecords(agent) + if (!profileRecords) + return [] + + const profilesWithRank = [] + for (const record of profileRecords) { + const profile: UserDetailsProtocolRecord.Details = await record.data.json() + + if (profile.did === agent.did) continue + + const profileWithRank = { + profile, + rank: 0 + } + + for (const condition of conditions) { + if (profile.conditions.indexOf(condition) > -1) { + profileWithRank.rank += 1 + } + } + + if (profileWithRank.rank === 0) continue + + profilesWithRank.push(profileWithRank) + } + + const sortedProfiles = profilesWithRank + .sort((a, b) => b.rank - a.rank) + .map((profileWithRank) => profileWithRank.profile) + + const matchingProfiles: (Omit & { profilePictureUrl: string })[] = [] + + for (const p of sortedProfiles) { + const { profilePictureId, ...profile } = p + const profilePictureRecord = await BlobUtils.fetchBlobRecord(agent, { recordId: profilePictureId }, true) + + const payload = { + ...profile, + profilePictureUrl: "" + } + + if (profilePictureRecord) { + const profilePicture = await profilePictureRecord.data.blob() + payload.profilePictureUrl = URL.createObjectURL(profilePicture) + } + + matchingProfiles.push(payload) + } + + return matchingProfiles +} + +export type Friend = Awaited>[number] & { + isOnline: boolean + username: string +} const index = () => { - const [friends, setFriends] = useState([ - { profile_pic: "/pg.jpg", username: "@scriptkidd", isOnline: false ,did:"1020383*@(wppwsj)"}, - { profile_pic: "/pg.jpg", username: "@nikki", isOnline: false, newChat: 1,did:"apqpwpudrZpwpsAaap" }, - { - profile_pic: "/pm.jpg", - username: "@gregidd", - isOnline: true, - newChat: 7, - did:"12340APDPDISavavagaAjd" - }, - { profile_pic: "/pic.jpg", username: "@scdd", isOnline: false, newChat: 4 ,did:"APSOWJEHDHaksosodoQPPE1O"}, + const [friends, setFriends] = useState([ + // { profile_pic: "/pg.jpg", username: "@scriptkidd", isOnline: false, did: "1020383*@(wppwsj)" }, + // { profile_pic: "/pg.jpg", username: "@nikki", isOnline: false, newChat: 1, did: "apqpwpudrZpwpsAaap" }, + // { + // profile_pic: "/pm.jpg", + // username: "@gregidd", + // isOnline: true, + // newChat: 7, + // did: "12340APDPDISavavagaAjd" + // }, + // { profile_pic: "/pic.jpg", username: "@scdd", isOnline: false, newChat: 4, did: "APSOWJEHDHaksosodoQPPE1O" }, ]); const [isMobile, setIsMobile] = useState(false); const [hideChat, setHideChat] = useState(false); + const profile = useProfile(store => store.state.profile!) + const { web5, did } = useWeb5Store(store => ({ web5: store.web5!, did: store.did! })) + + useEffect(() => { + const fetchProfiles = async () => { + const res = await fetchProfilesWithConditions({ web5, did }, profile.conditions) + const newFriends = res.map(profile => ({ + ...profile, + isOnline: true, + username: `${profile.firstName}${profile.lastName}` + })) + setFriends(newFriends) + } + + fetchProfiles() + }, [profile, web5, did]) + useEffect(() => { if (window.innerWidth < 750) { setIsMobile(true); @@ -39,25 +120,23 @@ const index = () => { return (
{hideChat && (
- +
)}
@@ -67,17 +146,14 @@ const index = () => {
- +
From e951d031e71f32698c9b76bac68fabed9053884a Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 22:08:08 +0100 Subject: [PATCH 112/120] done tho still need's work --- tauri-app/src/App.tsx | 2 +- .../src/components/FindFriends/index.css | 79 +++++++++++ .../src/components/FindFriends/index.tsx | 79 +++++++++++ .../src/components/FriendRequests/index.css | 127 ++++++++++++++++++ .../src/components/FriendRequests/index.tsx | 60 +++++++++ .../components/UserMobileProfile/index.tsx | 27 ++++ .../src/components/UserProfile/index.css | 55 ++++++++ .../src/components/UserProfile/index.tsx | 33 ++++- tauri-app/src/pages/Chat/index.tsx | 90 +++++++++++-- 9 files changed, 537 insertions(+), 15 deletions(-) create mode 100644 tauri-app/src/components/FindFriends/index.css create mode 100644 tauri-app/src/components/FindFriends/index.tsx create mode 100644 tauri-app/src/components/FriendRequests/index.css create mode 100644 tauri-app/src/components/FriendRequests/index.tsx diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 9a6d57d..f5fabe9 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -45,7 +45,7 @@ function App() { return ( <> <> - {web5 ? :
Connecting...
} + {true ? :
Connecting...
} diff --git a/tauri-app/src/components/FindFriends/index.css b/tauri-app/src/components/FindFriends/index.css new file mode 100644 index 0000000..1c3afee --- /dev/null +++ b/tauri-app/src/components/FindFriends/index.css @@ -0,0 +1,79 @@ +.find-friends-container { + width: 500px; + height: max-content; + min-height: 420px; + background: var(--color-white); + border-radius: 15px; + padding: 20px; +} + +.find-friends-container h3 { + font-family: "Pacifico"; +} + +.loading-container { + display: flex; + justify-content: center; + align-items: center; + flex-direction: center; + width: 480px; + height: max-content; + margin: auto auto; + min-height: 300px; + position: relative; +} + +.pluse-container { + width: 100px; + height: 100px; + background: var(--color-red); + box-shadow: var(--box-shadow-red); + border-radius: 50%; + font-size: 30px; + color: var(--color-white); + display: flex; + justify-content: center; + align-items: center; + position: relative; +} + +.g-pluse { + position: absolute; + width: 100px; + height: 100px; + background: var(--color-green); + border-radius: 50%; + top: 100px; + transform: scale(1.5); + animation: pulseAnim 2s ease-out infinite; +} + +.b-pluse { + position: absolute; + width: 100px; + height: 100px; + background: var(--color-blue); + border-radius: 50%; + top: 100px; + transform: scale(1.5); + animation: pulseAnim 2s ease-out infinite; + animation-delay: 1s; +} + +@keyframes pulseAnim { + 100% { + transform: scale(2.5); + opacity: 0; + } +} + +@media (max-width: 750px) { + .find-friends-container { + width: 320px; + padding: 10px; + } + + .loading-container { + width: 310px; + } +} diff --git a/tauri-app/src/components/FindFriends/index.tsx b/tauri-app/src/components/FindFriends/index.tsx new file mode 100644 index 0000000..4a288d1 --- /dev/null +++ b/tauri-app/src/components/FindFriends/index.tsx @@ -0,0 +1,79 @@ +import "./index.css"; +import React, { FC, useState, useRef } from "react"; + +const FriendRequest: FC = () => { + const [isCopied, setIsCopied] = useState(false); + const copyRef = useRef(null); + + return ( +
+
+ +
+

@Hello.world

+
+ + {!isCopied ? ( + { + copyRef.current.select(); + document.execCommand("copy"); + setIsCopied(true); + }} + className="fa-regular fa-copy" + > + ) : ( + + )} +
+
+
+
+ +
+
+ ); +}; + +const index: FC = () => { + const [isLoading, setIsLoading] = useState(true); + setTimeout(() => { + setIsLoading(false); + }, 5000); + return ( +
+ {isLoading ? ( + <> +
+
+
+ +
+ +
+
+

Recommending friends based off medical records...

+ + ) : ( + <> +
+ {[1, 2, 3, 4, 5, 6, 7].map((num) => { + return ; + })} +
+ + )} +
+ ); +}; + +export default index; diff --git a/tauri-app/src/components/FriendRequests/index.css b/tauri-app/src/components/FriendRequests/index.css new file mode 100644 index 0000000..ba82165 --- /dev/null +++ b/tauri-app/src/components/FriendRequests/index.css @@ -0,0 +1,127 @@ +.friend-request-container { + box-shadow: var(--box-shadow-black); + padding: 5px 8px; + border-radius: 5px; + width: 280px; + margin: 18px 0px; +} + +.friend-requests-container:n-child(1) { + margin-top: 60px; +} + +.btn-container { + display: flex; + justify-content: space-around; + align-items: center; +} + +.btn-container button { + width: max-content; + padding: 4px 12px; + outline: none; + border-radius: 3px; + border: none; + font-family: "Roboto"; + margin: 8px 0px; + font-weight: 800; + color: var(--color-white); + text-transform: uppercase; +} + +.btn-container button:nth-child(1) { + background: var(--color-green); + box-shadow: var(--box-shadow-green); +} + +.btn-container button:nth-child(2) { + background: var(--color-red); + box-shadow: var(--box-shadow-red); +} + +.friend-request-header { + display: flex; + justify-content: space-between; + align-items: center; + font-family: "Roboto"; + text-align: left; +} + +.friend-request-header img { + width: 50px; + height: 50px; + border-radius: 5px; +} + +.friend-request-header input { + padding: 4px 8px; + background: var(--color-slate-accent); + border: none; + border-radius: 3px; + font-family: "Roboto"; + margin: 8px 0; + margin-right: 10px; + outline: none; +} + +.friend-requests-container { + width: 400px; + height: max-content; + border-radius: 15px; + background: var(--color-white); + padding: 20px; +} + +.friend-requests-container h1 { + padding: 8px 10px; + font-family: "Pacifico"; +} + +.requests-container { + height: 420px; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + overflow-y: scroll; + overflow-x: hidden; + text-align: center; +} + +.requests-container::-webkit-scrollbar { + width: 6px; +} + +.requests-container::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1); + border-radius: 5px; +} + +.requests-container::-webkit-scrollbar-thumb { + width: 2px; + background: var(--color-blue); + border-radius: 5px; + margin: 0 3px; +} + +@media (max-width: 750px) { + .friend-requests-container { + width: 300px; + } + + .friend-request-container { + width: 270px; + } + + .friend-request-header img { + margin-right: 5px; + } + + .btn-container button { + padding: 8px 10px; + } + + .friend-requests-container:n-child(1) { + margin-top: 110px; + } +} diff --git a/tauri-app/src/components/FriendRequests/index.tsx b/tauri-app/src/components/FriendRequests/index.tsx new file mode 100644 index 0000000..ad5d819 --- /dev/null +++ b/tauri-app/src/components/FriendRequests/index.tsx @@ -0,0 +1,60 @@ +import "./index.css"; +import React, { FC, useState, useRef } from "react"; + +const FriendRequest: FC = () => { + const [isCopied, setIsCopied] = useState(false); + const copyRef = useRef(null); + + return ( +
+
+ +
+

@Hello.world

+
+ + {!isCopied ? ( + { + copyRef.current.select(); + document.execCommand("copy"); + setIsCopied(true); + }} + className="fa-regular fa-copy" + > + ) : ( + + )} +
+
+
+
+ + +
+
+ ); +}; +const index: FC = () => { + return ( +
e.stopPropagation()} + > +

Friend Requests!

+
+ {[1, 2, 3, 4, 5, 6, 7].map((num) => { + return ; + })} +
+
+ ); +}; + +export default index; diff --git a/tauri-app/src/components/UserMobileProfile/index.tsx b/tauri-app/src/components/UserMobileProfile/index.tsx index e25db19..272b42c 100644 --- a/tauri-app/src/components/UserMobileProfile/index.tsx +++ b/tauri-app/src/components/UserMobileProfile/index.tsx @@ -2,19 +2,35 @@ import React, { FC } from "react"; import "./index.css"; +interface friendUtils { + showFriendRequests: boolean; + setShowFriendRequests: () => void; +} + +interface findFriends { + showFriendRequests: boolean; + setShowFriendRequests: () => void; +} + interface UserProfileProps { username: String; profile_pic: String; cover_pic: String; about_user: String; friends: Number; + friendRequetsUtils: friendUtils[]; + findFriendsUtils: findFriendUtils[]; } + const index: FC = ({ username, profile_pic, cover_pic, about_user, friends, + friendRequests, + friendRequestsUtils, + findFriendsUtils }) => { return (
@@ -30,6 +46,17 @@ const index: FC = ({

Friends | {friends}

+

+ +

+ +
+ friendRequestsUtils[1](!friendRequestsUtils[0])} + className="fa fa-bell" + > + {friendRequests} +
diff --git a/tauri-app/src/components/UserProfile/index.css b/tauri-app/src/components/UserProfile/index.css index 084e0cd..d827ddc 100644 --- a/tauri-app/src/components/UserProfile/index.css +++ b/tauri-app/src/components/UserProfile/index.css @@ -49,8 +49,63 @@ top: 15px; } +.bell-container { + position: absolute; + right: 10px; + top: 22px; +} + +.bell-container i { + font-size: 25px; + color: var(--color-white); +} + +.bell-container span { + font-family: "Roboto"; + background: var(--color-red); + box-shadow: var(--box-shadow-red); + color: var(--color-white); + padding: 2px 4px; + border-radius: 10px; + border: 2px solid var(--color-white); + font-size: 10px; + position: relative; + left: -8px; +} + +.find-friend-btn { + background: transparent; + color: var(--color-white); + font-family: "Roboto"; + border: none; + outline: none; + text-decoration: underline; + cursor: pointer; +} + @media (max-width: 750px) { .userprofile-container { width: 100%; } + + .bell-container { + top: 18px; + } + + .bell-container i { + font-size: 30px; + } + + .find-friend-btn { + padding: 4px 6px; + margin-top: 5px; + background: var(--color-red); + box-shadow: var(--box-shadow-red); + color: var(--color-white); + border-radius: 5px; + font-family: "Roboto"; + border: none; + outline: none; + text-decoration: none; + } } diff --git a/tauri-app/src/components/UserProfile/index.tsx b/tauri-app/src/components/UserProfile/index.tsx index 59c87f0..fe9ff90 100644 --- a/tauri-app/src/components/UserProfile/index.tsx +++ b/tauri-app/src/components/UserProfile/index.tsx @@ -2,19 +2,35 @@ import React, { FC } from "react"; import "./index.css"; +interface friendUtils { + showFriendRequests: boolean; + setShowFriendRequests: () => void; +} + +interface findFriends { + showFriendRequests: boolean; + setShowFriendRequests: () => void; +} + interface UserProfileProps { username: String; profile_pic: String; cover_pic: String; about_user: String; friends: Number; + friendRequetsUtils: friendUtils[]; + findFriendsUtils: findFriendUtils[]; } + const index: FC = ({ username, profile_pic, cover_pic, about_user, friends, + friendRequests, + friendRequestsUtils, + findFriendsUtils, }) => { return (
@@ -28,8 +44,23 @@ const index: FC = ({ >

@{username}

- Friends | {friends} + Friends {friends} +

+

+

+
+ friendRequestsUtils[1](!friendRequestsUtils[0])} + className="fa fa-bell" + > + {friendRequests} +
diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index 04e3063..282d2c4 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -1,8 +1,9 @@ import "./index.css"; import UserProfile from "../../components/UserProfile/"; import UserFriendList from "../../components/UserFriendList/"; - import Chat from "../../components/Chat/"; +import FriendRequests from "../../components/FriendRequests/"; +import FindFriends from "../../components/FindFriends/"; import UserMobileProfile from "../../components/UserMobileProfile/"; import UserMobileFriendList from "../../components/UserMobileFriendList/"; @@ -12,19 +13,38 @@ import { useEffect, useState } from "react"; const index = () => { const [friends, setFriends] = useState([ - { profile_pic: "/pg.jpg", username: "@scriptkidd", isOnline: false ,did:"1020383*@(wppwsj)"}, - { profile_pic: "/pg.jpg", username: "@nikki", isOnline: false, newChat: 1,did:"apqpwpudrZpwpsAaap" }, + { + profile_pic: "/pg.jpg", + username: "@scriptkidd", + isOnline: false, + did: "1020383*@(wppwsj)", + }, + { + profile_pic: "/pg.jpg", + username: "@nikki", + isOnline: false, + newChat: 1, + did: "apqpwpudrZpwpsAaap", + }, { profile_pic: "/pm.jpg", username: "@gregidd", isOnline: true, newChat: 7, - did:"12340APDPDISavavagaAjd" + did: "12340APDPDISavavagaAjd", + }, + { + profile_pic: "/pic.jpg", + username: "@scdd", + isOnline: false, + newChat: 4, + did: "APSOWJEHDHaksosodoQPPE1O", }, - { profile_pic: "/pic.jpg", username: "@scdd", isOnline: false, newChat: 4 ,did:"APSOWJEHDHaksosodoQPPE1O"}, ]); const [isMobile, setIsMobile] = useState(false); const [hideChat, setHideChat] = useState(false); + const [showFriendRequests, setShowFriendRequests] = useState(false); + const [showFindFriends, setShowFindFriends] = useState(false); useEffect(() => { if (window.innerWidth < 750) { @@ -33,7 +53,7 @@ const index = () => { } setIsMobile(false); - }, []); + }, [window.innerWidth]); if (isMobile) { return ( @@ -46,18 +66,40 @@ const index = () => { profile_pic={"/pg.jpg"} cover_pic={"/pic.jpg"} friends={45} + friendRequests={5} + friendRequestsUtils={[showFriendRequests, setShowFriendRequests]} + findFriendsUtils={[showFindFriends, setShowFindFriends]} /> {hideChat && (
- + +
+ )} + + {showFriendRequests && ( +
setShowFriendRequests(false)} + className="data-container" + > + +
+ )} + {showFindFriends && ( +
setShowFindFriends(false)} + className="data-container" + > +
)}
@@ -74,14 +116,36 @@ const index = () => { profile_pic={"/pg.jpg"} cover_pic={"/pic.jpg"} friends={45} + friendRequests={5} + friendRequestsUtils={[showFriendRequests, setShowFriendRequests]} + findFriendsUtils={[showFindFriends, setShowFindFriends]} + /> + -
+ + {showFriendRequests && ( +
setShowFriendRequests(false)} + className="data-container" + > + +
+ )} + + {showFindFriends && ( +
setShowFindFriends(false)} + className="data-container" + > + +
+ )}
); }; From 7552db063ec523f144ed9d3b79079b12e3d1a32a Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 22:11:55 +0100 Subject: [PATCH 113/120] minor typo fix --- tauri-app/src/App.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 3a39460..78b72c9 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -28,7 +28,14 @@ const router = createHashRouter([ element: , }, { path: "/contact", element: }, - { path: "/chat", element: }, + { + path: "/chat", + element: ( + + + + ), + }, { path: "/chatConnect", element: }, ], }, @@ -46,7 +53,7 @@ function App() { return ( <> <> - {true ? :
Connecting...
} + {web5 ? :
Connecting...
} From 27a7c669dc1c11cd53b00bd4d1d70969a04b148a Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 22:20:18 +0100 Subject: [PATCH 114/120] fixed some merge conflicts --- tauri-app/src/components/FindFriends/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/components/FindFriends/index.tsx b/tauri-app/src/components/FindFriends/index.tsx index 4a288d1..9bb907e 100644 --- a/tauri-app/src/components/FindFriends/index.tsx +++ b/tauri-app/src/components/FindFriends/index.tsx @@ -50,7 +50,7 @@ const index: FC = () => { setIsLoading(false); }, 5000); return ( -
+
e.stopPropagation()}> {isLoading ? ( <>
From d10c18c3963a74bbd88123a72c57acc484d42281 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 22:20:34 +0100 Subject: [PATCH 115/120] fixed some merge conflicts --- tauri-app/src/pages/Chat/index.tsx | 49 ++++++------------------------ 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index acc49b7..044dd82 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -154,27 +154,15 @@ const index = () => { return (
>>>>>> 499f1964de53b184725503bcf7efa766f1394645 - /> - {
@@ -204,9 +191,7 @@ const index = () => { className="data-container" > -======= setHideChat={setHideChat} hideChat={hideChat} /> ->>>>>>> 499f1964de53b184725503bcf7efa766f1394645
)}
@@ -216,32 +201,18 @@ const index = () => {
- -======= - username={`${profile.firstName}${profile.lastName}`} + username={`${profile.firstName}${profile.lastName}`} about_user={profile.description} profile_pic={profile.profilePictureUrl} cover_pic={profile.profilePictureUrl} friends={friends.length} + friendRequests={5} + friendRequestsUtils={[showFriendRequests, setShowFriendRequests]} + findFriendsUtils={[showFindFriends, setShowFindFriends]} + /> ->>>>>>> 499f1964de53b184725503bcf7efa766f1394645
From 643dad47182122e5311a1ab400a3d6fecc3bd9c1 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 23:33:15 +0100 Subject: [PATCH 116/120] bugs fixed --- tauri-app/src/App.tsx | 2 +- tauri-app/src/components/FindFriends/index.tsx | 5 ++++- tauri-app/src/pages/Chat/index.tsx | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 78b72c9..a911cd8 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -53,7 +53,7 @@ function App() { return ( <> <> - {web5 ? :
Connecting...
} + {true ? :
Connecting...
} diff --git a/tauri-app/src/components/FindFriends/index.tsx b/tauri-app/src/components/FindFriends/index.tsx index 9bb907e..ce07ba3 100644 --- a/tauri-app/src/components/FindFriends/index.tsx +++ b/tauri-app/src/components/FindFriends/index.tsx @@ -50,7 +50,10 @@ const index: FC = () => { setIsLoading(false); }, 5000); return ( -
e.stopPropagation()}> +
e.stopPropagation()} + > {isLoading ? ( <>
diff --git a/tauri-app/src/pages/Chat/index.tsx b/tauri-app/src/pages/Chat/index.tsx index 044dd82..5450385 100644 --- a/tauri-app/src/pages/Chat/index.tsx +++ b/tauri-app/src/pages/Chat/index.tsx @@ -191,7 +191,6 @@ const index = () => { className="data-container" > - setHideChat={setHideChat} hideChat={hideChat} />
)}
From c15abe2ab75eb5c9dbf9a25bd2999a88ab526a55 Mon Sep 17 00:00:00 2001 From: lawrenceuchenye Date: Mon, 8 Jan 2024 23:54:22 +0100 Subject: [PATCH 117/120] fixes done and pushed --- tauri-app/src/components/FindFriends/index.css | 1 + tauri-app/src/components/UserMobileProfile/index.tsx | 11 ++++++++--- tauri-app/src/components/UserProfile/index.tsx | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tauri-app/src/components/FindFriends/index.css b/tauri-app/src/components/FindFriends/index.css index 1c3afee..3618e78 100644 --- a/tauri-app/src/components/FindFriends/index.css +++ b/tauri-app/src/components/FindFriends/index.css @@ -5,6 +5,7 @@ background: var(--color-white); border-radius: 15px; padding: 20px; + margin-top: 30px; } .find-friends-container h3 { diff --git a/tauri-app/src/components/UserMobileProfile/index.tsx b/tauri-app/src/components/UserMobileProfile/index.tsx index 272b42c..eae5b80 100644 --- a/tauri-app/src/components/UserMobileProfile/index.tsx +++ b/tauri-app/src/components/UserMobileProfile/index.tsx @@ -30,7 +30,7 @@ const index: FC = ({ friends, friendRequests, friendRequestsUtils, - findFriendsUtils + findFriendsUtils, }) => { return (
@@ -42,12 +42,17 @@ const index: FC = ({ }} className="m-cover-container" > -

@{username}

+

@{username.slice(0, 10) + "..."}

Friends | {friends}

- +

diff --git a/tauri-app/src/components/UserProfile/index.tsx b/tauri-app/src/components/UserProfile/index.tsx index fe9ff90..038de71 100644 --- a/tauri-app/src/components/UserProfile/index.tsx +++ b/tauri-app/src/components/UserProfile/index.tsx @@ -42,7 +42,7 @@ const index: FC = ({ }} className="cover-container" > -

@{username}

+

@{username.slice(0, 10) + "..."}

Friends {friends}

From 97d92dc61cbc72b97389cef9edb88dc0de77eb0b Mon Sep 17 00:00:00 2001 From: coder12git Date: Tue, 9 Jan 2024 10:29:20 +0530 Subject: [PATCH 118/120] removed unwanted routes Signed-off-by: coder12git --- tauri-app/src/App.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index a911cd8..985fc9b 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -9,7 +9,6 @@ import SharedLayout from "./pages/SharedLayout/"; import Records from "./pages/Records"; import Chat from "./pages/Chat/"; import { Toaster } from "react-hot-toast"; -import ChatConnect from "./pages/chat"; import ProfileGuard from "./components/Auth/Profile/Guard"; const router = createHashRouter([ @@ -35,8 +34,7 @@ const router = createHashRouter([ ), - }, - { path: "/chatConnect", element: }, + } ], }, ]); From cdb8a79ff8444a07b8c97dfab0900d4e7ffd260b Mon Sep 17 00:00:00 2001 From: Suruchi Kumari Date: Tue, 9 Jan 2024 11:08:47 +0530 Subject: [PATCH 119/120] Update video in readme --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d7151e..ebe173e 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,10 @@ npm run dev ## Explainer video (User POV) -https://github.com/coder12git/Web5-Hack/assets/58889001/b5c4aa11-426c-492b-88fb-37425991ab47 + + +https://github.com/coder12git/Web5-Hack/assets/108334168/f465aff5-d1b9-4116-bb91-87e1906baec6 + ## Demo Video (Clients POV) From b9fe504b1d0f328542013b50db6d4e2c02509c4f Mon Sep 17 00:00:00 2001 From: coder12git Date: Tue, 9 Jan 2024 11:18:55 +0530 Subject: [PATCH 120/120] make web5 in app.tsx Signed-off-by: coder12git --- tauri-app/src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 985fc9b..0f543ce 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -51,7 +51,7 @@ function App() { return ( <> <> - {true ? :
Connecting...
} + {web5 ? :
Connecting...
}