Compare commits

...

1 Commits

  1. 3
      src/db/tables/settings.ts
  2. 1
      src/libs/endorserServer.ts
  3. 2
      src/main.ts
  4. 129
      src/views/DiscoverView.vue

3
src/db/tables/settings.ts

@ -31,12 +31,15 @@ export type Settings = {
}>; }>;
showContactGivesInline?: boolean; // Display contact inline or not showContactGivesInline?: boolean; // Display contact inline or not
starredProjects?: Array<string>; // Array of starred project IDs
vapid?: string; // VAPID (Voluntary Application Server Identification) field for web push vapid?: string; // VAPID (Voluntary Application Server Identification) field for web push
warnIfProdServer?: boolean; // Warn if using a production server warnIfProdServer?: boolean; // Warn if using a production server
warnIfTestServer?: boolean; // Warn if using a testing server warnIfTestServer?: boolean; // Warn if using a testing server
webPushServer?: string; // Web Push server URL webPushServer?: string; // Web Push server URL
}; };
export const DEFAULT_SETTINGS: Settings = { id: 1 };
/** /**
* Schema for the Settings table in the database. * Schema for the Settings table in the database.
*/ */

1
src/libs/endorserServer.ts

@ -103,6 +103,7 @@ export interface PlanServerRecord {
handleId: string; handleId: string;
locLat?: number; locLat?: number;
locLon?: number; locLon?: number;
name: string;
startTime?: string; startTime?: string;
url?: string; url?: string;
} }

2
src/main.ts

