on master help sign in
reconfiguring lookup scry to filter already indexed listings from add apps/groups
95653ffHunter Miller
desk/app/sphinx.hoon+12−4
@@ -178,17 +178,25 @@
178 [%x %published ~]
178 [%x %published ~]
179 ``directory+!>(published)
179 ``directory+!>(published)
180 ::
180 ::
181− [%x %lookup @ @ @ @ ~]
181+ [%x %lookup @ @ @ $@(~ [@ ~])]
182 =- ``search+!>(-)
182 =- ``search+!>(-)
183 ^- search:s
183 ^- search:s
184 =/ filter
184 =/ filter
185 %+ rash i.t.t.path
185 %+ rash i.t.t.path
186 (perk [%app %group %content %other %all ~])
186 (perk [%app %group %content %other %all ~])
187+ =/ start (slav %ud i.t.t.t.path)
188+ =/ limit (slav %ud i.t.t.t.t.path)
189+ =/ term
190+ ?^ t.t.t.t.t.path
187− =/ term `@t`(slav %t i.t.t.t.path)
191+ `@t`(slav %t i.t.t.t.t.t.path)
188− =/ start (slav %ud i.t.t.t.t.path)
192+ ~
189− =/ limit (slav %ud i.t.t.t.t.t.path)
190 :: expects encoded @t values)
193 :: expects encoded @t values)
191 =/ all
194 =/ all
195+ ?~ term
196+ %+ skim
197+ ~(val by directory)
198+ |= =listing:s
199+ |(=(filter %all) =(filter type.post.listing))
192 %+ skim
200 %+ skim
193 %- get-listings
201 %- get-listings
194 %- get-hashes
202 %- get-hashes
desk/desk.docket-0+1−1
@@ -4,7 +4,7 @@
4 image+'https://nyc3.digitaloceanspaces.com/hmillerdev/nocsyx-lassul/2022.7.16..04.35.22-sphinx-web-shifted.svg'
4 image+'https://nyc3.digitaloceanspaces.com/hmillerdev/nocsyx-lassul/2022.7.16..04.35.22-sphinx-web-shifted.svg'
5 glob-http+['https://nyc3.digitaloceanspaces.com/hmillerdev/sphinx/glob-0vb8b8l.rmk5k.kmfli.fbeuf.c82vn.glob' 0vb8b8l.rmk5k.kmfli.fbeuf.c82vn]
5 glob-http+['https://nyc3.digitaloceanspaces.com/hmillerdev/sphinx/glob-0vb8b8l.rmk5k.kmfli.fbeuf.c82vn.glob' 0vb8b8l.rmk5k.kmfli.fbeuf.c82vn]
6 base+'sphinx'
6 base+'sphinx'
7− version+[0 0 2]
7+ version+[0 1 0]
8 website+'https://github.com'
8 website+'https://github.com'
9 license+'MIT'
9 license+'MIT'
10==
10==
ui/src/components/PostOptions.tsx+1−1
@@ -16,7 +16,7 @@ export const PostOptions = ({ options, emptyMessage, className }: PostOptionsPro
16 if (options.length === 0) {
16 if (options.length === 0) {
17 return (
17 return (
18 <div>
18 <div>
19− <h2 className='text-xl font-semibold'>{emptyMessage}</h2>
19+ <h2 className='text-lavender'>{emptyMessage}</h2>
20 </div>
20 </div>
21 )
21 )
22 }
22 }
ui/src/manage-listings/Apps.tsx+12−9
@@ -29,7 +29,6 @@ export const Apps = () => {
29 }, [apps, options, setValue]);
29 }, [apps, options, setValue]);
30
30
31 const onSubmit = useCallback((values: PostOptionsForm) => {
31 const onSubmit = useCallback((values: PostOptionsForm) => {
32− debugger;
33 api.poke<Declare[]>({
32 api.poke<Declare[]>({
34 app: 'sphinx',
33 app: 'sphinx',
35 mark: 'declarations',
34 mark: 'declarations',
@@ -46,21 +45,25 @@ export const Apps = () => {
46 <>
45 <>
47 <header className='flex items-center'>
46 <header className='flex items-center'>
48 <h1 className='text-2xl font-semibold'>Add Apps</h1>
47 <h1 className='text-2xl font-semibold'>Add Apps</h1>
48+ {apps.length > 0 && (
49− <button className='p-2 ml-auto text-sm underline font-semibold' onClick={toggleAll}>
49+ <button className='p-2 ml-auto text-sm underline font-semibold' onClick={toggleAll}>
50− {options.length !== apps.length && 'select all'}
50+ {options.length !== apps.length && 'select all'}
51− {options.length === apps.length && 'deselect all'}
51+ {options.length === apps.length && 'deselect all'}
52− </button>
52+ </button>
53+ )}
53 </header>
54 </header>
54 <FormProvider {...form}>
55 <FormProvider {...form}>
55 <form onSubmit={handleSubmit(onSubmit)}>
56 <form onSubmit={handleSubmit(onSubmit)}>
56− <PostOptions options={apps} emptyMessage="No apps found" />
57+ <PostOptions options={apps} emptyMessage="All apps already indexed" />
57 <div className='flex justify-between border-t border-zinc-300 py-3 mt-6'>
58 <div className='flex justify-between border-t border-zinc-300 py-3 mt-6'>
58 <Link to="/search" className='flex items-center rounded-lg text-base font-semibold text-rosy bg-rosy/30 border-2 border-transparent hover:border-rosy leading-none py-2 px-3 transition-colors'>
59 <Link to="/search" className='flex items-center rounded-lg text-base font-semibold text-rosy bg-rosy/30 border-2 border-transparent hover:border-rosy leading-none py-2 px-3 transition-colors'>
59 Back to Search
60 Back to Search
60 </Link>
61 </Link>
62+ {apps.length > 0 && (
61− <button type="submit" className='flex items-center rounded-lg text-base font-semibold text-linen bg-rosy disabled:bg-zinc-200 disabled:text-zinc-400 disabled:border-transparent border-2 border-transparent hover:border-linen/60 leading-none py-2 px-3 transition-colors' disabled={options.length === 0}>
63+ <button type="submit" className='flex items-center rounded-lg text-base font-semibold text-linen bg-rosy disabled:bg-zinc-200 disabled:text-zinc-400 disabled:border-transparent border-2 border-transparent hover:border-linen/60 leading-none py-2 px-3 transition-colors' disabled={options.length === 0}>
62− Publish
64+ Publish
63− </button>
65+ </button>
66+ )}
64 </div>
67 </div>
65 </form>
68 </form>
66 </FormProvider>
69 </FormProvider>
ui/src/manage-listings/Groups.tsx+12−8
@@ -52,21 +52,25 @@ export const Groups = () => {
52 <>
52 <>
53 <header className='flex items-center'>
53 <header className='flex items-center'>
54 <h1 className='text-2xl font-semibold'>Add Groups</h1>
54 <h1 className='text-2xl font-semibold'>Add Groups</h1>
55+ {groups.length > 0 && (
55− <button className='p-2 ml-auto text-sm underline font-semibold' onClick={toggleAll}>
56+ <button className='p-2 ml-auto text-sm underline font-semibold' onClick={toggleAll}>
56− {options.length !== groups.length && 'select all'}
57+ {options.length !== groups.length && 'select all'}
57− {options.length === groups.length && 'deselect all'}
58+ {options.length === groups.length && 'deselect all'}
58− </button>
59+ </button>
60+ )}
59 </header>
61 </header>
60 <FormProvider {...form}>
62 <FormProvider {...form}>
61 <form onSubmit={handleSubmit(onSubmit)}>
63 <form onSubmit={handleSubmit(onSubmit)}>
62− <PostOptions options={groups} emptyMessage="No groups found" />
64+ <PostOptions options={groups} emptyMessage="All groups already indexed" />
63 <div className='flex justify-between border-t border-zinc-300 py-3 mt-6'>
65 <div className='flex justify-between border-t border-zinc-300 py-3 mt-6'>
64 <Link to="/search" className='flex items-center rounded-lg text-base font-semibold text-rosy bg-rosy/30 border-2 border-transparent hover:border-rosy leading-none py-2 px-3 transition-colors'>
66 <Link to="/search" className='flex items-center rounded-lg text-base font-semibold text-rosy bg-rosy/30 border-2 border-transparent hover:border-rosy leading-none py-2 px-3 transition-colors'>
65 Back to Search
67 Back to Search
66 </Link>
68 </Link>
69+ {groups.length > 0 && (
67− <button type="submit" className='flex items-center rounded-lg text-base font-semibold text-linen bg-rosy disabled:bg-zinc-200 disabled:text-zinc-400 disabled:border-transparent border-2 border-transparent hover:border-linen/60 leading-none py-2 px-3 transition-colors' disabled={options.length === 0}>
70+ <button type="submit" className='flex items-center rounded-lg text-base font-semibold text-linen bg-rosy disabled:bg-zinc-200 disabled:text-zinc-400 disabled:border-transparent border-2 border-transparent hover:border-linen/60 leading-none py-2 px-3 transition-colors' disabled={options.length === 0}>
68− Publish
71+ Publish
69− </button>
72+ </button>
73+ )}
70 </div>
74 </div>
71 </form>
75 </form>
72 </FormProvider>
76 </FormProvider>
ui/src/pages/Search.tsx+3−3
@@ -40,9 +40,9 @@ export const Search = () => {
40 const size = parseInt(limit || '10', 10);
40 const size = parseInt(limit || '10', 10);
41 const pageInt = parseInt(page || '1', 10) - 1;
41 const pageInt = parseInt(page || '1', 10) - 1;
42 const start = pageInt * size;
42 const start = pageInt * size;
43− const { data } = useQuery<unknown, unknown, SearchType>(`lookup-${selected}-${lookup}-${size}-${start}`, () => api.scry<SearchType>({
43+ const { data } = useQuery<unknown, unknown, SearchType>(`lookup-${selected}-${size}-${start}-${lookup}`, () => api.scry<SearchType>({
44 app: 'sphinx',
44 app: 'sphinx',
45− path: `/lookup/${selected}/${encodeLookup(lookup)}/${start}/${size}`
45+ path: `/lookup/${selected}/${start}/${size}/${encodeLookup(lookup)}`
46 }), {
46 }), {
47 enabled: !!lookup,
47 enabled: !!lookup,
48 keepPreviousData: true
48 keepPreviousData: true
@@ -56,7 +56,7 @@ export const Search = () => {
56 })
56 })
57 }, {
57 }, {
58 onSuccess: () => {
58 onSuccess: () => {
59− queryClient.invalidateQueries(`lookup-${selected}-${lookup}-${size}-${start}`)
59+ queryClient.invalidateQueries(`lookup-${selected}-${size}-${start}-${lookup}`)
60 }
60 }
61 });
61 });
62
62
ui/src/state/apps.ts+13−2
@@ -1,7 +1,7 @@
1import { Charge, ChargeUpdateInitial, getVats, scryCharges, Vat, Vats } from "@urbit/api";
1import { Charge, ChargeUpdateInitial, getVats, scryCharges, Vat, Vats } from "@urbit/api";
2import { useQuery } from "react-query"
2import { useQuery } from "react-query"
3import api from "../api";
3import api from "../api";
4−import { Post } from "../types/sphinx";
4+import { Post, Search } from "../types/sphinx";
5
5
6function getAppPost(app: string, vat: Vat, charge: Charge): Post {
6function getAppPost(app: string, vat: Vat, charge: Charge): Post {
7 const ship = vat.arak.rail?.publisher || vat.arak.rail?.ship || `~${window.ship}`;
7 const ship = vat.arak.rail?.publisher || vat.arak.rail?.ship || `~${window.ship}`;
@@ -19,6 +19,17 @@ function getAppPost(app: string, vat: Vat, charge: Charge): Post {
19export const useApps = () => {
19export const useApps = () => {
20 const { data: vats } = useQuery('vats', () => api.scry<Vats>(getVats));
20 const { data: vats } = useQuery('vats', () => api.scry<Vats>(getVats));
21 const { data: charges } = useQuery('charges', () => api.scry<ChargeUpdateInitial>(scryCharges));
21 const { data: charges } = useQuery('charges', () => api.scry<ChargeUpdateInitial>(scryCharges));
22+ const { data } = useQuery('app-listings', () => api.scry<Search>({
23+ app: 'sphinx',
24+ path: '/lookup/app/0/999'
25+ }));
22
26
27+ if (!vats || !charges || !data) {
28+ return [];
29+ }
30+
31+ return Object.entries(charges.initial)
32+ .filter(([k]) => k in vats)
23− return vats && charges ? Object.entries(charges.initial).filter(([k]) => k in vats).map(([k,v]) => ({ key: k, post: getAppPost(k, vats[k], v) })) : [];
33+ .map(([k,v]) => ({ key: k, post: getAppPost(k, vats[k], v) }))
34+ .filter(({ post }) => !data.listings.some(l => l.post.link === post.link || l.post.title === post.title));
24}
35}
ui/src/state/groups.ts+13−7
@@ -1,25 +1,31 @@
1import { GroupUpdateInitial, MetadataUpdateInitial } from "@urbit/api";
1import { GroupUpdateInitial, MetadataUpdateInitial } from "@urbit/api";
2−import { useQuery, useQueryClient } from "react-query"
2+import { useQuery } from "react-query"
3import api from "../api"
3import api from "../api"
4−import { PostOption } from "../types/sphinx";
4+import { PostOption, PostType, Search } from "../types/sphinx";
5
5
6
6
7
7
8export const useGroups = (): PostOption[] => {
8export const useGroups = (): PostOption[] => {
9 const { data } = useQuery('metadata', () => api.subscribeOnce<{ 'metadata-update': MetadataUpdateInitial }>('metadata-store', '/all'));
9 const { data } = useQuery('metadata', () => api.subscribeOnce<{ 'metadata-update': MetadataUpdateInitial }>('metadata-store', '/all'));
10 const { data: groupData } = useQuery('groups', () => api.subscribeOnce<{ groupUpdate: GroupUpdateInitial }>('group-store', '/groups'));
10 const { data: groupData } = useQuery('groups', () => api.subscribeOnce<{ groupUpdate: GroupUpdateInitial }>('group-store', '/groups'));
11+ const { data: d } = useQuery('group-listings', () => api.scry<Search>({
12+ app: 'sphinx',
13+ path: '/lookup/group/0/999'
14+ }));
11
15
12− //web+urbitgraph://group/~nocsyx-lassul/celestial-systems
13− console.log(data, groupData)
16+ if (!data || !groupData || !d) {
17+ return [];
18+ }
14
19
15− return data && groupData ? Object.entries(data['metadata-update'].associations)
20+ return Object.entries(data['metadata-update'].associations)
16 .filter(([k,v]) => v['app-name'] === 'groups' && 'open' in (groupData.groupUpdate.initial[v.resource]?.policy || {}))
21 .filter(([k,v]) => v['app-name'] === 'groups' && 'open' in (groupData.groupUpdate.initial[v.resource]?.policy || {}))
17 .map(([k,v]) => ({ key: k, post: {
22 .map(([k,v]) => ({ key: k, post: {
18− type: 'group',
23+ type: 'group' as PostType,
19 title: v.metadata.title,
24 title: v.metadata.title,
20 link: v.group.replace('/ship/', 'web+urbitgraph://group/'),
25 link: v.group.replace('/ship/', 'web+urbitgraph://group/'),
21 image: v.metadata.picture,
26 image: v.metadata.picture,
22 description: v.metadata.description,
27 description: v.metadata.description,
23 tags: ['group']
28 tags: ['group']
24− }})) : [];
29+ }}))
30+ .filter(({ post }) => !d.listings.some(l => l.post.link === post.link || l.post.title === post.title));
25}
31}