on main help sign in
fix some bugs in star chart and add locked stars tab
15920bdJohn Hyde
README.md+1
@@ -38,6 +38,7 @@ Regardless of what you run to develop, Vite will hot-reload code changes as you
384. Bump the `version` in `desk.docket-0`.
384. Bump the `version` in `desk.docket-0`.
393. Install the desk
393. Install the desk
40 1. From the `ui` folder: `npm run install:desk`
40 1. From the `ui` folder: `npm run install:desk`
41+ 2. (first time only, on dev ship): `|install our %astrolabe`
41 2. From the distribution ship's dojo: `:treaty|unpublish %astrolabe`
42 2. From the distribution ship's dojo: `:treaty|unpublish %astrolabe`
42 2. From middleman or distribution ship's dojo: `|commit %astrolabe`
43 2. From middleman or distribution ship's dojo: `|commit %astrolabe`
43 3. (if using a comet as a middleman) `|public %astrolabe`
44 3. (if using a comet as a middleman) `|public %astrolabe`
base-desk/mar/kelvin.hoonnew file+28
@@ -0,0 +1,28 @@
1+|_ kal=waft:clay
2+++ grow
3+ |%
4+ ++ mime `^mime`[/text/x-kelvin (as-octs:mimes:html hoon)]
5+ ++ noun kal
6+ ++ hoon
7+ %+ rap 3
8+ %+ turn
9+ %+ sort
10+ ~(tap in (waft-to-wefts:clay kal))
11+ |= [a=weft b=weft]
12+ ?: =(lal.a lal.b)
13+ (gte num.a num.b)
14+ (gte lal.a lal.b)
15+ |= =weft
16+ (rap 3 '[%' (scot %tas lal.weft) ' ' (scot %ud num.weft) ']\0a' ~)
17+ ::
18+ ++ txt (to-wain:format hoon)
19+ --
20+++ grab
21+ |%
22+ ++ noun waft:clay
23+ ++ mime
24+ |= [=mite len=@ud tex=@]
25+ (cord-to-waft:clay tex)
26+ --
27+++ grad %noun
28+--
desk/app/astrolabe.hoon+12−64
@@ -1,42 +1,12 @@
1/- *astrolabe
1/- *astrolabe
2+/+ *astrolabe, *search, slib=state
2−/+ *astrolabe, *search, *mip, naive, default-agent, dbug, agentio
3+/+ *mip, naive, default-agent, dbug, agentio
3/$ udon-to-docu %udon %docu
4/$ udon-to-docu %udon %docu
4|%
5|%
5−+$ versioned-state
6− $% state-0
7− state-1
8− state-2
9− state-3
10− ==
11−+$ state-0
12− $: %0
13− spa=spawned
14− ==
15−+$ state-1
16− $: %1
17− fropoints-1
18− ==
19−+$ state-2
20− $: %2
21− spam=spawn-mip
22− fropoints-1
23− ==
24−+$ state-3
25− $: %3
26− prev-spo=(map ship ship) :: so we know who the old sponsor was when sponsor changes
27− spam=spawn-mip
28− fropoints-1
29− ==
30−::
31−+$ fropoints-1
32− $: fopoints=opoints :: forward ordered points
33− ropoints=opoints :: reversed ordered points, e.g. .~palnet-sampel
34− ==
35−+$ spawned (jug ship ship)
36+$ card card:agent:gall
6+$ card card:agent:gall
37--
7--
38%- agent:dbug
8%- agent:dbug
39−=| state-3
9+=| state-latest
40=* state -
10=* state -
41^- agent:gall
11^- agent:gall
42=<
12=<
@@ -55,15 +25,15 @@
55 |= old-state=vase
25 |= old-state=vase
56 ^- (quip card _this)
26 ^- (quip card _this)
57 =/ old !<(versioned-state old-state)
27 =/ old !<(versioned-state old-state)
58− =^ cards-01 old
28+ =/ [cards-01=(list card) new=state-latest]
59− ?. ?=(?(%0 %1 %2) -.old) `old
29+ ?. ?=(?(%0 %1 %2 %3) -.old) `old
60 (on-naive-state:hc get-nas:hc)
30 (on-naive-state:hc get-nas:hc)
61− ?> ?=(%3 -.old)
31+ ?> ?=(%4 -.new)
62 =/ cards=(list card)
32 =/ cards=(list card)
63 =/ ug-vase !>([/astrolabe '/apps/astrolabe/#'])
33 =/ ug-vase !>([/astrolabe '/apps/astrolabe/#'])
64 [%pass /monkey-ug %agent [our.bowl %monkey] %poke [%bind-ug ug-vase]]~
34 [%pass /monkey-ug %agent [our.bowl %monkey] %poke [%bind-ug ug-vase]]~
65 =. cards (weld cards-01 cards)
35 =. cards (weld cards-01 cards)
66− [cards this(state old)]
36+ [cards this(state new)]
67++ on-poke on-poke:def
37++ on-poke on-poke:def
68++ on-watch on-watch:def
38++ on-watch on-watch:def
69++ on-leave on-leave:def
39++ on-leave on-leave:def
@@ -72,11 +42,14 @@
72 |= =path
42 |= =path
73 ^- (unit (unit cage))
43 ^- (unit (unit cage))
74 ?+ path (on-peek:def path)
44 ?+ path (on-peek:def path)
45+ [%x %nop ~]
46+ ``noun+!>(~)
75 [%x %point @ ~]
47 [%x %point @ ~]
76 ``astrolabe-point+!>((get-point:hc &3.path))
48 ``astrolabe-point+!>((get-point:hc &3.path))
77 [%x %point @ %spawned ?(~ [spawned-filter ~])]
49 [%x %point @ %spawned ?(~ [spawned-filter ~])]
78 =/ =ship `@p`(slav %p &3.path)
50 =/ =ship `@p`(slav %p &3.path)
79− =/ arg ?~(t.t.t.t.path %all i.t.t.t.t.path)
51+ =/ filter t.t.t.t.path
52+ =/ arg ?~(filter %all -.filter)
80 ``astrolabe-point-set+!>((get-spawned-points:hc ship arg))
53 ``astrolabe-point-set+!>((get-spawned-points:hc ship arg))
81 [%x %search %patp @ ?(~ [%narrow ~])]
54 [%x %search %patp @ ?(~ [%narrow ~])]
82 =/ =search-text (trip &4.path)
55 =/ =search-text (trip &4.path)
@@ -158,32 +131,7 @@
158 |= [child=ship nas=^state:naive]
131 |= [child=ship nas=^state:naive]
159 ^- _state
132 ^- _state
160 =/ =npoint (get-npoint-from-nas child nas)
133 =/ =npoint (get-npoint-from-nas child nas)
161− =/ parent (^sein:title child)
134+ (put-in-spawn-mip:slib child npoint state)
162− ?: =(parent child) state
163− ?: (is-npoint-locked npoint) state
164− =/ pdata (pdata:smel (pmeta:smel child npoint) ~)
165− =* spo sponsor.net.npoint
166− =/ spo-not-par &(has.spo !=(parent who.spo))
167− =? state spo-not-par
168− =/ prev (~(get by prev-spo) child)
169− =? spam &(?=(^ prev) !=(u.prev who.spo))
170− (~(del bi spam) u.prev child)
171− =. prev-spo
172− %+ ~(put by prev-spo)
173− child
174− who.spo
175− =. spam
176− %^ ~(put bi-meta spam)
177− who.spo
178− child
179− pdata
180− state
181− =. spam
182− %^ ~(put bi-meta spam)
183− parent
184− child
185− pdata
186− state
187::
135::
188++ on-naive-state
136++ on-naive-state
189 |= nas=^state:naive
137 |= nas=^state:naive
desk/desk.sealnew file+7
@@ -0,0 +1,7 @@
1+:- :~ [%watch & %azimuth /event]
2+ [%reads %gall `%x `%azimuth /]
3+ [%reads %clay `%u ~ /]
4+ [%reads %clay `%x ~ /]
5+ [%reads %ames `%x ~ /peers]
6+ ==
7+~
desk/lib/astrolabe.hoon+1−2
@@ -1,5 +1,5 @@
1/- sur=astrolabe
1/- sur=astrolabe
2−/+ azimuth, naive, mip
2+/+ azimuth, naive
3=< [sur .]
3=< [sur .]
4=, sur
4=, sur
5|%
5|%
@@ -25,7 +25,6 @@
25 ^- ?
25 ^- ?
26 (rev-f lte a b)
26 (rev-f lte a b)
27::
27::
28−+$ opoints (tree [@ @]) :: ordered points [ship ~]
29++ ors ((on @q @) rpor)
28++ ors ((on @q @) rpor)
30++ or-meta ((on @p tape) por:naive)
29++ or-meta ((on @p tape) por:naive)
31++ bi-meta
30++ bi-meta
desk/lib/state.hoonnew file+23
@@ -0,0 +1,23 @@
1+/- *astrolabe
2+/+ *astrolabe
3+|%
4+++ put-in-spawn-mip
5+ |= [child=ship =npoint s=state-latest]
6+ ^- _s
7+ =/ parent (^sein:title child)
8+ ?: =(parent child) s
9+ ?: (is-npoint-locked npoint) s
10+ =/ pdata (pdata:smel (pmeta:smel child npoint) ~)
11+ =* spo sponsor.net.npoint
12+ =/ prev (~(gut by prev-spo.s) child parent)
13+ =/ unsponsored-state
14+ =. prev-spo.s (~(del by prev-spo.s) child)
15+ =. spam.s (~(del bi spam.s) prev child)
16+ s
17+ ?. has.spo unsponsored-state
18+ =? s !=(prev who.spo)
19+ unsponsored-state
20+ =. prev-spo.s (~(put by prev-spo.s) child who.spo)
21+ =. spam.s (~(put bi spam.s) who.spo child pdata)
22+ s
23+--
desk/mar/seal.hoonnew file+12
@@ -0,0 +1,12 @@
1+|_ dat=@
2+++ grow
3+ |%
4+ ++ mime [/text (as-octs:mimes:html dat)]
5+ --
6+++ grab
7+ |%
8+ ++ mime |=([p=mite q=octs] q.q)
9+ ++ noun @
10+ --
11+++ grad %mime
12+--
desk/sur/astrolabe.hoon+43−1
@@ -1,5 +1,48 @@
1/+ naive, *mip
1/+ naive, *mip
2|%
2|%
3++$ versioned-state
4+ $% state-0
5+ state-1
6+ state-2
7+ state-3
8+ state-4
9+ ==
10++$ state-latest state-4
11++$ state-0
12+ $: %0
13+ spa=spawned
14+ ==
15++$ state-1
16+ $: %1
17+ fropoints-1
18+ ==
19++$ state-2
20+ $: %2
21+ spam=spawn-mip
22+ fropoints-1
23+ ==
24++$ state-3
25+ $: %3
26+ prev-spo=(map ship ship) :: so we know who the old sponsor was when sponsor changes
27+ spam=spawn-mip
28+ fropoints-1
29+ ==
30++$ state-4
31+ $: %4
32+ bump=@ud :: bump to update state without changing the type
33+ prev-spo=(map ship ship) :: so we know who the old sponsor was when sponsor changes
34+ spam=spawn-mip
35+ fropoints-1
36+ ==
37+::
38++$ fropoints-1
39+ $: fopoints=opoints :: forward ordered points
40+ ropoints=opoints :: reversed ordered points, e.g. .~palnet-sampel
41+ ==
42++$ spawned (jug ship ship)
43++$ spawn-mip (mip ship ship tape)
44++$ opoints (tree [@ @]) :: ordered points [ship ~]
45+::
3+$ npoint point:naive
46+$ npoint point:naive
4++ unpoint (unit npoint)
47++ unpoint (unit npoint)
5+$ point
48+$ point
@@ -11,6 +54,5 @@
11 ==
54 ==
12+$ spawned-filter ?(%all %locked %unlocked)
55+$ spawned-filter ?(%all %locked %unlocked)
13::
56::
14−+$ spawn-mip (mip ship ship tape)
15::
57::
16--
58--
desk/tests/lib/state.hoonnew file+59
@@ -0,0 +1,59 @@
1+/- *astrolabe
2+/+ *astrolabe, *state, *test
3+|%
4+++ test-put-in-spawn-mip
5+ =| state=state-latest
6+ =/ moved-to-bus=npoint
7+ =< .(who.sponsor.net ~bus)
8+ *npoint
9+ =/ moved-to-hec=npoint
10+ =< .(who.sponsor.net ~hec)
11+ *npoint
12+ ;: weld
13+ %+ expect-eq
14+ !> :-
15+ `~zod :: new prev-spo
16+ %.y :: spawn-mip has something under ~zod
17+ !> =- :-
18+ (~(get by prev-spo) ~marzod)
19+ (~(has by spam) ~zod)
20+ (put-in-spawn-mip ~marzod *npoint state)
21+ ::
22+ %+ expect-eq
23+ !> :*
24+ `~hec :: new prev-spo
25+ %.n :: nothing under ~zod
26+ %.n :: nothing under ~bus
27+ %.y :: something under ~hec
28+ ==
29+ !>
30+ =. state (put-in-spawn-mip ~marzod *npoint state)
31+ =. state (put-in-spawn-mip ~marzod moved-to-bus state)
32+ =+ (put-in-spawn-mip ~marzod moved-to-hec state)
33+ :*
34+ (~(get by prev-spo) ~marzod)
35+ (~(has by spam) ~zod)
36+ (~(has by spam) ~bus)
37+ (~(has by spam) ~hec)
38+ ==
39+ ::
40+ %+ expect-eq
41+ !> :*
42+ `~zod :: new prev-spo
43+ %.y :: something under ~zod
44+ %.n :: nothing under ~bus
45+ %.n :: something under ~hec
46+ ==
47+ !>
48+ =. state (put-in-spawn-mip ~marzod *npoint state)
49+ =. state (put-in-spawn-mip ~marzod moved-to-bus state)
50+ =. state (put-in-spawn-mip ~marzod moved-to-hec state)
51+ =+ (put-in-spawn-mip ~marzod *npoint state)
52+ :*
53+ (~(get by prev-spo) ~marzod)
54+ (~(has by spam) ~zod)
55+ (~(has by spam) ~bus)
56+ (~(has by spam) ~hec)
57+ ==
58+ ==
59+--
ui/scraps/scry thoughtsdeleted−5
@@ -1,5 +0,0 @@
1−:: get list of group ids
2−.^((set [ship term]) %gy /(scot %p our)/group-store/(scot %da now)/groups)
3−.^(* %gx /(scot %p our)/group-store/(scot %da now)/groups/ship/~poster-hoster-midlev-mindyr/astrolabe/noun)
4−
5−web+urbitgraph://astrolabe/ship/~midlev-mindyr
ui/src/components/ShipListing.svelte+3−5
@@ -12,8 +12,9 @@
12 export let differentiateContacts = false;
12 export let differentiateContacts = false;
13
13
14 $: patp = normalizeId(ship.patp);
14 $: patp = normalizeId(ship.patp);
15+ $: contact = $store.contacts[ship.patp];
15 $: borderClass = differentiateContacts ? (
16 $: borderClass = differentiateContacts ? (
16− 'border-l-8 ' + (Object.keys(ship).length > 1 ? 'border-gold' : 'border-gray-300')
17+ 'border-l-8 ' + (contact ? 'border-gold' : 'border-gray-300')
17 ) : '';
18 ) : '';
18
19
19 function handleClick() {
20 function handleClick() {
@@ -29,16 +30,13 @@ on:click
29>
30>
30 <div class="flex p-4 items-center gap-x-4">
31 <div class="flex p-4 items-center gap-x-4">
31 <Sigil {patp} size={48} useNew noShrink />
32 <Sigil {patp} size={48} useNew noShrink />
32− <!-- {#if ship.avatar}
33− <img src={ship.avatar} class="h-12 w-12 mr-4" />
34− {/if} -->
35 <p class="break-words grow">
33 <p class="break-words grow">
36 <span class="align-middle mr-1">
34 <span class="align-middle mr-1">
37 {patp}
35 {patp}
38 </span>
36 </span>
39 <PalStatusIndicator status={getPalStatus($store.pals, patp)} class="inline" />
37 <PalStatusIndicator status={getPalStatus($store.pals, patp)} class="inline" />
40 <br/>
38 <br/>
41− {ship.nickname ? `(${ship.nickname})` : ''}
39+ {contact?.nickname ? `(${contact.nickname})` : ''}
42 </p>
40 </p>
43 </div>
41 </div>
44</div>
42</div>
ui/src/components/StarChart.svelte+6−1
@@ -23,6 +23,7 @@
23 let firstRender = true;
23 let firstRender = true;
24 let mouseDown = false;
24 let mouseDown = false;
25 let isDragging = false;
25 let isDragging = false;
26+ let stoppedDragging = Date.now();
26
27
27 function sigma(container: HTMLElement, params: any = {}) {
28 function sigma(container: HTMLElement, params: any = {}) {
28 try {
29 try {
@@ -38,7 +39,9 @@
38 });
39 });
39
40
40 s.on('clickNode', ({ node }) => {
41 s.on('clickNode', ({ node }) => {
42+ if (!isDragging && 100 < Date.now() - stoppedDragging) {
41− push(linkToShip(node));
43+ push(linkToShip(node));
44+ }
42 });
45 });
43 s.on('afterRender', () => {
46 s.on('afterRender', () => {
44 if (firstRender) {
47 if (firstRender) {
@@ -58,6 +61,8 @@
58 mc.on('mouseup', () => {
61 mc.on('mouseup', () => {
59 if (!isDragging) {
62 if (!isDragging) {
60 clearHighlight();
63 clearHighlight();
64+ } else {
65+ stoppedDragging = Date.now();
61 }
66 }
62 mouseDown = false;
67 mouseDown = false;
63 isDragging = false;
68 isDragging = false;
ui/src/components/search/SearchBar.svelte+19−9
@@ -12,8 +12,16 @@
12 export let sigilQuery: SigilQuery = new SigilQuery('planet');
12 export let sigilQuery: SigilQuery = new SigilQuery('planet');
13 sigilQuery.urlString = search;
13 sigilQuery.urlString = search;
14 export let searchMode: ('patp' | 'sigil') = 'patp';
14 export let searchMode: ('patp' | 'sigil') = 'patp';
15+ export let allowSigilSearch: boolean = true;
15− export let placeholderText = "Search by @p or #. '*' matches any character";
16+ let defaultPlaceholderText = "Search by @p or #. '*' matches any character";
17+ export let placeholderText = defaultPlaceholderText;
16
18
19+ $: {
20+ placeholderText = placeholderText ? placeholderText : defaultPlaceholderText;
21+ }
22+ $: {
23+ searchMode = allowSigilSearch ? searchMode : 'patp';
24+ }
17 $: showSigilInput = searchMode == 'sigil';
25 $: showSigilInput = searchMode == 'sigil';
18
26
19 let bouncySearch: string = search;
27 let bouncySearch: string = search;
@@ -113,13 +121,15 @@
113 value={search}
121 value={search}
114 autofocus
122 autofocus
115 />
123 />
124+ {#if allowSigilSearch}
116− <button
125+ <button
117− on:click={openSigilInput}
126+ on:click={openSigilInput}
118− class="absolute top-1 right-1 w-8 h-8 {buttonClasses}"
127+ class="absolute top-1 right-1 w-8 h-8 {buttonClasses}"
119− >
128+ >
120− <Symbol components={'gci.lvf.lhf.lbhb.atrf4.al3.cbl2lf.cbl2mb'.split('.')} size={32}
129+ <Symbol components={'gci.lvf.lhf.lbhb.atrf4.al3.cbl2lf.cbl2mb'.split('.')} size={32}
121− altBgColor="transparent"
130+ altBgColor="transparent"
122− />
131+ />
123− </button>
132+ </button>
133+ {/if}
124 {/if}
134 {/if}
125</div>
135</div>
ui/src/components/ship_view/AzimuthDetails.sveltenew file+92
@@ -0,0 +1,92 @@
1+<script lang="ts">
2+ import { clan, patp2dec } from 'urbit-ob';
3+ import { getPoint, getSpawnedPoints } from 'lib/api';
4+ import { generateParentChain, processPointInfo } from 'lib/ship';
5+ import TooltipAndDocLink from '@/common/TooltipAndDocLink.svelte';
6+ import EthAddressLink from '@/common/EthAddressLink.svelte';
7+ import ShipChain from './ShipChain.svelte';
8+
9+ export let patp: string;
10+ export let pointInfo: any = {};
11+
12+
13+ $: shipClass = clan(patp);
14+ $: azPoint = ['galaxy', 'star', 'planet'].includes(shipClass);
15+</script>
16+
17+{#if azPoint}
18+ {#if shipClass !== 'galaxy'}
19+ <p>
20+ {#if pointInfo.sponsorChain && pointInfo.sponsorChain.length > 0}
21+ <p>
22+ {pointInfo.sponsorChain.length === 1 ? 'Sponsor:' : 'Sponsor Chain:'}
23+ <ShipChain shipChain={pointInfo.sponsorChain}></ShipChain>
24+ </p>
25+ {:else}
26+ Unsponsored
27+ {/if}
28+ </p>
29+ {/if}
30+ <p>
31+ <TooltipAndDocLink
32+ text="Number of times this ship's keys have been set. Must be at least 1 to use the network."
33+ doc="keys"
34+ class="inline"
35+ >
36+ Key Revision:
37+ {pointInfo.life}
38+ </TooltipAndDocLink>
39+ </p>
40+ <p>
41+ <TooltipAndDocLink
42+ text="Number of times this ship has breached."
43+ doc="keys"
44+ class="inline"
45+ >
46+ Factory Resets:
47+ {pointInfo.rift}
48+ </TooltipAndDocLink>
49+ </p>
50+ {#if pointInfo.proxies}
51+ <p>
52+ <span>
53+ Owner:
54+ <EthAddressLink address={pointInfo.proxies.owner.address} />
55+ </span>
56+ </p>
57+ <p>
58+ <span>
59+ Management Proxy:
60+ <EthAddressLink address={pointInfo.proxies['management-proxy'].address}>
61+ <span class="text-gray-700">not set</span>
62+ </EthAddressLink>
63+ </span>
64+ </p>
65+ <p>
66+ <span>
67+ Spawn Proxy:
68+ <EthAddressLink address={pointInfo.proxies['spawn-proxy'].address}>
69+ <span class="text-gray-700">not set</span>
70+ </EthAddressLink>
71+ </span>
72+ </p>
73+ <p>
74+ <span>
75+ Transfer Proxy:
76+ <EthAddressLink address={pointInfo.proxies['transfer-proxy'].address}>
77+ <span class="text-gray-700">not set</span>
78+ </EthAddressLink>
79+ </span>
80+ </p>
81+ {#if shipClass === 'galaxy'}
82+ <p>
83+ <span>
84+ Voting Proxy:
85+ <EthAddressLink address={pointInfo.proxies['voting-proxy'].address}>
86+ [not set]
87+ </EthAddressLink>
88+ </span>
89+ </p>
90+ {/if}
91+ {/if}
92+{/if}
ui/src/components/ship_view/ShipChildrenTabs.svelte+35−4
@@ -2,7 +2,7 @@
2 import { clan } from 'urbit-ob';
2 import { clan } from 'urbit-ob';
3
3
4 import { normalizeId, filterIdsForChildMoons } from 'lib/id';
4 import { normalizeId, filterIdsForChildMoons } from 'lib/id';
5− import { getSpawnedPoints } from 'lib/api';
5+ import { getSpawnedPoints, getUnlockedSpawnedPoints, getLockedSpawnedPoints } from 'lib/api';
6 import store from 'stores/store';
6 import store from 'stores/store';
7 import ShipListings from '@/ShipListings.svelte';
7 import ShipListings from '@/ShipListings.svelte';
8
8
@@ -11,7 +11,10 @@
11
11
12 let rawSpawnedPointsPromise: any;
12 let rawSpawnedPointsPromise: any;
13 let rawSpawnedPoints: any = null;
13 let rawSpawnedPoints: any = null;
14+ let rawLockedPointsPromise: any;
15+ let rawLockedPoints: any = null;
14 let spawnedPoints: string[] = [];
16 let spawnedPoints: string[] = [];
17+ let lockedPoints: string[] = [];
15
18
16 $: shipClass = clan(patp);
19 $: shipClass = clan(patp);
17 $: azPoint = ['galaxy', 'star', 'planet'].includes(shipClass);
20 $: azPoint = ['galaxy', 'star', 'planet'].includes(shipClass);
@@ -19,8 +22,19 @@
19 $: spawnableClassPlural = !canSpawnPoints ? '' : (shipClass === 'galaxy' ? 'Star' : 'Planet');
22 $: spawnableClassPlural = !canSpawnPoints ? '' : (shipClass === 'galaxy' ? 'Star' : 'Planet');
20 $: {
23 $: {
21 rawSpawnedPoints = null;
24 rawSpawnedPoints = null;
25+ rawLockedPoints = null;
22 if (canSpawnPoints) {
26 if (canSpawnPoints) {
23− rawSpawnedPointsPromise = getSpawnedPoints(patp);
27+ let galaxy = shipClass === 'galaxy';
28+ let getSpawnedPointsFunc = galaxy ? getUnlockedSpawnedPoints : getSpawnedPoints;
29+ if (galaxy) {
30+ rawLockedPointsPromise = getLockedSpawnedPoints(patp);
31+ rawLockedPointsPromise.then((info) => {
32+ rawLockedPoints = info;
33+ }).catch((error) => {
34+ rawLockedPoints = { error };
35+ });
36+ }
37+ rawSpawnedPointsPromise = getSpawnedPointsFunc(patp);
24 rawSpawnedPointsPromise.then((info) => {
38 rawSpawnedPointsPromise.then((info) => {
25 rawSpawnedPoints = info;
39 rawSpawnedPoints = info;
26 }).catch((error) => {
40 }).catch((error) => {
@@ -34,6 +48,12 @@
34 spawnedPoints = rawSpawnedPoints?.points.map(patpToShip);
48 spawnedPoints = rawSpawnedPoints?.points.map(patpToShip);
35 }
49 }
36 }
50 }
51+ $: {
52+ lockedPoints = [];
53+ if (rawLockedPoints?.points) {
54+ lockedPoints = rawLockedPoints?.points.map(patpToShip);
55+ }
56+ }
37 $: trueSpawnedCount = spawnedCount || spawnedPoints.length;
57 $: trueSpawnedCount = spawnedCount || spawnedPoints.length;
38 $: spawnedTab = {
58 $: spawnedTab = {
39 name: 'Spawned',
59 name: 'Spawned',
@@ -42,6 +62,13 @@
42 points: spawnedPoints,
62 points: spawnedPoints,
43 count: trueSpawnedCount,
63 count: trueSpawnedCount,
44 };
64 };
65+ $: lockedTab = {
66+ name: 'Locked',
67+ plural: 'Locked ' + spawnableClassPlural + (lockedPoints.length == 1 ? '' : 's'),
68+ promise: rawLockedPointsPromise,
69+ points: lockedPoints,
70+ count: lockedPoints.length,
71+ };
45 $: moons = filterIdsForChildMoons($store.peers, patp).map(patpToShip);
72 $: moons = filterIdsForChildMoons($store.peers, patp).map(patpToShip);
46 $: moonsTab = {
73 $: moonsTab = {
47 name: 'Moons',
74 name: 'Moons',
@@ -57,6 +84,9 @@
57 if (spawnedCount !== undefined || spawnedPoints.length > 0) {
84 if (spawnedCount !== undefined || spawnedPoints.length > 0) {
58 tabs.push(spawnedTab);
85 tabs.push(spawnedTab);
59 }
86 }
87+ if (lockedPoints.length > 0) {
88+ tabs.push(lockedTab);
89+ }
60 if (azPoint) {
90 if (azPoint) {
61 tabs.push(moonsTab);
91 tabs.push(moonsTab);
62 }
92 }
@@ -82,8 +112,8 @@
82 </div>
112 </div>
83 {/if}
113 {/if}
84 {#if tab}
114 {#if tab}
85− <div class="mt-2">
115+ <div>
86− <h3 class="text-lg">
116+ <h3 class="text-lg m-2">
87 {#if tab.count}
117 {#if tab.count}
88 {tab.count} {tab.plural}:
118 {tab.count} {tab.plural}:
89 {:else}
119 {:else}
@@ -97,6 +127,7 @@
97 <ShipListings
127 <ShipListings
98 ships={tab.points}
128 ships={tab.points}
99 linkToShips
129 linkToShips
130+ differentiateContacts
100 />
131 />
101 {/await}
132 {/await}
102 </div>
133 </div>
ui/src/components/ship_view/ShipView.svelte+3−75
@@ -13,6 +13,7 @@
13 import LoadingSpinner from '@/common/LoadingSpinner.svelte';
13 import LoadingSpinner from '@/common/LoadingSpinner.svelte';
14 import CollapsibleContent from '@/CollapsibleContent.svelte';
14 import CollapsibleContent from '@/CollapsibleContent.svelte';
15 import ShipChain from './ShipChain.svelte';
15 import ShipChain from './ShipChain.svelte';
16+ import AzimuthDetails from './AzimuthDetails.svelte';
16 import ShipChildrenTabs from './ShipChildrenTabs.svelte';
17 import ShipChildrenTabs from './ShipChildrenTabs.svelte';
17 import ProfileShipViewExtension from '~/components/extensions/ProfileShipViewExtension.svelte';
18 import ProfileShipViewExtension from '~/components/extensions/ProfileShipViewExtension.svelte';
18 import PalsShipViewExtension from '@/pals/PalsShipViewExtension.svelte';
19 import PalsShipViewExtension from '@/pals/PalsShipViewExtension.svelte';
@@ -113,81 +114,8 @@
113 {#await rawPointInfoPromise}
114 {#await rawPointInfoPromise}
114 <LoadingSpinner spinnerClass="text-black" />
115 <LoadingSpinner spinnerClass="text-black" />
115 {:then}
116 {:then}
116− {#if shipClass !== 'galaxy'}
117+ <AzimuthDetails {patp} {pointInfo}></AzimuthDetails>
117− <p>
118+
118− {#if pointInfo.sponsorChain && pointInfo.sponsorChain.length > 0}
119− <p>
120− {pointInfo.sponsorChain.length === 1 ? 'Sponsor:' : 'Sponsor Chain:'}
121− <ShipChain shipChain={pointInfo.sponsorChain}></ShipChain>
122− </p>
123− {:else}
124− Unsponsored
125− {/if}
126− </p>
127− {/if}
128− <p>
129− <TooltipAndDocLink
130− text="Number of times this ship's keys have been set. Must be at least 1 to use the network."
131− doc="keys"
132− class="inline"
133− >
134− Key Revision:
135− {pointInfo.life}
136− </TooltipAndDocLink>
137− </p>
138− <p>
139− <TooltipAndDocLink
140− text="Number of times this ship has breached."
141− doc="keys"
142− class="inline"
143− >
144− Factory Resets:
145− {pointInfo.rift}
146− </TooltipAndDocLink>
147− </p>
148− {#if pointInfo.proxies}
149− <p>
150− <span>
151− Owner:
152− <EthAddressLink address={pointInfo.proxies.owner.address} />
153− </span>
154− </p>
155− <p>
156− <span>
157− Management Proxy:
158− <EthAddressLink address={pointInfo.proxies['management-proxy'].address}>
159− <span class="text-gray-700">not set</span>
160− </EthAddressLink>
161− </span>
162− </p>
163− <p>
164− <span>
165− Spawn Proxy:
166− <EthAddressLink address={pointInfo.proxies['spawn-proxy'].address}>
167− <span class="text-gray-700">not set</span>
168− </EthAddressLink>
169− </span>
170− </p>
171− <p>
172− <span>
173− Transfer Proxy:
174− <EthAddressLink address={pointInfo.proxies['transfer-proxy'].address}>
175− <span class="text-gray-700">not set</span>
176− </EthAddressLink>
177− </span>
178− </p>
179− {#if shipClass === 'galaxy'}
180− <p>
181− <span>
182− Voting Proxy:
183− <EthAddressLink address={pointInfo.proxies['voting-proxy'].address}>
184− [not set]
185− </EthAddressLink>
186− </span>
187− </p>
188− {/if}
189− {/if}
190−
191 <!-- {#if value && value.point}
119 <!-- {#if value && value.point}
192 <pre class="text-sm overflow-scroll">
120 <pre class="text-sm overflow-scroll">
193 Raw Info:{JSON.stringify(rawPointInfo, null, 2)}
121 Raw Info:{JSON.stringify(rawPointInfo, null, 2)}
ui/src/lib/api.ts+8
@@ -24,6 +24,14 @@ export function getSpawnedPoints(patp: string): Promise<any> {
24 return scry<any>(`/point/${patp}/spawned`);
24 return scry<any>(`/point/${patp}/spawned`);
25}
25}
26
26
27+export function getLockedSpawnedPoints(patp: string): Promise<any> {
28+ return scry<any>(`/point/${patp}/spawned/locked`);
29+}
30+
31+export function getUnlockedSpawnedPoints(patp: string): Promise<any> {
32+ return scry<any>(`/point/${patp}/spawned/unlocked`);
33+}
34+
27export function getPeers(): Promise<any> {
35export function getPeers(): Promise<any> {
28 return scry<any>(`/peers`);
36 return scry<any>(`/peers`);
29}
37}
ui/src/routes/Home.svelte+4−2
@@ -149,7 +149,9 @@
149</script>
149</script>
150
150
151<div class="p-4 space-y-4 min-h-full flex flex-col items-center 2xs:p-8 2xs:space-y-8">
151<div class="p-4 space-y-4 min-h-full flex flex-col items-center 2xs:p-8 2xs:space-y-8">
152− <SearchBar bind:analysis bind:sigilQuery bind:search bind:searchMode bind:patp {placeholderText} />
152+ <SearchBar bind:analysis bind:sigilQuery bind:search bind:searchMode bind:patp {placeholderText}
153+ allowSigilSearch={params.mode !== 'chart'}
154+ />
153 <!-- <div class="bg-white">
155 <!-- <div class="bg-white">
154 <p>
156 <p>
155 Search: {search}
157 Search: {search}
@@ -164,7 +166,7 @@
164 Patp: {patp}
166 Patp: {patp}
165 </p>
167 </p>
166 </div> -->
168 </div> -->
167− {#if params.mode == "chart"}
169+ {#if params.mode == 'chart'}
168 <StarChart patp={patp || null} />
170 <StarChart patp={patp || null} />
169 {:else if patp}
171 {:else if patp}
170 <ShipView {patp} />
172 <ShipView {patp} />
ui/src/styles/tailwind-output.css+3
@@ -728,6 +728,9 @@ Ensure the default browser behavior of the `hidden` attribute.
728.-mb-16 {
728.-mb-16 {
729 margin-bottom: -4rem;
729 margin-bottom: -4rem;
730}
730}
731+.mb-2 {
732+ margin-bottom: 0.5rem;
733+}
731.-mt-0\.5 {
734.-mt-0\.5 {
732 margin-top: -0.125rem;
735 margin-top: -0.125rem;
733}
736}