@ -61,6 +61,7 @@ import {
faSquareCaretDown, faSquareCaretDown,
faSquareCaretUp, faSquareCaretUp,
faSquarePlus, faSquarePlus,
faStar,
faTrashCan, faTrashCan,
faTriangleExclamation, faTriangleExclamation,
faUser, faUser,
@ -119,6 +120,7 @@ library.add(
faSquareCaretDown, faSquareCaretDown,
faSquareCaretUp, faSquareCaretUp,
faSquarePlus, faSquarePlus,
faStar,
faTrashCan, faTrashCan,
faTriangleExclamation, faTriangleExclamation,
faUser, faUser,

129
src/views/DiscoverView.vue

@ -1,5 +1,5 @@
<template> <template>
<QuickNav selected="Discover"></QuickNav> <QuickNav selected="Discover" />
<TopMessage /> <TopMessage />
<!-- CONTENT --> <!-- CONTENT -->
@ -28,6 +28,20 @@
<!-- Result Tabs --> <!-- Result Tabs -->
<div class="text-center text-slate-500 border-b border-slate-300"> <div class="text-center text-slate-500 border-b border-slate-300">
<ul class="flex flex-wrap justify-center gap-4 -mb-px"> <ul class="flex flex-wrap justify-center gap-4 -mb-px">
<li>
<a
href="#"
@click="
projects = [];
isRemoteActive = false;
isLocalActive = false;
isStarActive = true;
"
v-bind:class="computedStarTabClassNames()"
>
<fa icon="star" class="fa-fw" />
</a>
</li>
<li> <li>
<a <a
href="#" href="#"
@ -35,6 +49,7 @@
projects = []; projects = [];
isLocalActive = true; isLocalActive = true;
isRemoteActive = false; isRemoteActive = false;
isStarActive = false;
searchLocal(); searchLocal();
" "
v-bind:class="computedLocalTabClassNames()" v-bind:class="computedLocalTabClassNames()"
@ -55,6 +70,7 @@
projects = []; projects = [];
isRemoteActive = true; isRemoteActive = true;
isLocalActive = false; isLocalActive = false;
isStarActive = false;
searchAll(); searchAll();
" "
v-bind:class="computedRemoteTabClassNames()" v-bind:class="computedRemoteTabClassNames()"
@ -71,8 +87,11 @@
</ul> </ul>
</div> </div>
<div v-if="isStarActive && projects.length == 0">
<div class="mt-4 text-center">You have not starred any projects.</div>
</div>
<div v-if="isLocalActive"> <div v-if="isLocalActive">
<div> <div class="mt-2 text-center">
<button <button
class="ml-2 px-4 py-2 rounded-md bg-blue-200 text-blue-500" class="ml-2 px-4 py-2 rounded-md bg-blue-200 text-blue-500"
@click="$router.push({ name: 'search-area' })" @click="$router.push({ name: 'search-area' })"
@ -131,9 +150,14 @@ import { Component, Vue } from "vue-facing-decorator";
import { accountsDB, db } from "@/db/index"; import { accountsDB, db } from "@/db/index";
import { Contact } from "@/db/tables/contacts"; import { Contact } from "@/db/tables/contacts";
import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings"; import {
BoundingBox,
DEFAULT_SETTINGS,
MASTER_SETTINGS_KEY,
Settings,
} from "@/db/tables/settings";
import { accessToken } from "@/libs/crypto"; import { accessToken } from "@/libs/crypto";
import { didInfo, PlanData } from "@/libs/endorserServer"; import { didInfo, PlanData, PlanServerRecord } from "@/libs/endorserServer";
import QuickNav from "@/components/QuickNav.vue"; import QuickNav from "@/components/QuickNav.vue";
import InfiniteScroll from "@/components/InfiniteScroll.vue"; import InfiniteScroll from "@/components/InfiniteScroll.vue";
import EntityIcon from "@/components/EntityIcon.vue"; import EntityIcon from "@/components/EntityIcon.vue";
@ -168,19 +192,23 @@ export default class DiscoverView extends Vue {
isLoading = false; isLoading = false;
isLocalActive = true; isLocalActive = true;
isRemoteActive = false; isRemoteActive = false;
isStarActive = false;
localCount = -1; localCount = -1;
remoteCount = -1; remoteCount = -1;
searchBox: { name: string; bbox: BoundingBox } | null = null; searchBox: { name: string; bbox: BoundingBox } | null = null;
starredProjects: Array<string> = [];
// make this function available to the Vue template // make this function available to the Vue template
didInfo = didInfo; didInfo = didInfo;
async mounted() { async mounted() {
await db.open(); await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY); const settings: Settings =
(await db.settings.get(MASTER_SETTINGS_KEY)) || DEFAULT_SETTINGS;
this.activeDid = (settings?.activeDid as string) || ""; this.activeDid = (settings?.activeDid as string) || "";
this.apiServer = (settings?.apiServer as string) || ""; this.apiServer = (settings?.apiServer as string) || "";
this.searchBox = settings?.searchBoxes?.[0] || null; this.searchBox = settings?.searchBoxes?.[0] || null;
this.starredProjects = settings?.starredProjects || [];
this.allContacts = await db.contacts.toArray(); this.allContacts = await db.contacts.toArray();
@ -188,7 +216,9 @@ export default class DiscoverView extends Vue {
const allAccounts = await accountsDB.accounts.toArray(); const allAccounts = await accountsDB.accounts.toArray();
this.allMyDids = allAccounts.map((acc) => acc.did); this.allMyDids = allAccounts.map((acc) => acc.did);
if (this.searchBox) { if (this.starredProjects.length > 0) {
await this.searchStars();
} else if (this.searchBox) {
await this.searchLocal(); await this.searchLocal();
} else { } else {
this.isLocalActive = false; this.isLocalActive = false;
@ -203,7 +233,9 @@ export default class DiscoverView extends Vue {
} }
public async searchSelected() { public async searchSelected() {
if (this.isLocalActive) { if (this.isStarActive) {
await this.searchStars();
} else if (this.isLocalActive) {
await this.searchLocal(); await this.searchLocal();
} else { } else {
await this.searchAll(); await this.searchAll();
@ -395,6 +427,71 @@ export default class DiscoverView extends Vue {
} }
} }
public async searchStars() {
this.resetCounts();
if (this.starredProjects.length == 0) {
this.projects = [];
return;
}
try {
this.isLoading = true;
const response = await fetch(
this.apiServer +
"/api/v2/report/plans?handleIds=" +
encodeURIComponent(JSON.stringify(this.starredProjects)),
{
method: "GET",
headers: await this.buildHeaders(),
},
);
if (response.status !== 200) {
const details = await response.text();
console.log("Problem with full search:", details);
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text: `There was a problem accessing the server. Try again later.`,
},
-1,
);
throw details;
}
const results = await response.json();
const plans: PlanServerRecord[] = results.data;
if (plans) {
for (const plan of plans) {
const { name, description, handleId, issuerDid } = plan;
this.projects.push({ name, description, handleId, issuerDid });
}
this.remoteCount = this.projects.length;
} else {
throw JSON.stringify(results);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
console.log("Error with feed load:", e);
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text: e.userMessage || "There was a problem retrieving projects.",
},
-1,
);
} finally {
this.isLoading = false;
}
}
/** /**
* Data loader used by infinite scroller * Data loader used by infinite scroller
* @param payload is the flag from the InfiniteScroll indicating if it should load * @param payload is the flag from the InfiniteScroll indicating if it should load
@ -422,6 +519,24 @@ export default class DiscoverView extends Vue {
this.$router.push(route); this.$router.push(route);
} }
public computedStarTabClassNames() {
return {
"inline-block": true,
"py-3": true,
"rounded-t-lg": true,
"border-b-2": true,
active: this.isStarActive,
"text-black": this.isStarActive,
"border-black": this.isStarActive,
"font-semibold": this.isStarActive,
"text-blue-600": !this.isStarActive,
"border-transparent": !this.isStarActive,
"hover:border-slate-400": !this.isStarActive,
};
}
public computedLocalTabClassNames() { public computedLocalTabClassNames() {
return { return {
"inline-block": true, "inline-block": true,

Loading…
Cancel
Save