on main help sign in
more search fixes, and rudimentary frontend search
9ea2d6fJohn Hyde
desk/app/astrolabe.hoon+28−17
@@ -136,6 +136,12 @@
136++ on-naive-diff
136++ on-naive-diff
137 |= =diff:naive
137 |= =diff:naive
138 ^- (quip card _state)
138 ^- (quip card _state)
139+ ~& %+ weld "received diff:naive: {<-.diff>}"
140+ ?+ -.diff ""
141+ %nonce " ship: {<ship.diff>}"
142+ %tx " from: {<ship.from.tx.raw-tx.diff>} - {<+<.tx.raw-tx.diff>}"
143+ %point " ship: {<ship.diff>} - {<+>-.diff>}"
144+ ==
139 =? state ?=([%tx [* * * %spawn ship *] *] diff)
145 =? state ?=([%tx [* * * %spawn ship *] *] diff)
140 %- put-in-opoints
146 %- put-in-opoints
141 ship.tx.raw-tx.diff
147 ship.tx.raw-tx.diff
@@ -201,35 +207,37 @@
201++ run-wildcard-search
207++ run-wildcard-search
202 |* [agg=mold search=search-full points=opoints =page-info]
208 |* [agg=mold search=search-full points=opoints =page-info]
203 |= f=$-([agg @q] agg)
209 |= f=$-([agg @q] agg)
204− ^- agg
210+ ^- [count=@ =agg]
205 =/ s-syls search-syls.search
211 =/ s-syls search-syls.search
206 ~& s-syls
212 ~& s-syls
207 =/ s-opts search-opts.search
213 =/ s-opts search-opts.search
208− =| =agg
214+ =| res=[count=@ =agg]
209 =+ [llb=.~zod rrb=`@q`(sub (bex 32) 1)]
215 =+ [llb=.~zod rrb=`@q`(sub (bex 32) 1)]
210− =| agg-count=@
216+ :: =< +
211 |-
217 |-
212− ^- _agg
218+ ^- _res
213 ?~ points
219 ?~ points
214 :: ~& "nothing here, going up"
220 :: ~& "nothing here, going up"
215− agg
221+ res
222+ ?: (gth count.res 1.000) ~|(%search-too-broad !!)
216 =/ n=@q `@`-.n.points
223 =/ n=@q `@`-.n.points
217 =/ lrb=@q ?: (gth n 0) (sub-d n 1) .~zod
224 =/ lrb=@q ?: (gth n 0) (sub-d n 1) .~zod
218 =/ rlb=@q (add-d n 1)
225 =/ rlb=@q (add-d n 1)
219 =/ left-view (range-contains-search llb lrb s-opts)
226 =/ left-view (range-contains-search llb lrb s-opts)
220 :: ~& "arrived at {<n>}"
227 :: ~& "arrived at {<n>}"
221− :: ~& "left side: {<?:(contains.left-view 'Y' 'N')>} {<llb>} - {<lrb>} contains {<s-opts>}"
228+ :: ~& "left side: {<?:(contains.left-view 'Y' 'N')>} {<llb>} - {<lrb>}"
222 =/ right-view (range-contains-search rlb rrb s-opts)
229 =/ right-view (range-contains-search rlb rrb s-opts)
223− =? agg contains.left-view
230+ =? res contains.left-view
224 $(points l.points, rrb lrb, s-opts opts.left-view)
231 $(points l.points, rrb lrb, s-opts opts.left-view)
225− =? agg (matches-search s-syls n)
232+ =? res (matches-search s-syls n)
226− =/ fits (fits-on-page agg-count page-info)
233+ =/ fits (fits-on-page count.res page-info)
227− =. agg-count +(agg-count)
234+ =. count.res +(count.res)
228− ?: fits (f agg n) agg
235+ =? agg.res fits (f agg.res n)
236+ res
229− :: ~& "right side: {<?:(contains.right-view 'Y' 'N')>} {<rlb>} - {<rrb>} contains {<s-opts>}"
237+ :: ~& "right side: {<?:(contains.right-view 'Y' 'N')>} {<rlb>} - {<rrb>}"
230− =? agg contains.right-view
238+ =? res contains.right-view
231 $(points r.points, llb rlb, s-opts opts.right-view)
239 $(points r.points, llb rlb, s-opts opts.right-view)
232− agg
240+ res
233::
241::
234++ search-opoints
242++ search-opoints
235 |= =search-text
243 |= =search-text
@@ -237,15 +245,18 @@
237 =/ =search-full (search-text-to-search-full search-text)
245 =/ =search-full (search-text-to-search-full search-text)
238 =^ spoints search-full
246 =^ spoints search-full
239 (maybe-reverse-search search-full fopoints ropoints)
247 (maybe-reverse-search search-full fopoints ropoints)
248+ ?: (gth pain.spoints 2.820) ~|(%search-predicted-too-broad !!)
240 =/ results
249 =/ results
241 %-
250 %-
242 (run-wildcard-search (list @q) search-full points.spoints *page-info)
251 (run-wildcard-search (list @q) search-full points.spoints *page-info)
243 |= [agg=(list @q) result=@q]
252 |= [agg=(list @q) result=@q]
244 [result agg]
253 [result agg]
254+ ~& "returning {<(lent agg.results)>} of {<count.results>} results"
255+ =/ ships agg.results
245− =? results reversed.spoints
256+ =? ships reversed.spoints
246− (turn results switch-words)
257+ (turn ships switch-words)
247 %- flop
258 %- flop
248− (turn results to-p)
259+ (turn ships to-p)
249::
260::
250++ sponsor-chain
261++ sponsor-chain
251 |= [=ship =unpoint]
262 |= [=ship =unpoint]
desk/lib/astrolabe.hoon+32−10
@@ -109,10 +109,17 @@
109 %+ weld
109 %+ weld
110 (slag 2 lst)
110 (slag 2 lst)
111 (scag 2 lst)
111 (scag 2 lst)
112+++ pad-search-syls
113+ |= =search-syls
114+ ^- ^search-syls
115+ =/ padding (search-text-to-search-syls "dozzoddozzod")
116+ %+ weld
117+ search-syls
118+ (slag (lent search-syls) padding)
112++ reverse-search
119++ reverse-search
113 |= search=search-full
120 |= search=search-full
114 ^- search-full
121 ^- search-full
115− :- (reverse-list search-syls.search)
122+ :- (reverse-list (pad-search-syls search-syls.search))
116 (reverse-list search-opts.search)
123 (reverse-list search-opts.search)
117++ estimate-search-pain
124++ estimate-search-pain
118 |= search=search-full
125 |= search=search-full
@@ -123,15 +130,29 @@
123 =/ new-acc
130 =/ new-acc
124 (add (mul acc 2) (lent i.opts))
131 (add (mul acc 2) (lent i.opts))
125 $(acc new-acc, opts t.opts)
132 $(acc new-acc, opts t.opts)
133+:: ++ estimate-search-pain
134+:: |= search=search-full
135+:: =/ max-pain (bex 32)
136+:: =/ opts search-opts.search
137+:: =| acc=@
138+:: |-
139+:: ?~ opts acc
140+:: =/ level-pain (div (mul max-pain (lent i.opts)) 256)
141+:: =/ new-acc
142+:: (add (mul acc 2) (lent i.opts))
143+:: $(acc new-acc, opts t.opts)
144+++ estimate-search-text-pain
145+ |= =search-text
146+ (estimate-search-pain (search-text-to-search-full search-text))
126++ maybe-reverse-search
147++ maybe-reverse-search
127 |= [search=search-full fopoints=opoints ropoints=opoints]
148 |= [search=search-full fopoints=opoints ropoints=opoints]
128− ^- [[points=opoints reversed=?] search-full]
149+ ^- [[points=opoints reversed=? pain=@] =search-full]
129 =/ search-pain (estimate-search-pain search)
150 =/ search-pain (estimate-search-pain search)
130 =/ rsearch (reverse-search search)
151 =/ rsearch (reverse-search search)
131 =/ rsearch-pain (estimate-search-pain rsearch)
152 =/ rsearch-pain (estimate-search-pain rsearch)
132 ?: (gth search-pain rsearch-pain)
153 ?: (gth search-pain rsearch-pain)
133− [[ropoints %.y] rsearch]
154+ [[ropoints %.y rsearch-pain] rsearch]
134− [[fopoints %.n] search]
155+ [[fopoints %.n search-pain] search]
135++ tape-matches
156++ tape-matches
136 |= [search=tape cand=tape]
157 |= [search=tape cand=tape]
137 ^- ?
158 ^- ?
@@ -149,14 +170,15 @@
149++ matches-search
170++ matches-search
150 |= [search=search-syls cand-atom=@]
171 |= [search=search-syls cand-atom=@]
151 =/ cand (rip 3 cand-atom)
172 =/ cand (rip 3 cand-atom)
152− =? cand =(cand ~)
153− (limo ~[0])
154 |-
173 |-
155 ^- ?
174 ^- ?
156− ?~ search =(~ cand)
175+ ?~ search =(cand ~)
176+ :: =? cand =(cand ~)
177+ :: `(lest @)`~[0]
178+ =/ nncand ^- (lest @)
157− ?~ cand %.n
179+ ?~ cand ~[0] cand
158− ?: (syl-matches i.search i.cand)
180+ ?: (syl-matches i.search i.nncand)
159− $(search t.search, cand t.cand)
181+ $(search t.search, cand t.nncand)
160 %.n
182 %.n
161::
183::
162++ opts-in-range
184++ opts-in-range
ui/src/components/SearchResults.svelte+52−38
@@ -1,42 +1,45 @@
1<script lang="ts">
1<script lang="ts">
2 import { Groups, Rolodex } from '@urbit/api';
2 import { Groups, Rolodex } from '@urbit/api';
3+ import { searchPoints } from '../lib/api';
3 import store from '../stores/store';
4 import store from '../stores/store';
4 import ShipListing from './ShipListing.svelte';
5 import ShipListing from './ShipListing.svelte';
5 import SearchResultNavButtons from './SearchResultNavButtons.svelte';
6 import SearchResultNavButtons from './SearchResultNavButtons.svelte';
6 import ShipView from './ShipView.svelte';
7 import ShipView from './ShipView.svelte';
7− export let searchQuery: RegExp;
8+ export let query: RegExp;
9+ export let search: string;
8− export let patp: string;
10+ // export let patp: string;
9 let contactsList = [];
11 let contactsList = [];
10 let selectedShipIndex: number;
12 let selectedShipIndex: number;
11
13
12− $: {
14+ $: searchedPointsP = searchPoints(search)
15+ // $: {
13− if (!patp) {
16+ // // if (!patp) {
14− store.search(searchQuery)
17+ // store.search(query)
15− }
18+ // // }
16− // if (searchQuery) {
19+ // // if (searchQuery) {
17− // store.search(searchQuery)
20+ // // store.search(searchQuery)
18− // } else {
21+ // // } else {
19− // store.reset();
22+ // // store.reset();
20− // }
23+ // // }
21− }
24+ // }
22− $: {
25+ // $: {
23− contactsList = Object.entries($store?.contacts).map(([patp, ship]) => {
26+ // contactsList = Object.entries($store?.contacts).map(([patp, ship]) => {
24− return {
27+ // return {
25− ...ship,
28+ // ...ship,
26− patp,
29+ // patp,
27− };
30+ // };
28− });
31+ // });
29− if (contactsList.length === 1) {
32+ // if (contactsList.length === 1) {
30− selectedShipIndex = 0;
33+ // selectedShipIndex = 0;
31− } else {
34+ // } else {
32− selectedShipIndex = null;
35+ // selectedShipIndex = null;
33− }
36+ // }
34− }
37+ // }
35− $: selectedShip = contactsList[selectedShipIndex]
38+ // $: selectedShip = contactsList[selectedShipIndex]
36
39
37− function updateIndex(e) {
40+ // function updateIndex(e) {
38− selectedShipIndex = e.detail.index;
41+ // selectedShipIndex = e.detail.index;
39− }
42+ // }
40</script>
43</script>
41
44
42<!-- should actually switch on whether field is empty -->
45<!-- should actually switch on whether field is empty -->
@@ -46,7 +49,7 @@
46 Hello, ~{window.ship}, would you like to search?
49 Hello, ~{window.ship}, would you like to search?
47 </p>
50 </p>
48{/if} -->
51{/if} -->
49−{#if patp}
52+<!-- {#if patp}
50 <ShipView {patp} />
53 <ShipView {patp} />
51{:else if selectedShip}
54{:else if selectedShip}
52 {#if contactsList.length > 1}
55 {#if contactsList.length > 1}
@@ -57,12 +60,23 @@
57 />
60 />
58 {/if}
61 {/if}
59 <ShipView patp={selectedShip.patp} />
62 <ShipView patp={selectedShip.patp} />
60−{:else}
63+{:else} -->
61− <div class="flex justify-center">
64+{query}
65+{search}
66+{#await searchedPointsP}
67+Loading...
68+{:then { points }}
62− <div class="max-w-md w-full rounded-lg bg-white">
69+ <div class="max-w-md w-full rounded-lg bg-white">
63− {#each contactsList as contact, i (contact.patp)}
70+ <!-- {#each contactsList as contact, i (contact.patp)}
64− <ShipListing ship={contact} on:click={() => selectedShipIndex = i}/>
71+ <ShipListing ship={contact} on:click={() => selectedShipIndex = i}/>
65− {/each}
72+ {/each} -->
66− </div>
73+ {#each points as patp, i (patp)}
74+ <ShipListing ship={{ patp }} linkToShip />
75+ {/each}
67 </div>
76 </div>
77+{:catch}
78+ <div class="max-w-md w-full rounded-lg bg-white">
79+ Search Too Broad
80+ </div>
81+{/await}
68−{/if}
82+<!-- {/if} -->
ui/src/components/ShipView.svelte+3−5
@@ -1,9 +1,8 @@
1<script lang="ts">
1<script lang="ts">
2− import UrbitApi from '@urbit/http-api';
3 import { clan, sein, patp2dec } from 'urbit-ob';
2 import { clan, sein, patp2dec } from 'urbit-ob';
4
3
5 import { cite, normalizeId } from '../lib/id';
4 import { cite, normalizeId } from '../lib/id';
6− import tooltip from "../actions/tooltip";
5+ import { getPoint, getSpawnedPoints } from '../lib/api';
7 import Sigil from "./Sigil.svelte";
6 import Sigil from "./Sigil.svelte";
8 import GoldBadge from './GoldBadge.svelte';
7 import GoldBadge from './GoldBadge.svelte';
9 import TooltipAndDocLink from "./TooltipAndDocLink.svelte";
8 import TooltipAndDocLink from "./TooltipAndDocLink.svelte";
@@ -23,7 +22,6 @@
23 let rawSpawnedPointsPromise: any;
22 let rawSpawnedPointsPromise: any;
24 let rawSpawnedPoints: any = null;
23 let rawSpawnedPoints: any = null;
25 let spawnedPoints: string[] = [];
24 let spawnedPoints: string[] = [];
26− const api: UrbitApi = new UrbitApi('');
27 const spawnStatusOptions = {
25 const spawnStatusOptions = {
28 unspawned: {
26 unspawned: {
29 text: 'unspawned',
27 text: 'unspawned',
@@ -83,7 +81,7 @@
83 $: {
81 $: {
84 rawPointInfo = null;
82 rawPointInfo = null;
85 if (azPoint) {
83 if (azPoint) {
86− rawPointInfoPromise = api.scry<any>({ app: 'astrolabe', path: `/point/${patp}` });
84+ rawPointInfoPromise = getPoint(patp);
87 rawPointInfoPromise.then((info) => {
85 rawPointInfoPromise.then((info) => {
88 rawPointInfo = info;
86 rawPointInfo = info;
89 }).catch((error) => {
87 }).catch((error) => {
@@ -94,7 +92,7 @@
94 $: {
92 $: {
95 rawSpawnedPoints = null;
93 rawSpawnedPoints = null;
96 if (canSpawnPoints) {
94 if (canSpawnPoints) {
97− rawSpawnedPointsPromise = api.scry<any>({ app: 'astrolabe', path: `/point/${patp}/spawned` });
95+ rawSpawnedPointsPromise = getSpawnedPoints(patp);
98 rawSpawnedPointsPromise.then((info) => {
96 rawSpawnedPointsPromise.then((info) => {
99 rawSpawnedPoints = info;
97 rawSpawnedPoints = info;
100 }).catch((error) => {
98 }).catch((error) => {
ui/src/lib/api.ts+29−1
@@ -1,4 +1,32 @@
1import UrbitApi from '@urbit/http-api';
1import UrbitApi from '@urbit/http-api';
2+console.log(`Initializing Urbit API at ${Date()}`);
2const api: UrbitApi = new UrbitApi('');
3const api: UrbitApi = new UrbitApi('');
3
4
5+function scry<T = any>(path: string): Promise<T> {
6+ return api.scry<T>({ app: 'astrolabe', path });
7+}
8+
9+function getPoint(patp: string): Promise<any> {
10+ return scry<any>(`/point/${patp}`);
11+}
12+
13+function getSpawnedPoints(patp: string): Promise<any> {
14+ return scry<any>(`/point/${patp}/spawned`);
15+}
16+
17+function searchPoints(search: string): Promise<any> {
18+ return scry<any>(`/search/${search}`);
19+}
20+
21+function getDoc(path: string): Promise<string> {
22+ return scry<string>(`/doc/${path}`);
23+}
24+
4−export default api;
25+export {
26+ api,
27+ scry,
28+ getPoint,
29+ getSpawnedPoints,
30+ searchPoints,
31+ getDoc,
32+};
ui/src/routes/ShipViewPage.svelte+4−1
@@ -4,6 +4,7 @@
4 import { SearchAnalysis } from '../lib/id';
4 import { SearchAnalysis } from '../lib/id';
5 import { linkToShip } from '../lib/link';
5 import { linkToShip } from '../lib/link';
6 import SearchBar from "../components/SearchBar.svelte";
6 import SearchBar from "../components/SearchBar.svelte";
7+ import SearchResults from "../components/SearchResults.svelte";
7 import ShipView from '../components/ShipView.svelte';
8 import ShipView from '../components/ShipView.svelte';
8 import ValidationProblems from '../components/ValidationProblems.svelte';
9 import ValidationProblems from '../components/ValidationProblems.svelte';
9 import HomeScreenTiles from '../components/HomeScreenTiles.svelte';
10 import HomeScreenTiles from '../components/HomeScreenTiles.svelte';
@@ -44,8 +45,10 @@
44 <SearchBar bind:analysis bind:search />
45 <SearchBar bind:analysis bind:search />
45 {#if analysis.patpIsValid}
46 {#if analysis.patpIsValid}
46 <ShipView patp={analysis.patp} />
47 <ShipView patp={analysis.patp} />
48+ {:else if (analysis.queryIsValid)}
49+ <SearchResults query={analysis.query} search={analysis.search} />
47 {:else if (analysis.search.length > 0)}
50 {:else if (analysis.search.length > 0)}
48− <ValidationProblems problems={analysis.patpProblems} />
51+ <ValidationProblems problems={analysis.queryProblems} />
49 {:else}
52 {:else}
50 <HomeScreenTiles />
53 <HomeScreenTiles />
51 {/if}
54 {/if}
ui/src/stores/docs.ts+9−5
@@ -1,6 +1,6 @@
1import { writable } from 'svelte/store';
1import { writable } from 'svelte/store';
2
2
3−import api from '../lib/api';
3+import { getDoc } from '../lib/api';
4const docs = {};
4const docs = {};
5// import type { AppState, Contacts } from '../types/store';
5// import type { AppState, Contacts } from '../types/store';
6
6
@@ -12,11 +12,11 @@ const initStore: any = {
12const store = writable(initStore);
12const store = writable(initStore);
13const { subscribe, update, set } = store;
13const { subscribe, update, set } = store;
14
14
15−async function getDoc(path): Promise<string> {
15+async function getCachedDoc(path): Promise<string> {
16 if (docs[path]) {
16 if (docs[path]) {
17 return docs[path];
17 return docs[path];
18 } else {
18 } else {
19− const doc = await api.scry<string>({ app: 'astrolabe', path: `/doc/${path}` });
19+ const doc = await getDoc(path);
20 docs[path] = doc;
20 docs[path] = doc;
21 return doc;
21 return doc;
22 }
22 }
@@ -37,5 +37,9 @@ function hide() {
37 }));
37 }));
38}
38}
39
39
40−
41−export default { subscribe, getDoc, show, hide };
40+export default {
41+ subscribe,
42+ getDoc: getCachedDoc,
43+ show,
44+ hide
45+};
ui/src/stores/store.ts+2−30
@@ -1,6 +1,6 @@
1import { writable } from 'svelte/store';
1import { writable } from 'svelte/store';
2
2
3−import api from '../lib/api';
3+import { api } from '../lib/api';
4import type { StoreState, Contacts } from '../types/store';
4import type { StoreState, Contacts } from '../types/store';
5import { filterObject } from '../lib/utils';
5import { filterObject } from '../lib/utils';
6import fakeContacts from '../fake_data/fake-contacts';
6import fakeContacts from '../fake_data/fake-contacts';
@@ -11,7 +11,6 @@ const initStore: StoreState = {
11 contacts: {},
11 contacts: {},
12 connection: 'disconnected',
12 connection: 'disconnected',
13 ship: window.ship,
13 ship: window.ship,
14− docs: {},
15};
14};
16
15
17const store = writable(initStore);
16const store = writable(initStore);
@@ -40,32 +39,5 @@ function reset() {
40 set(initStore);
39 set(initStore);
41}
40}
42
41
43−function getDoc(path) {
44− return new Promise((resolve, reject) => {
45− const unsubscribe = subscribe(async ({ docs }) => {
46− try {
47− if (docs[path]) {
48− resolve(docs[path]);
49− } else {
50− const doc = await api.scry<string>({ app: 'astrolabe', path: `/doc/${path}` });
51− update(($store: StoreState): StoreState => {
52− return {
53− ...$store,
54− docs: {
55− ...$store.docs,
56− [path]: doc,
57− },
58− }
59− });
60− resolve(doc);
61− }
62− } catch (error) {
63− reject(error);
64− }
65− });
66− unsubscribe();
67− });
68−}
69−
70
42
71−export default { subscribe, search, reset, getDoc };
43+export default { subscribe, search, reset };
ui/src/styles/tailwind-output.css+4
@@ -1106,6 +1106,10 @@ Ensure the default browser behavior of the `hidden` attribute.
1106 max-width: 42rem;
1106 max-width: 42rem;
1107 }
1107 }
1108
1108
1109+ .md\:max-w-lg {
1110+ max-width: 32rem;
1111+ }
1112+
1109 .md\:flex-row {
1113 .md\:flex-row {
1110 flex-direction: row;
1114 flex-direction: row;
1111 }
1115 }
ui/src/types/store.ts−1
@@ -17,5 +17,4 @@ export interface StoreState {
17 connection: ConnectionStatus;
17 connection: ConnectionStatus;
18 subscription?: unknown;
18 subscription?: unknown;
19 ship: Patp;
19 ship: Patp;
20− docs: Docs;
21}
20}