mirror of
https://github.com/urbit/shrub.git
synced 2025-01-08 06:00:27 +03:00
Merge remote-tracking branch 'origin/master' into release/next-vere
This commit is contained in:
commit
c83b83930e
@ -268,6 +268,13 @@ Contributions:
|
||||
[..]
|
||||
```
|
||||
|
||||
Ensure the Vere release is marked as the 'latest' release and upload the two
|
||||
`.tgz` files to the release as `darwin.tgz` and `linux64.tgz`;
|
||||
this allows us to programmatically retrieve the latest release at
|
||||
[urbit.org/install/mac/latest/](https://urbit.org/install/mac/latest) and
|
||||
[urbit.org/install/linux64/latest](https://urbit.org/install/linux64/latest),
|
||||
respectively.
|
||||
|
||||
The same schpeel re: release candidates applies here.
|
||||
|
||||
Note that the release notes indicate which version of Urbit OS the Vere release
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e5c82dea80aa7c5593f43fa4294db7974211abceedd907663da73889857642e7
|
||||
size 1309381
|
||||
oid sha256:45d51478148fec9c32677a581c646a7ad0bbd29edcc46da15be4e1864dba59cd
|
||||
size 1322242
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6f38fba85eb50a94c0e64fed57fb1f9005ff4f3f37ef7115554c9c15b0982d39
|
||||
size 6308842
|
||||
oid sha256:15cb1f87dcb239a61b48eab90a740342643719a47ae1404f319a987e2f39daab
|
||||
size 6371972
|
||||
|
@ -21,11 +21,15 @@
|
||||
:: We get ++unix-event and ++pill from /-aquarium
|
||||
::
|
||||
/- aquarium
|
||||
/+ pill, default-agent
|
||||
/+ pill, default-agent, aqua-azimuth, dbug, verb
|
||||
=, pill-lib=pill
|
||||
=, aquarium
|
||||
=> $~ |%
|
||||
+$ state
|
||||
+$ versioned-state
|
||||
$% state-0
|
||||
state-1
|
||||
==
|
||||
+$ state-0
|
||||
$: %0
|
||||
pil=pill
|
||||
assembled=*
|
||||
@ -33,7 +37,16 @@
|
||||
fleet-snaps=(map term (map ship pier))
|
||||
piers=(map ship pier)
|
||||
==
|
||||
+$ state-1
|
||||
$: %1
|
||||
pil=pill
|
||||
assembled=*
|
||||
tym=@da
|
||||
fleet-snaps=(map term fleet)
|
||||
piers=fleet
|
||||
==
|
||||
::
|
||||
+$ fleet [ships=(map ship pier) azi=az-state]
|
||||
+$ pier
|
||||
$: snap=*
|
||||
event-log=(list unix-timed-event)
|
||||
@ -42,9 +55,11 @@
|
||||
==
|
||||
--
|
||||
::
|
||||
=| state
|
||||
=* all-state -
|
||||
=| state-1
|
||||
=* state -
|
||||
=<
|
||||
%- agent:dbug
|
||||
%+ verb |
|
||||
^- agent:gall
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
@ -52,24 +67,37 @@
|
||||
ac ~(. aqua-core bowl)
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
++ on-init `this
|
||||
++ on-save !>(all-state)
|
||||
++ on-save !>(state)
|
||||
++ on-load
|
||||
|= old-state=vase
|
||||
|= old-vase=vase
|
||||
^- step:agent:gall
|
||||
~& prep=%aqua
|
||||
=+ new=((soft state) !<(* old-state))
|
||||
?~ new
|
||||
`this
|
||||
`this(all-state u.new)
|
||||
=+ !<(old=versioned-state old-vase)
|
||||
=| cards=(list card:agent:gall)
|
||||
|-
|
||||
?- -.old
|
||||
:: wipe fleets and piers rather than give them falsely nulled azimuth state
|
||||
::
|
||||
%0
|
||||
%_ $
|
||||
-.old %1
|
||||
fleet-snaps.old *(map term fleet)
|
||||
piers.old *fleet
|
||||
==
|
||||
::
|
||||
%1
|
||||
[cards this(state old)]
|
||||
==
|
||||
::
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
^- step:agent:gall
|
||||
=^ cards all-state
|
||||
=^ cards state
|
||||
?+ mark ~|([%aqua-bad-mark mark] !!)
|
||||
%aqua-events (poke-aqua-events:ac !<((list aqua-event) vase))
|
||||
%pill (poke-pill:ac !<(pill vase))
|
||||
%noun (poke-noun:ac !<(* vase))
|
||||
%aqua-events (poke-aqua-events:ac !<((list aqua-event) vase))
|
||||
%pill (poke-pill:ac !<(pill vase))
|
||||
%noun (poke-noun:ac !<(* vase))
|
||||
%azimuth-action (poke-azimuth-action:ac !<(azimuth-action vase))
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
@ -92,7 +120,18 @@
|
||||
++ on-peek peek:ac
|
||||
::
|
||||
++ on-agent on-agent:def
|
||||
++ on-arvo on-arvo:def
|
||||
::
|
||||
++ on-arvo
|
||||
|= [=wire sign=sign-arvo]
|
||||
^- step:agent:gall
|
||||
?+ wire (on-arvo:def wire sign)
|
||||
[%wait @ ~]
|
||||
?> ?=(%wake +<.sign)
|
||||
=/ wen=@da (slav %da i.t.wire)
|
||||
=^ cards state
|
||||
(handle-wake:ac wen)
|
||||
[cards this]
|
||||
==
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
::
|
||||
@ -110,7 +149,7 @@
|
||||
::
|
||||
++ pe
|
||||
|= who=ship
|
||||
=+ (~(gut by piers) who *pier)
|
||||
=+ (~(gut by ships.piers) who *pier)
|
||||
=* pier-data -
|
||||
|%
|
||||
::
|
||||
@ -118,7 +157,7 @@
|
||||
::
|
||||
++ abet-pe
|
||||
^+ this
|
||||
=. piers (~(put by piers) who pier-data)
|
||||
=. ships.piers (~(put by ships.piers) who pier-data)
|
||||
this
|
||||
::
|
||||
:: Initialize new ship
|
||||
@ -248,7 +287,19 @@
|
||||
this
|
||||
::
|
||||
++ abet-aqua
|
||||
^- (quip card:agent:gall state)
|
||||
^- (quip card:agent:gall _state)
|
||||
::
|
||||
:: interecept %request effects to handle azimuth subscription
|
||||
::
|
||||
=. this
|
||||
%- emit-cards
|
||||
%- zing
|
||||
%+ turn ~(tap by unix-effects)
|
||||
|= [=ship ufs=(list unix-effect)]
|
||||
%+ murn ufs
|
||||
|= uf=unix-effect
|
||||
(router:aqua-azimuth our.hid ship uf azi.piers)
|
||||
::
|
||||
=. this
|
||||
=/ =path /effect
|
||||
%- emit-cards
|
||||
@ -300,20 +351,19 @@
|
||||
=/ =path /boths/(scot %p ship)
|
||||
[%give %fact ~[path] %aqua-boths !>(`aqua-boths`[ship (flop bo)])]
|
||||
::
|
||||
[(flop cards) all-state]
|
||||
[(flop cards) state]
|
||||
::
|
||||
++ emit-cards
|
||||
|= ms=(list card:agent:gall)
|
||||
=. cards (weld ms cards)
|
||||
this
|
||||
::
|
||||
::
|
||||
:: Run all events on all ships until all queues are empty
|
||||
::
|
||||
++ plow-all
|
||||
|- ^+ this
|
||||
=/ who
|
||||
=/ pers ~(tap by piers)
|
||||
=/ pers ~(tap by ships.piers)
|
||||
|- ^- (unit ship)
|
||||
?~ pers
|
||||
~
|
||||
@ -331,7 +381,7 @@
|
||||
::
|
||||
++ poke-pill
|
||||
|= p=pill
|
||||
^- (quip card:agent:gall state)
|
||||
^- (quip card:agent:gall _state)
|
||||
=. this apex-aqua =< abet-aqua
|
||||
=. pil p
|
||||
~& lent=(met 3 (jam boot-ova.pil))
|
||||
@ -362,7 +412,7 @@
|
||||
::
|
||||
++ poke-noun
|
||||
|= val=*
|
||||
^- (quip card:agent:gall state)
|
||||
^- (quip card:agent:gall _state)
|
||||
=. this apex-aqua =< abet-aqua
|
||||
^+ this
|
||||
:: Could potentially factor out the three lines of turn-ships
|
||||
@ -391,7 +441,7 @@
|
||||
=/ txt .^(@ %cx (weld pax /hoon))
|
||||
[/vane/[vane] [%veer v pax txt]]
|
||||
=> .(this ^+(this this))
|
||||
=^ ms all-state (poke-pill pil)
|
||||
=^ ms state (poke-pill pil)
|
||||
(emit-cards ms)
|
||||
::
|
||||
[%swap-files ~]
|
||||
@ -402,7 +452,7 @@
|
||||
%- unix-event
|
||||
%- %*(. file-ovum:pill-lib directories slim-dirs)
|
||||
/(scot %p our.hid)/work/(scot %da now.hid)
|
||||
=^ ms all-state (poke-pill pil)
|
||||
=^ ms state (poke-pill pil)
|
||||
(emit-cards ms)
|
||||
::
|
||||
[%wish hers=* p=@t]
|
||||
@ -412,12 +462,14 @@
|
||||
(wish:(pe who) p.val)
|
||||
::
|
||||
[%unpause-events hers=*]
|
||||
=. this start-azimuth-timer
|
||||
%+ turn-ships ((list ship) hers.val)
|
||||
|= [who=ship thus=_this]
|
||||
=. this thus
|
||||
start-processing-events:(pe who)
|
||||
::
|
||||
[%pause-events hers=*]
|
||||
=. this stop-azimuth-timer
|
||||
%+ turn-ships ((list ship) hers.val)
|
||||
|= [who=ship thus=_this]
|
||||
=. this thus
|
||||
@ -428,17 +480,47 @@
|
||||
this
|
||||
==
|
||||
::
|
||||
:: Make changes to azimuth state for the current fleet
|
||||
::
|
||||
++ poke-azimuth-action
|
||||
|= act=azimuth-action
|
||||
^- (quip card:agent:gall _state)
|
||||
=. this apex-aqua =< abet-aqua
|
||||
^+ this
|
||||
?- -.act
|
||||
::
|
||||
%init-azimuth
|
||||
=. azi.piers *az-state
|
||||
start-azimuth-timer
|
||||
::
|
||||
%spawn
|
||||
=. state (spawn who.act)
|
||||
this
|
||||
::
|
||||
%breach
|
||||
:: should we remove the pier from state here?
|
||||
=. state (breach who.act)
|
||||
this
|
||||
::
|
||||
==
|
||||
::
|
||||
:: Apply a list of events tagged by ship
|
||||
::
|
||||
++ poke-aqua-events
|
||||
|= events=(list aqua-event)
|
||||
^- (quip card:agent:gall state)
|
||||
^- (quip card:agent:gall _state)
|
||||
=. this apex-aqua =< abet-aqua
|
||||
%+ turn-events events
|
||||
|= [ae=aqua-event thus=_this]
|
||||
=. this thus
|
||||
?- -.ae
|
||||
::
|
||||
%init-ship
|
||||
:: XX Note that the keys that get passed in are unused. The keys field
|
||||
:: should be deleted now that aqua is capable of managing azimuth state
|
||||
:: internally. Its been left this way for now until all the ph tests
|
||||
:: can be rewritten
|
||||
=/ keys=dawn-event:able:jael (dawn who.ae)
|
||||
=. this abet-pe:(publish-effect:(pe who.ae) [/ %sleep ~])
|
||||
=/ initted
|
||||
=< plow
|
||||
@ -451,7 +533,7 @@
|
||||
:^ //term/1 %boot &
|
||||
?~ keys.ae
|
||||
[%fake who.ae]
|
||||
[%dawn u.keys.ae]
|
||||
[%dawn keys]
|
||||
-.userspace-ova.pil
|
||||
[//http-client/0v1n.2m9vh %born ~]
|
||||
[//http-server/0v1n.2m9vh %born ~]
|
||||
@ -464,27 +546,36 @@
|
||||
stop-processing-events:(pe who.ae)
|
||||
::
|
||||
%snap-ships
|
||||
=. this
|
||||
%+ turn-ships (turn ~(tap by ships.piers) head)
|
||||
|= [who=ship thus=_this]
|
||||
=. this thus
|
||||
(publish-effect:(pe who) [/ %kill ~])
|
||||
=. fleet-snaps
|
||||
%+ ~(put by fleet-snaps) lab.ae
|
||||
:_ azi.piers
|
||||
%- malt
|
||||
%+ murn hers.ae
|
||||
|= her=ship
|
||||
^- (unit (pair ship pier))
|
||||
=+ per=(~(get by piers) her)
|
||||
=+ per=(~(get by ships.piers) her)
|
||||
?~ per
|
||||
~
|
||||
`[her u.per]
|
||||
=. this stop-azimuth-timer
|
||||
=. piers *fleet
|
||||
(pe -.hers.ae)
|
||||
::
|
||||
%restore-snap
|
||||
=. this
|
||||
%+ turn-ships (turn ~(tap by piers) head)
|
||||
%+ turn-ships (turn ~(tap by ships.piers) head)
|
||||
|= [who=ship thus=_this]
|
||||
=. this thus
|
||||
(publish-effect:(pe who) [/ %sleep ~])
|
||||
=. piers (~(uni by piers) (~(got by fleet-snaps) lab.ae))
|
||||
(publish-effect:(pe who) [/ %kill ~])
|
||||
=. piers (~(got by fleet-snaps) lab.ae)
|
||||
=. this start-azimuth-timer
|
||||
=. this
|
||||
%+ turn-ships (turn ~(tap by piers) head)
|
||||
%+ turn-ships (turn ~(tap by ships.piers) head)
|
||||
|= [who=ship thus=_this]
|
||||
=. this thus
|
||||
(publish-effect:(pe who) [/ %restore ~])
|
||||
@ -537,18 +628,163 @@
|
||||
^- (unit (unit cage))
|
||||
?+ path ~
|
||||
[%x %fleet-snap @ ~] ``noun+!>((~(has by fleet-snaps) i.t.t.path))
|
||||
[%x %ships ~] ``noun+!>((turn ~(tap by piers) head))
|
||||
[%x %fleets ~] ``noun+!>((turn ~(tap by fleet-snaps) head))
|
||||
[%x %ships ~] ``noun+!>((turn ~(tap by ships.piers) head))
|
||||
[%x %pill ~] ``pill+!>(pil)
|
||||
[%x %i @ @ @ @ @ *]
|
||||
=/ who (slav %p i.t.t.path)
|
||||
=/ pier (~(get by piers) who)
|
||||
=/ pier (~(get by ships.piers) who)
|
||||
?~ pier
|
||||
~
|
||||
:^ ~ ~ %noun !>
|
||||
(peek:(pe who) t.t.t.path)
|
||||
[%x %log-info ~]
|
||||
``noun+!>([lives.azi.piers (lent logs.azi.piers) tym.azi.piers])
|
||||
==
|
||||
::
|
||||
:: Trivial scry for mock
|
||||
::
|
||||
++ scry |=([* *] ~)
|
||||
::
|
||||
++ handle-wake
|
||||
|= wen=@da
|
||||
^- (quip card:agent:gall _state)
|
||||
=. this apex-aqua =< abet-aqua
|
||||
?. =(wen tym.azi.piers)
|
||||
this
|
||||
=. state (spam-logs 10)
|
||||
start-azimuth-timer
|
||||
::
|
||||
++ start-azimuth-timer
|
||||
^+ this
|
||||
=? this !=(tym.azi.piers *@da)
|
||||
stop-azimuth-timer
|
||||
=/ until=@da (add now.hid ~s40)
|
||||
=. tym.azi.piers until
|
||||
%- emit-cards
|
||||
[%pass /wait/(scot %da until) %arvo %b %wait until]~
|
||||
::
|
||||
++ stop-azimuth-timer
|
||||
^+ this
|
||||
=* tym tym.azi.piers
|
||||
?: =(tym *@da)
|
||||
this
|
||||
%- emit-cards
|
||||
[%pass /wait/(scot %da tym) %arvo %b %rest tym]~
|
||||
::
|
||||
++ spam-logs
|
||||
|= n=@
|
||||
^- _state
|
||||
=* loop $
|
||||
?: =(n 0)
|
||||
state
|
||||
=/ new-state=_state
|
||||
?. (~(has by lives.azi.piers) ~fes)
|
||||
(spawn ~fes)
|
||||
(cycle-keys ~fes)
|
||||
=. state new-state
|
||||
loop(n (dec n))
|
||||
::
|
||||
++ spawn
|
||||
|= who=@p
|
||||
^- _state
|
||||
?< (~(has by lives.azi.piers) who)
|
||||
=. lives.azi.piers (~(put by lives.azi.piers) who [1 0])
|
||||
=. logs.azi.piers
|
||||
%+ weld logs.azi.piers
|
||||
:_ ~
|
||||
%- changed-keys:lo:aqua-azimuth
|
||||
:* who
|
||||
(get-public:aqua-azimuth who 1 %crypt)
|
||||
(get-public:aqua-azimuth who 1 %auth)
|
||||
1
|
||||
1
|
||||
==
|
||||
(spam-logs 10)
|
||||
::
|
||||
++ cycle-keys
|
||||
|= who=@p
|
||||
^- _state
|
||||
=/ prev
|
||||
~| no-such-ship+who
|
||||
(~(got by lives.azi.piers) who)
|
||||
=/ lyfe +(lyfe.prev)
|
||||
=. lives.azi.piers (~(put by lives.azi.piers) who [lyfe rut.prev])
|
||||
=. logs.azi.piers
|
||||
%+ weld logs.azi.piers
|
||||
:_ ~
|
||||
%- changed-keys:lo:aqua-azimuth
|
||||
:* who
|
||||
(get-public:aqua-azimuth who lyfe %crypt)
|
||||
(get-public:aqua-azimuth who lyfe %auth)
|
||||
1
|
||||
lyfe
|
||||
==
|
||||
state
|
||||
::
|
||||
++ breach
|
||||
|= who=@p
|
||||
^- _state
|
||||
=. state (cycle-keys who)
|
||||
=/ prev (~(got by lives.azi.piers) who)
|
||||
=/ rut +(rut.prev)
|
||||
=. lives.azi.piers (~(put by lives.azi.piers) who [lyfe.prev rut])
|
||||
=. logs.azi.piers
|
||||
%+ weld logs.azi.piers
|
||||
[(broke-continuity:lo:aqua-azimuth who rut) ~]
|
||||
(spam-logs 10)
|
||||
::
|
||||
++ dawn
|
||||
|= who=ship
|
||||
^- dawn-event:able:jael
|
||||
?> ?=(?(%czar %king %duke) (clan:title who))
|
||||
=/ spon=(list [ship point:azimuth])
|
||||
%- flop
|
||||
|- ^- (list [ship point:azimuth])
|
||||
=/ =ship (^sein:title who)
|
||||
=/ a-point=[^ship point:azimuth]
|
||||
=/ spon-spon [& (^sein:title ship)]
|
||||
=/ life-rift ~|([ship lives.azi.piers] (~(got by lives.azi.piers) ship))
|
||||
=/ =life lyfe.life-rift
|
||||
=/ =rift rut.life-rift
|
||||
=/ =pass
|
||||
%^ pass-from-eth:azimuth
|
||||
(as-octs:mimes:html (get-public:aqua-azimuth ship life %crypt))
|
||||
(as-octs:mimes:html (get-public:aqua-azimuth ship life %auth))
|
||||
1
|
||||
:^ ship
|
||||
*[address address address address]:azimuth
|
||||
`[life=life pass rift spon-spon ~]
|
||||
~
|
||||
?: ?=(%czar (clan:title ship))
|
||||
[a-point]~
|
||||
[a-point $(who ship)]
|
||||
=/ =seed:able:jael
|
||||
=/ life-rift (~(got by lives.azi.piers) who)
|
||||
=/ =life lyfe.life-rift
|
||||
[who life sec:ex:(get-keys:aqua-azimuth who life) ~]
|
||||
:* seed
|
||||
spon
|
||||
get-czars
|
||||
~[~['arvo' 'netw' 'ork']]
|
||||
0
|
||||
`(need (de-purl:html 'http://localhost:8545'))
|
||||
==
|
||||
::
|
||||
:: Should only do galaxies
|
||||
::
|
||||
++ get-czars
|
||||
^- (map ship [rift life pass])
|
||||
%- malt
|
||||
%+ murn
|
||||
~(tap by lives.azi.piers)
|
||||
|= [who=ship lyfe=life rut=rift]
|
||||
?. =(%czar (clan:title who))
|
||||
~
|
||||
%- some
|
||||
:^ who rut lyfe
|
||||
%^ pass-from-eth:azimuth
|
||||
(as-octs:mimes:html (get-public:aqua-azimuth who lyfe %crypt))
|
||||
(as-octs:mimes:html (get-public:aqua-azimuth who lyfe %auth))
|
||||
1
|
||||
--
|
||||
|
@ -8,7 +8,7 @@
|
||||
view=chat-view,
|
||||
*group
|
||||
/+ default-agent, verb, dbug, store=chat-store, group-store, grpl=group,
|
||||
resource
|
||||
resource, *migrate
|
||||
~% %chat-hook-top ..is ~
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
@ -369,6 +369,10 @@
|
||||
::
|
||||
%chat-hook-action
|
||||
(poke-chat-hook-action:cc !<(action:hook vase))
|
||||
::
|
||||
%import
|
||||
?> (team:title our.bol src.bol)
|
||||
(poke-import:cc q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
@ -417,8 +421,28 @@
|
||||
==
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek on-peek:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-peek
|
||||
|= =path
|
||||
^- (unit (unit cage))
|
||||
?+ path (on-peek:def path)
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
==
|
||||
::
|
||||
++ on-arvo
|
||||
|= [=wire =sign-arvo]
|
||||
^- (quip card _this)
|
||||
?. ?=([%try-rejoin @ @ *] wire)
|
||||
(on-arvo:def wire sign-arvo)
|
||||
=/ nack-count=@ud (slav %ud i.t.wire)
|
||||
=/ who=@p (slav %p i.t.t.wire)
|
||||
=/ pax t.t.t.wire
|
||||
?> ?=([%b %wake *] sign-arvo)
|
||||
~? ?=(^ error.sign-arvo)
|
||||
"behn errored in backoff timers, continuing anyway"
|
||||
:_ this
|
||||
[(try-rejoin:cc who pax +(nack-count))]~
|
||||
::
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
::
|
||||
@ -677,6 +701,32 @@
|
||||
==
|
||||
==
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
=/ sty=state-10
|
||||
:* %10
|
||||
(remake-map ;;((tree [path ship]) +<.arc))
|
||||
;;(? +>-.arc)
|
||||
(remake-map ;;((tree [path ?]) +>+.arc))
|
||||
==
|
||||
:_ sty
|
||||
%+ turn ~(tap by synced.sty)
|
||||
|= [=path =ship]
|
||||
^- card
|
||||
=/ watch-path=^path [%mailbox path]
|
||||
?: =(our.bol ship)
|
||||
=/ store-wire=wire [%store path]
|
||||
[%pass store-wire %agent [our.bol %chat-store] %watch watch-path]
|
||||
(try-rejoin ship watch-path 0)
|
||||
::
|
||||
++ try-rejoin
|
||||
|= [who=@p pax=path nack-count=@ud]
|
||||
^- card
|
||||
=/ =wire
|
||||
[%try-rejoin (scot %ud nack-count) (scot %p who) pax]
|
||||
[%pass wire %agent [who %chat-hook] %watch pax]
|
||||
::
|
||||
++ watch-synced
|
||||
|= pax=path
|
||||
^- (list card)
|
||||
@ -835,6 +885,9 @@
|
||||
[%pass /permissions %agent [our.bol %permission-store] %watch /updates]~
|
||||
::
|
||||
?+ wir !!
|
||||
[%try-rejoin @ @ *]
|
||||
$(wir t.t.t.wir)
|
||||
::
|
||||
[%groups ~] [~[watch-groups] state]
|
||||
::
|
||||
[%store @ *]
|
||||
@ -909,6 +962,13 @@
|
||||
?> ?=(^ chat)
|
||||
(migrate-listen t.chat)
|
||||
[~ state]
|
||||
::
|
||||
[%try-rejoin @ *]
|
||||
=/ nack-count=@ud (slav %ud i.t.wir)
|
||||
=/ wakeup=@da
|
||||
(add now.bol (mul ~s1 (bex (min 19 nack-count))))
|
||||
:_ state
|
||||
[%pass wir %arvo %b %wait wakeup]~
|
||||
==
|
||||
::
|
||||
++ chat-poke
|
||||
|
@ -2,7 +2,7 @@
|
||||
::
|
||||
:: data store that holds linear sequences of chat messages
|
||||
::
|
||||
/+ store=chat-store, default-agent, verb, dbug, group-store
|
||||
/+ store=chat-store, default-agent, verb, dbug, group-store, *migrate
|
||||
~% %chat-store-top ..is ~
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
@ -89,9 +89,10 @@
|
||||
?> (team:title our.bowl src.bowl)
|
||||
=^ cards state
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%json (poke-json:cc !<(json vase))
|
||||
%chat-action (poke-chat-action:cc !<(action:store vase))
|
||||
%noun [~ (poke-noun:cc !<(admin-action vase))]
|
||||
%json (poke-json:cc !<(json vase))
|
||||
%chat-action (poke-chat-action:cc !<(action:store vase))
|
||||
%noun [~ (poke-noun:cc !<(admin-action vase))]
|
||||
%import (poke-import:cc q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
@ -139,6 +140,9 @@
|
||||
?~ mailbox
|
||||
~
|
||||
``noun+!>(config.u.mailbox)
|
||||
::
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
==
|
||||
::
|
||||
++ on-agent on-agent:def
|
||||
@ -235,6 +239,12 @@
|
||||
[(weld message-moves read-moves) state]
|
||||
==
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
=/ sty=state-3 [%3 (remake-map ;;((tree [path mailbox:store]) +.arc))]
|
||||
[~ sty]
|
||||
::
|
||||
++ handle-create
|
||||
|= =action:store
|
||||
^- (quip card _state)
|
||||
|
@ -8,7 +8,14 @@
|
||||
*metadata-hook,
|
||||
*metadata-store,
|
||||
*group
|
||||
/+ *contact-json, default-agent, dbug, group-store, verb, resource, grpl=group
|
||||
/+ *contact-json,
|
||||
default-agent,
|
||||
dbug,
|
||||
group-store,
|
||||
verb,
|
||||
resource,
|
||||
grpl=group,
|
||||
*migrate
|
||||
~% %contact-hook-top ..is ~
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
@ -132,6 +139,10 @@
|
||||
::
|
||||
%contact-hook-action
|
||||
(poke-hook-action:cc !<(contact-hook-action vase))
|
||||
::
|
||||
%import
|
||||
?> (team:title our.bol src.bol)
|
||||
(poke-import:cc q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
@ -170,8 +181,27 @@
|
||||
==
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek on-peek:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-peek
|
||||
|= =path
|
||||
^- (unit (unit cage))
|
||||
?+ path (on-peek:def path)
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
==
|
||||
++ on-arvo
|
||||
|= [=wire =sign-arvo]
|
||||
^- (quip card _this)
|
||||
?. ?=([%try-rejoin @ @ *] wire)
|
||||
(on-arvo:def wire sign-arvo)
|
||||
=/ nack-count=@ud (slav %ud i.t.wire)
|
||||
=/ who=@p (slav %p i.t.t.wire)
|
||||
=/ pax t.t.t.wire
|
||||
?> ?=([%b %wake *] sign-arvo)
|
||||
~? ?=(^ error.sign-arvo)
|
||||
"behn errored in backoff timers, continuing anyway"
|
||||
:_ this
|
||||
[(try-rejoin:cc who pax +(nack-count))]~
|
||||
::
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
::
|
||||
@ -260,6 +290,27 @@
|
||||
==
|
||||
==
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
=/ sty=state-three
|
||||
[%3 (remake-map ;;((tree [path ship]) +<.arc)) ;;(? +>.arc)]
|
||||
:_ sty
|
||||
%+ turn ~(tap by synced.sty)
|
||||
|= [=path =ship]
|
||||
^- card
|
||||
=/ contact-path [%contacts path]
|
||||
?: =(our.bol ship)
|
||||
[%pass contact-path %agent [our.bol %contact-store] %watch contact-path]
|
||||
(try-rejoin ship contact-path 0)
|
||||
::
|
||||
++ try-rejoin
|
||||
|= [who=@p pax=path nack-count=@ud]
|
||||
^- card
|
||||
=/ =wire
|
||||
[%try-rejoin (scot %ud nack-count) (scot %p who) pax]
|
||||
[%pass wire %agent [who %contact-hook] %watch pax]
|
||||
::
|
||||
++ watch-contacts
|
||||
|= pax=path
|
||||
^- (list card)
|
||||
@ -282,6 +333,13 @@
|
||||
^- (quip card _state)
|
||||
?~ saw
|
||||
[~ state]
|
||||
?: ?=([%try-rejoin @ *] wir)
|
||||
=/ nack-count=@ud (slav %ud i.t.wir)
|
||||
=/ wakeup=@da
|
||||
(add now.bol (mul ~s1 (bex (min 19 nack-count))))
|
||||
:_ state
|
||||
[%pass wir %arvo %b %wait wakeup]~
|
||||
::
|
||||
?> ?=(^ wir)
|
||||
[~ state(synced (~(del by synced) t.wir))]
|
||||
::
|
||||
@ -295,6 +353,9 @@
|
||||
|= wir=wire
|
||||
^- (list card)
|
||||
?+ wir !!
|
||||
[%try-rejoin @ @ *]
|
||||
$(wir t.t.t.wir)
|
||||
::
|
||||
[%inv ~]
|
||||
[%pass /inv %agent [our.bol %invite-store] %watch /invitatory/contacts]~
|
||||
::
|
||||
|
@ -2,7 +2,7 @@
|
||||
::
|
||||
:: data store that holds group-based contact data
|
||||
::
|
||||
/+ *contact-json, default-agent, dbug
|
||||
/+ *contact-json, default-agent, dbug, *migrate
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
+$ versioned-state
|
||||
@ -121,8 +121,12 @@
|
||||
?> (team:title our.bowl src.bowl)
|
||||
=^ cards state
|
||||
?+ mark (on-poke:def mark vase)
|
||||
::%json (poke-json:cc !<(json vase))
|
||||
%contact-action (poke-contact-action:cc !<(contact-action vase))
|
||||
::%json (poke-json:cc !<(json vase))
|
||||
%contact-action
|
||||
(poke-contact-action:cc !<(contact-action vase))
|
||||
::
|
||||
%import
|
||||
(poke-import:cc q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
@ -169,6 +173,9 @@
|
||||
?~ contacts
|
||||
~
|
||||
``noun+!>((~(get by u.contacts) ship))
|
||||
::
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
==
|
||||
::
|
||||
++ on-agent on-agent:def
|
||||
@ -197,6 +204,15 @@
|
||||
%edit (handle-edit +.action)
|
||||
==
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
=/ sty=state-three
|
||||
:- %3
|
||||
%- remake-map-of-map
|
||||
;;((tree [path (tree [ship contact])]) +.arc)
|
||||
[~ sty]
|
||||
::
|
||||
++ handle-create
|
||||
|= =path
|
||||
^- (quip card _state)
|
||||
|
@ -181,22 +181,7 @@
|
||||
~[(add-pending rid ship.act)]
|
||||
::
|
||||
%delete
|
||||
=/ rid=resource
|
||||
(de-path:resource path.act)
|
||||
=/ group-pokes=(list card)
|
||||
?: =(our.bol entity.rid)
|
||||
~[(group-push-poke %remove rid)]
|
||||
:~ (group-proxy-poke %remove-members rid (sy our.bol ~))
|
||||
(group-pull-poke %remove rid)
|
||||
==
|
||||
;: weld
|
||||
group-pokes
|
||||
:~ (contact-hook-poke [%remove path.act])
|
||||
(group-poke [%remove-group rid ~])
|
||||
(contact-poke [%delete path.act])
|
||||
==
|
||||
(delete-metadata path.act)
|
||||
==
|
||||
~
|
||||
::
|
||||
%remove
|
||||
=/ rid=resource
|
||||
@ -357,13 +342,6 @@
|
||||
(metadata-hook-poke [%add-owned path])
|
||||
==
|
||||
::
|
||||
++ delete-metadata
|
||||
|= =path
|
||||
^- (list card)
|
||||
:~ (metadata-poke [%remove path [%contacts path]])
|
||||
(metadata-hook-poke [%remove path])
|
||||
==
|
||||
::
|
||||
++ all-scry
|
||||
^- rolodex
|
||||
.^(rolodex %gx /(scot %p our.bol)/contact-store/(scot %da now.bol)/all/noun)
|
||||
|
@ -5,7 +5,7 @@
|
||||
/- glob
|
||||
/+ default-agent, verb, dbug
|
||||
|%
|
||||
++ hash 0v4.fpa4r.s6dtc.h8tps.62jv0.qn0fj
|
||||
++ hash 0vtkeco.6p0qd.c44uf.jnjph.ie5vt
|
||||
+$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))]
|
||||
+$ all-states
|
||||
$% state-0
|
||||
|
@ -1,7 +1,8 @@
|
||||
:: graph-store [landscape]
|
||||
::
|
||||
::
|
||||
/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug
|
||||
/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug,
|
||||
*migrate
|
||||
~% %graph-store-top ..is ~
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
@ -218,6 +219,7 @@
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%graph-update (graph-update !<(update:store vase))
|
||||
%noun (debug !<(debug-input vase))
|
||||
%import (poke-import q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
@ -612,6 +614,151 @@
|
||||
%graph ^$(graph p.children.node)
|
||||
==
|
||||
==
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
|^
|
||||
=/ sty=state-2 [%2 (remake-network ;;(tree-network +.arc))]
|
||||
:_ sty
|
||||
%+ turn ~(tap by graphs.sty)
|
||||
|= [rid=resource:store =marked-graph:store]
|
||||
^- card
|
||||
?: =(our.bowl entity.rid)
|
||||
=/ =cage [%push-hook-action !>([%add rid])]
|
||||
[%pass / %agent [our.bowl %graph-push-hook] %poke cage]
|
||||
(try-rejoin rid 0)
|
||||
::
|
||||
+$ tree-network
|
||||
$: graphs=tree-graphs
|
||||
tag-queries=(tree [term (tree resource:store)])
|
||||
update-logs=tree-update-logs
|
||||
archive=tree-graphs
|
||||
validators=(tree ^mark)
|
||||
==
|
||||
+$ tree-graphs (tree [resource:store tree-marked-graph])
|
||||
+$ tree-marked-graph [p=tree-graph q=(unit ^mark)]
|
||||
+$ tree-graph (tree [atom tree-node])
|
||||
+$ tree-node [post=tree-post children=tree-internal-graph]
|
||||
+$ tree-internal-graph
|
||||
$~ [%empty ~]
|
||||
$% [%graph p=tree-graph]
|
||||
[%empty ~]
|
||||
==
|
||||
+$ tree-update-logs (tree [resource:store tree-update-log])
|
||||
+$ tree-update-log (tree [time tree-logged-update])
|
||||
+$ tree-logged-update
|
||||
$: %0
|
||||
p=time
|
||||
$= q
|
||||
$% [%add-nodes =resource:store nodes=(tree [index:store tree-node])]
|
||||
[%remove-nodes =resource:store indices=(tree index:store)]
|
||||
[%add-signatures =uid:store signatures=tree-signatures]
|
||||
[%remove-signatures =uid:store signatures=tree-signatures]
|
||||
==
|
||||
==
|
||||
+$ tree-signatures (tree signature:store)
|
||||
+$ tree-post
|
||||
$: author=ship
|
||||
=index:store
|
||||
time-sent=time
|
||||
contents=(list content:store)
|
||||
hash=(unit hash:store)
|
||||
signatures=tree-signatures
|
||||
==
|
||||
::
|
||||
++ remake-network
|
||||
|= t=tree-network
|
||||
^- network:store
|
||||
:* (remake-graphs graphs.t)
|
||||
(remake-jug tag-queries.t)
|
||||
(remake-update-logs update-logs.t)
|
||||
(remake-graphs archive.t)
|
||||
(remake-set validators.t)
|
||||
==
|
||||
::
|
||||
++ remake-graphs
|
||||
|= t=tree-graphs
|
||||
^- graphs:store
|
||||
%- remake-map
|
||||
(~(run by t) remake-marked-graph)
|
||||
::
|
||||
++ remake-marked-graph
|
||||
|= t=tree-marked-graph
|
||||
^- marked-graph:store
|
||||
[(remake-graph p.t) q.t]
|
||||
::
|
||||
++ remake-graph
|
||||
|= t=tree-graph
|
||||
^- graph:store
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn ~(tap by t)
|
||||
|= [a=atom tn=tree-node]
|
||||
^- [atom node:store]
|
||||
[a (remake-node tn)]
|
||||
::
|
||||
++ remake-internal-graph
|
||||
|= t=tree-internal-graph
|
||||
^- internal-graph:store
|
||||
?: ?=(%empty -.t)
|
||||
[%empty ~]
|
||||
[%graph (remake-graph p.t)]
|
||||
::
|
||||
++ remake-node
|
||||
|= t=tree-node
|
||||
^- node:store
|
||||
:- (remake-post post.t)
|
||||
(remake-internal-graph children.t)
|
||||
::
|
||||
++ remake-update-logs
|
||||
|= t=tree-update-logs
|
||||
^- update-logs:store
|
||||
%- remake-map
|
||||
(~(run by t) remake-update-log)
|
||||
::
|
||||
++ remake-update-log
|
||||
|= t=tree-update-log
|
||||
^- update-log:store
|
||||
=/ ulm ((ordered-map time logged-update:store) gth)
|
||||
%+ gas:ulm *update-log:store
|
||||
%+ turn ~(tap by t)
|
||||
|= [=time tlu=tree-logged-update]
|
||||
^- [^time logged-update:store]
|
||||
[time (remake-logged-update tlu)]
|
||||
::
|
||||
++ remake-logged-update
|
||||
|= t=tree-logged-update
|
||||
^- logged-update:store
|
||||
:+ %0 p.t
|
||||
?- -.q.t
|
||||
%add-nodes
|
||||
:- %add-nodes
|
||||
:- resource.q.t
|
||||
%- remake-map
|
||||
(~(run by nodes.q.t) remake-node)
|
||||
::
|
||||
%remove-nodes
|
||||
[%remove-nodes resource.q.t (remake-set indices.q.t)]
|
||||
::
|
||||
%add-signatures
|
||||
[%add-signatures uid.q.t (remake-set signatures.q.t)]
|
||||
::
|
||||
%remove-signatures
|
||||
[%remove-signatures uid.q.t (remake-set signatures.q.t)]
|
||||
==
|
||||
::
|
||||
++ remake-post
|
||||
|= t=tree-post
|
||||
^- post:store
|
||||
t(signatures (remake-set signatures.t))
|
||||
--
|
||||
::
|
||||
++ try-rejoin
|
||||
|= [rid=resource:store nack-count=@]
|
||||
^- card
|
||||
=/ res-path (en-path:res rid)
|
||||
=/ wire [%try-rejoin (scot %ud nack-count) res-path]
|
||||
[%pass wire %agent [entity.rid %graph-push-hook] %watch resource+res-path]
|
||||
--
|
||||
::
|
||||
++ on-peek
|
||||
@ -668,6 +815,9 @@
|
||||
:+ %0
|
||||
now.bowl
|
||||
[%add-graph [ship term] `graph:store`p.u.result q.u.result %.y]
|
||||
::
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
::
|
||||
[%x %graph-subset @ @ @ @ ~]
|
||||
=/ =ship (slav %p i.t.t.path)
|
||||
@ -748,12 +898,14 @@
|
||||
[%x %peek-update-log @ @ ~]
|
||||
=/ =ship (slav %p i.t.t.path)
|
||||
=/ =term i.t.t.t.path
|
||||
=/ update-log=(unit update-log:store) (~(get by update-logs) [ship term])
|
||||
?~ update-log [~ ~]
|
||||
=/ result=(unit [time update:store])
|
||||
(peek:orm-log:store u.update-log)
|
||||
?~ result [~ ~]
|
||||
``noun+!>([~ -.u.result])
|
||||
=/ m-update-log=(unit update-log:store) (~(get by update-logs) [ship term])
|
||||
:- ~ :- ~ :- %noun
|
||||
!> ^- (unit time)
|
||||
%+ biff m-update-log
|
||||
|= =update-log:store
|
||||
=/ result=(unit [=time =update:store])
|
||||
(peek:orm-log:store update-log)
|
||||
(bind result |=([=time update:store] time))
|
||||
==
|
||||
::
|
||||
++ get-node
|
||||
@ -790,9 +942,38 @@
|
||||
=* validator i.t.wire
|
||||
=/ =rave:clay [%next %b [%da now.bowl] /[validator]]
|
||||
[%pass wire %arvo %c %warp our.bowl [%home `rave]]~
|
||||
::
|
||||
[%try-rejoin @ *]
|
||||
=/ rid=resource:store (de-path:res t.t.wire)
|
||||
=/ nack-count (slav %ud i.t.wire)
|
||||
?> ?=([%b %wake *] sign-arvo)
|
||||
~? ?=(^ error.sign-arvo)
|
||||
"behn errored in backoff timers, continuing anyway"
|
||||
=/ new=^wire [%try-rejoin (scot %ud +(nack-count)) t.t.wire]
|
||||
:_ this
|
||||
[%pass new %agent [entity.rid %graph-push-hook] %watch resource+t.t.wire]~
|
||||
==
|
||||
::
|
||||
++ on-agent on-agent:def
|
||||
++ on-agent
|
||||
|= [=wire =sign:agent:gall]
|
||||
^- (quip card _this)
|
||||
?. ?=([%try-rejoin @ *] wire)
|
||||
(on-agent:def wire sign)
|
||||
?. ?=(%watch-ack -.sign)
|
||||
[~ this]
|
||||
=/ rid=resource:store (de-path:res t.t.wire)
|
||||
?~ p.sign
|
||||
=/ =cage [%pull-hook-action !>([%add entity.rid rid])]
|
||||
:_ this
|
||||
:~ [%pass / %agent [our.bowl %graph-pull-hook] %poke cage]
|
||||
[%pass wire %agent [entity.rid %graph-push-hook] %leave ~]
|
||||
==
|
||||
=/ nack-count=@ud (slav %ud i.t.wire)
|
||||
=/ wakeup=@da
|
||||
(add now.bowl (mul ~s1 (bex (min 19 nack-count))))
|
||||
:_ this
|
||||
[%pass wire %arvo %b %wait wakeup]~
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
|
@ -29,8 +29,8 @@
|
||||
:: Modify the group. Further documented in /sur/group-store.hoon
|
||||
::
|
||||
::
|
||||
/- *group, permission-store
|
||||
/+ store=group-store, default-agent, verb, dbug, resource
|
||||
/- *group, permission-store, *contact-view
|
||||
/+ store=group-store, default-agent, verb, dbug, resource, *migrate
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
::
|
||||
@ -165,12 +165,15 @@
|
||||
^- (quip card _this)
|
||||
?> (team:title our.bowl src.bowl)
|
||||
=^ cards state
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%noun (poke-noun:gc vase)
|
||||
::
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%noun
|
||||
(poke-noun:gc vase)
|
||||
::
|
||||
?(%group-update %group-action)
|
||||
(poke-group-update:gc !<(update:store vase))
|
||||
::
|
||||
::
|
||||
%import
|
||||
(poke-import:gc q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
@ -214,10 +217,42 @@
|
||||
(slav %p i.t.t.t.t.t.t.path)
|
||||
?~ rid ~
|
||||
``noun+!>((peek-group-join u.rid ship))
|
||||
::
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
==
|
||||
::
|
||||
++ on-agent on-agent:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-agent
|
||||
|= [=wire =sign:agent:gall]
|
||||
^- (quip card _this)
|
||||
?. ?=([%try-rejoin @ *] wire)
|
||||
(on-agent:def wire sign)
|
||||
?> ?=(%poke-ack -.sign)
|
||||
=/ rid=resource (de-path:resource t.t.wire)
|
||||
?~ p.sign
|
||||
=/ =cage
|
||||
[%pull-hook-action !>([%add entity.rid rid])]
|
||||
:_ this
|
||||
[%pass / %agent [our.bowl %group-pull-hook] %poke cage]~
|
||||
=/ nack-count=@ud (slav %ud i.t.wire)
|
||||
=/ wakeup=@da
|
||||
(add now.bowl (mul ~s1 (bex (min 19 nack-count))))
|
||||
:_ this
|
||||
[%pass wire %arvo %b %wait wakeup]~
|
||||
::
|
||||
++ on-arvo
|
||||
|= [=wire =sign-arvo]
|
||||
^- (quip card _this)
|
||||
?. ?=([%try-rejoin @ *] wire)
|
||||
(on-arvo:def wire sign-arvo)
|
||||
=/ =resource (de-path:resource t.t.wire)
|
||||
=/ nack-count=@ud (slav %ud i.t.wire)
|
||||
?> ?=([%b %wake *] sign-arvo)
|
||||
~? ?=(^ error.sign-arvo)
|
||||
"behn errored in backoff timers, continuing anyway"
|
||||
:_ this
|
||||
[(try-rejoin:gc resource +(nack-count))]~
|
||||
::
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
::
|
||||
@ -226,7 +261,7 @@
|
||||
|= rid=resource
|
||||
^- (unit group)
|
||||
(~(get by groups) rid)
|
||||
|
||||
::
|
||||
++ peek-group-join
|
||||
|= [rid=resource =ship]
|
||||
=/ ugroup
|
||||
@ -246,6 +281,77 @@
|
||||
(~(has in ban-ranks.policy) (clan:title ship))
|
||||
==
|
||||
==
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
|^
|
||||
=/ sty=state-one
|
||||
[%1 (remake-groups ;;((tree [resource tree-group]) +.arc))]
|
||||
:_ sty
|
||||
%+ roll ~(tap by groups.sty)
|
||||
|= [[rid=resource grp=group] out=(list card)]
|
||||
?: =(entity.rid our.bol)
|
||||
%+ weld out
|
||||
%+ roll ~(tap in members.grp)
|
||||
|= [recipient=@p out=(list card)]
|
||||
?: =(recipient our.bol)
|
||||
out
|
||||
:_ out
|
||||
%- poke-contact
|
||||
:* %invite rid recipient
|
||||
(crip "Rejoin disconnected group {<entity.rid>}/{<name.rid>}")
|
||||
==
|
||||
:_ out
|
||||
(try-rejoin rid 0)
|
||||
::
|
||||
++ remake-groups
|
||||
|= grps=(tree [resource tree-group])
|
||||
^- ^groups
|
||||
%- remake-map
|
||||
(~(run by grps) remake-group)
|
||||
::
|
||||
++ remake-group
|
||||
|= grp=tree-group
|
||||
^- group
|
||||
%= grp
|
||||
members (remake-set members.grp)
|
||||
tags (remake-jug tags.grp)
|
||||
policy (remake-policy policy.grp)
|
||||
==
|
||||
::
|
||||
+$ tree-group
|
||||
$: members=(tree ship)
|
||||
tags=(tree [tag (tree ship)])
|
||||
policy=tree-policy
|
||||
hidden=?
|
||||
==
|
||||
::
|
||||
+$ tree-policy
|
||||
$% [%invite pending=(tree ship)]
|
||||
[%open ban-ranks=(tree rank:title) banned=(tree ship)]
|
||||
==
|
||||
::
|
||||
++ remake-policy
|
||||
|= pl=tree-policy
|
||||
^- policy
|
||||
?- -.pl
|
||||
%invite [%invite (remake-set pending.pl)]
|
||||
%open [%open (remake-set ban-ranks.pl) (remake-set banned.pl)]
|
||||
==
|
||||
--
|
||||
::
|
||||
++ try-rejoin
|
||||
|= [rid=resource nack-count=@ud]
|
||||
^- card
|
||||
=/ =cage
|
||||
:- %group-update
|
||||
!> ^- update:store
|
||||
[%add-members rid (sy our.bol ~)]
|
||||
=/ =wire
|
||||
[%try-rejoin (scot %ud nack-count) (en-path:resource rid)]
|
||||
[%pass wire %agent [entity.rid %group-push-hook] %poke cage]
|
||||
::
|
||||
++ poke-noun
|
||||
|= =vase
|
||||
^- (quip card _state)
|
||||
@ -604,6 +710,11 @@
|
||||
|= =action:store
|
||||
^- card
|
||||
[%pass / %agent [our.bol %group-store] %poke %group-action !>(action)]
|
||||
::
|
||||
++ poke-contact
|
||||
|= act=contact-view-action
|
||||
^- card
|
||||
[%pass / %agent [our.bol %contact-view] %poke %contact-view-action !>(act)]
|
||||
:: +send-diff: update subscribers of new state
|
||||
::
|
||||
:: We only allow subscriptions on /groups
|
||||
|
@ -166,11 +166,16 @@
|
||||
?~ existing-notif
|
||||
notification
|
||||
(merge-notification:ha u.existing-notif notification)
|
||||
=/ new-read=?
|
||||
?~ existing-notif
|
||||
%.y
|
||||
read.u.existing-notif
|
||||
=. read.new %.n
|
||||
=/ new-timebox=timebox:store
|
||||
(~(put by timebox) index new)
|
||||
:- (give:ha [/updates]~ %added last-seen index new)
|
||||
%_ state
|
||||
+ ?~(existing-notif (upd-unreads:ha index last-seen %.n) +.state)
|
||||
+ ?.(new-read +.state (upd-unreads:ha index last-seen %.n))
|
||||
notifications (put:orm notifications last-seen new-timebox)
|
||||
==
|
||||
++ read-index
|
||||
|
@ -1,6 +1,6 @@
|
||||
:: invite-store [landscape]
|
||||
/- store=invite-store
|
||||
/+ res=resource, default-agent, dbug
|
||||
/+ res=resource, default-agent, dbug, *migrate
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
+$ versioned-state
|
||||
@ -102,9 +102,19 @@
|
||||
=^ cards state
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%invite-action (poke-invite-action !<(action:store vase))
|
||||
%import (poke-import q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
=/ sty=state-1
|
||||
:- %1
|
||||
%- remake-map-of-map
|
||||
;;((tree [term (tree [serial:store invite:store])]) +.arc)
|
||||
[~ sty]
|
||||
::
|
||||
++ poke-invite-action
|
||||
|= =action:store
|
||||
^- (quip card _state)
|
||||
@ -205,5 +215,7 @@
|
||||
:^ ~ ~ %noun
|
||||
!> ^- (unit invite:store)
|
||||
(~(get by invitatory) serial)
|
||||
::
|
||||
[%x %export ~] ``noun+!>(state)
|
||||
==
|
||||
--
|
||||
|
@ -24,6 +24,6 @@
|
||||
<div id="portal-root"></div>
|
||||
<script src="/~landscape/js/channel.js"></script>
|
||||
<script src="/~landscape/js/session.js"></script>
|
||||
<script src="/~landscape/js/bundle/index.c099f574cf3ccea90625.js"></script>
|
||||
<script src="/~landscape/js/bundle/index.8c657f420ce31bef2c7b.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -17,10 +17,10 @@
|
||||
::
|
||||
++ export-app
|
||||
|= [app=@tas our=@p now=@da]
|
||||
.^(@ %gx /(scot %p our)/[app]/(scot %da now)/export/noun)
|
||||
.^(* %gx /(scot %p our)/[app]/(scot %da now)/export/noun)
|
||||
++ export-all
|
||||
|= [our=@p now=@da]
|
||||
^- (list [@tas @])
|
||||
^- (list [@tas *])
|
||||
%+ turn
|
||||
^- (list @tas)
|
||||
:~ %group-store
|
||||
@ -31,7 +31,6 @@
|
||||
%invite-store
|
||||
%chat-store
|
||||
%chat-hook
|
||||
%publish
|
||||
%graph-store
|
||||
==
|
||||
|= app=@tas
|
||||
@ -94,13 +93,14 @@
|
||||
(json-response:gen jon)
|
||||
::
|
||||
%import-all
|
||||
~& %import-all
|
||||
=/ enc (de:base64 base64-jam.source.com)
|
||||
?~ enc !!
|
||||
=/ by-app ;;((list [@tas @]) (cue q.u.enc))
|
||||
=/ by-app ;;((list [@tas *]) (cue q.u.enc))
|
||||
:_ this
|
||||
%+ weld (give-simple-payload:app eyre-id not-found:gen)
|
||||
%+ turn by-app
|
||||
|= [app=@tas data=@]
|
||||
|= [app=@tas data=*]
|
||||
^- card:agent:gall
|
||||
[%pass /import-all %agent [our.bowl app] %poke %import !>(data)]
|
||||
==
|
||||
|
@ -6,7 +6,7 @@
|
||||
:: /group/%group-path all updates related to this group
|
||||
::
|
||||
/- *metadata-store, *metadata-hook
|
||||
/+ default-agent, dbug, verb, grpl=group
|
||||
/+ default-agent, dbug, verb, grpl=group, *migrate
|
||||
~% %metadata-hook-top ..is ~
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
@ -51,9 +51,30 @@
|
||||
`this
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek on-peek:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-peek
|
||||
|= =path
|
||||
^- (unit (unit cage))
|
||||
?+ path (on-peek:def path)
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
==
|
||||
::
|
||||
++ on-arvo
|
||||
|= [=wire =sign-arvo]
|
||||
^- (quip card _this)
|
||||
?. ?=([%try-rejoin @ @ *] wire)
|
||||
(on-arvo:def wire sign-arvo)
|
||||
=/ nack-count=@ud (slav %ud i.t.wire)
|
||||
=/ who=@p (slav %p i.t.t.wire)
|
||||
=/ pax t.t.t.wire
|
||||
?> ?=([%b %wake *] sign-arvo)
|
||||
~? ?=(^ error.sign-arvo)
|
||||
"behn errored in backoff timers, continuing anyway"
|
||||
:_ this
|
||||
[(try-rejoin:hc who pax +(nack-count))]~
|
||||
::
|
||||
++ on-fail on-fail:def
|
||||
::
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
^- (quip card _this)
|
||||
@ -65,6 +86,12 @@
|
||||
::
|
||||
%metadata-action
|
||||
[(poke-action:hc !<(metadata-action vase)) this]
|
||||
::
|
||||
%import
|
||||
?> (team:title our.bowl src.bowl)
|
||||
=^ cards state
|
||||
(poke-import:hc q.vase)
|
||||
[cards this]
|
||||
==
|
||||
::
|
||||
++ on-watch
|
||||
@ -166,6 +193,26 @@
|
||||
!=(i.path '~')
|
||||
--
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
=/ sty=state-one
|
||||
[%1 (remake-map ;;((tree [group-path ship]) +.arc))]
|
||||
:_ sty
|
||||
%+ murn ~(tap by synced.sty)
|
||||
|= [=group-path =ship]
|
||||
?: =(ship our.bowl)
|
||||
~
|
||||
=/ =path [%group group-path]
|
||||
`(try-rejoin ship path 0)
|
||||
::
|
||||
++ try-rejoin
|
||||
|= [who=@p pax=path nack-count=@ud]
|
||||
^- card
|
||||
=/ =wire
|
||||
[%try-rejoin (scot %ud nack-count) (scot %p who) pax]
|
||||
[%pass wire %agent [who %metadata-hook] %watch pax]
|
||||
::
|
||||
++ watch-group
|
||||
|= =path
|
||||
^- (list card)
|
||||
@ -240,7 +287,11 @@
|
||||
|= wir=wire
|
||||
^- (quip card _state)
|
||||
:_ state
|
||||
|-
|
||||
?+ wir !!
|
||||
[%try-rejoin @ @ *]
|
||||
$(wir t.t.t.wir)
|
||||
::
|
||||
[%updates ~]
|
||||
[%pass /updates %agent [our.bowl %metadata-store] %watch /updates]~
|
||||
::
|
||||
@ -255,6 +306,14 @@
|
||||
++ watch-ack
|
||||
|= [wir=wire saw=(unit tang)]
|
||||
^- (quip card _state)
|
||||
?: ?=([%try-rejoin @ *] wir)
|
||||
?~ saw
|
||||
[~ state]
|
||||
=/ nack-count=@ud (slav %ud i.t.wir)
|
||||
=/ wakeup=@da
|
||||
(add now.bowl (mul ~s1 (bex (min 19 nack-count))))
|
||||
:_ state
|
||||
[%pass wir %arvo %b %wait wakeup]~
|
||||
?> ?=(^ wir)
|
||||
[~ ?~(saw state state(synced (~(del by synced) t.wir)))]
|
||||
::
|
||||
|
@ -24,7 +24,7 @@
|
||||
:: /group/%group-path associations for group
|
||||
::
|
||||
/- *metadata-store, *metadata-hook
|
||||
/+ *metadata-json, default-agent, verb, dbug, resource
|
||||
/+ *metadata-json, default-agent, verb, dbug, resource, *migrate
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
+$ base-state-0
|
||||
@ -278,6 +278,7 @@
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%metadata-action
|
||||
(poke-metadata-action:mc !<(metadata-action vase))
|
||||
::
|
||||
%noun
|
||||
=/ val=(each [%cleanup path] tang)
|
||||
(mule |.(!<([%cleanup path] vase)))
|
||||
@ -296,6 +297,9 @@
|
||||
[app-name.r group app-path.r]
|
||||
==
|
||||
out
|
||||
::
|
||||
%import
|
||||
(poke-import:mc q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
@ -350,6 +354,9 @@
|
||||
=/ app=term i.t.t.path
|
||||
=/ app-path=^path t.t.t.path
|
||||
``noun+!>((~(get by resource-indices) app app-path))
|
||||
::
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
==
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
@ -368,6 +375,31 @@
|
||||
%remove (handle-remove group-path.act resource.act)
|
||||
==
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
|^
|
||||
=/ sty=state-6
|
||||
[%6 (remake-metadata ;;(tree-metadata +.arc))]
|
||||
[~ sty]
|
||||
::
|
||||
+$ tree-metadata
|
||||
$: associations=(tree [[group-path md-resource] metadata])
|
||||
group-indices=(tree [group-path (tree md-resource)])
|
||||
app-indices=(tree [app-name (tree [group-path app-path])])
|
||||
resource-indices=(tree [md-resource (tree group-path)])
|
||||
==
|
||||
::
|
||||
++ remake-metadata
|
||||
|= tm=tree-metadata
|
||||
^- base-state-1
|
||||
:* (remake-map associations.tm)
|
||||
(remake-jug group-indices.tm)
|
||||
(remake-jug app-indices.tm)
|
||||
(remake-jug resource-indices.tm)
|
||||
==
|
||||
--
|
||||
::
|
||||
++ handle-add
|
||||
|= [=group-path =md-resource =metadata]
|
||||
^- (quip card _state)
|
||||
|
@ -10,10 +10,13 @@
|
||||
+$ card card:agent:gall
|
||||
+$ versioned-state
|
||||
$% state-0
|
||||
state-1
|
||||
==
|
||||
::
|
||||
+$ serial @uv
|
||||
+$ state-0 [%0 observers=(map serial observer:sur)]
|
||||
+$ state-1 [%1 observers=(map serial observer:sur)]
|
||||
::
|
||||
++ got-by-val
|
||||
|= [a=(map serial observer:sur) b=observer:sur]
|
||||
^- serial
|
||||
@ -24,7 +27,7 @@
|
||||
--
|
||||
::
|
||||
%- agent:dbug
|
||||
=| state-0
|
||||
=| state-1
|
||||
=* state -
|
||||
::
|
||||
^- agent:gall
|
||||
@ -35,8 +38,14 @@
|
||||
++ on-init
|
||||
|^ ^- (quip card _this)
|
||||
:_ this
|
||||
:_ ~
|
||||
(act /inv-gra [%watch %invite-store /invitatory/graph %invite-accepted-graph])
|
||||
:~ %+ act
|
||||
/inv-gra
|
||||
[%watch %invite-store /invitatory/graph %invite-accepted-graph]
|
||||
::
|
||||
%+ act
|
||||
/grp-gra
|
||||
[%watch %group-store /groups %group-on-leave]
|
||||
==
|
||||
::
|
||||
++ act
|
||||
|= [=wire =action:sur]
|
||||
@ -56,7 +65,17 @@
|
||||
++ on-load
|
||||
|= old-vase=vase
|
||||
^- (quip card _this)
|
||||
`this(state !<(state-0 old-vase))
|
||||
=/ old-state !<(versioned-state old-vase)
|
||||
?- -.old-state
|
||||
%1 `this(state old-state)
|
||||
::
|
||||
%0
|
||||
=. state [%1 observers.old-state]
|
||||
%+ on-poke
|
||||
%observe-action
|
||||
!> ^- action:sur
|
||||
[%watch %group-store /groups %group-on-leave]
|
||||
==
|
||||
::
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
|
@ -83,7 +83,7 @@
|
||||
?. ?=(%s -.jon)
|
||||
[~ state]
|
||||
=/ str=@t +.jon
|
||||
=/ req=request:http (request-darksky str)
|
||||
=/ req=request:http (request-wttr str)
|
||||
=/ out *outbound-config:iris
|
||||
=/ lismov=(list card)
|
||||
[%pass /[(scot %da now.bol)] %arvo %i %request req out]~
|
||||
@ -102,11 +102,11 @@
|
||||
^- (list card)
|
||||
[%give %fact ~[/all] %json !>((frond:enjs:format %location jon))]~
|
||||
::
|
||||
++ request-darksky
|
||||
++ request-wttr
|
||||
|= location=@t
|
||||
^- request:http
|
||||
=/ base 'https://api.darksky.net/forecast/634639c10670c7376dc66b6692fe57ca/'
|
||||
=/ url=@t (cat 3 (cat 3 base location) '?units=auto')
|
||||
=/ base 'https://wttr.in/'
|
||||
=/ url=@t (cat 3 (cat 3 base location) '?format=j1')
|
||||
=/ hed [['Accept' 'application/json']]~
|
||||
[%'GET' url hed *(unit octs)]
|
||||
::
|
||||
@ -133,8 +133,9 @@
|
||||
=/ jon=json
|
||||
%+ frond:enjs:format %weather
|
||||
%- pairs:enjs:format
|
||||
:~ [%currently (~(got by p.u.ujon) 'currently')]
|
||||
[%daily (~(got by p.u.ujon) 'daily')]
|
||||
:~ [%current-condition (~(got by p.u.ujon) 'current_condition')]
|
||||
[%weather (~(got by p.u.ujon) 'weather')]
|
||||
[%nearest-area (~(got by p.u.ujon) 'nearest_area')]
|
||||
==
|
||||
:- [%give %fact ~[/all] %json !>(jon)]~
|
||||
%= state
|
||||
@ -146,7 +147,7 @@
|
||||
|= [wir=wire err=(unit tang)]
|
||||
^- (quip card _state)
|
||||
?~ err
|
||||
=/ req/request:http (request-darksky location)
|
||||
=/ req/request:http (request-wttr location)
|
||||
=/ out *outbound-config:iris
|
||||
:_ state(timer `(add now.bol ~h3))
|
||||
:~ [%pass /[(scot %da now.bol)] %arvo %i %request req out]
|
||||
|
45
pkg/arvo/gen/aqua-export.hoon
Normal file
45
pkg/arvo/gen/aqua-export.hoon
Normal file
@ -0,0 +1,45 @@
|
||||
/+ *ph-util
|
||||
:- %say
|
||||
|= $: [now=@da eny=@uv bec=beak]
|
||||
[who=@p ~]
|
||||
~
|
||||
==
|
||||
|^
|
||||
:- %noun
|
||||
(export-all who)
|
||||
::
|
||||
++ export-app
|
||||
|= [who=ship agent=term]
|
||||
=/ aqua-pax=path
|
||||
:~ %i
|
||||
(scot %p who)
|
||||
%gx
|
||||
(scot %p who)
|
||||
agent
|
||||
(scot %da now)
|
||||
%export
|
||||
%noun
|
||||
%noun
|
||||
==
|
||||
~| agent
|
||||
%- need
|
||||
(scry-aqua (unit *) p.bec now aqua-pax)
|
||||
::
|
||||
++ export-all
|
||||
|= who=ship
|
||||
%+ turn
|
||||
^- (list @tas)
|
||||
:~ %group-store
|
||||
%metadata-store
|
||||
%metadata-hook
|
||||
%contact-store
|
||||
%contact-hook
|
||||
%invite-store
|
||||
%chat-store
|
||||
%chat-hook
|
||||
%graph-store
|
||||
==
|
||||
|= app=@tas
|
||||
[app (export-app who app)]
|
||||
::
|
||||
--
|
4
pkg/arvo/gen/aqua/breach.hoon
Normal file
4
pkg/arvo/gen/aqua/breach.hoon
Normal file
@ -0,0 +1,4 @@
|
||||
:- %say
|
||||
|= [* [her=ship ~] ~]
|
||||
:- %azimuth-action
|
||||
[%breach her]
|
4
pkg/arvo/gen/aqua/init-azimuth.hoon
Normal file
4
pkg/arvo/gen/aqua/init-azimuth.hoon
Normal file
@ -0,0 +1,4 @@
|
||||
:- %say
|
||||
|= [* ~ ~]
|
||||
:- %azimuth-action
|
||||
[%init-azimuth ~]
|
@ -3,4 +3,4 @@
|
||||
:- %say
|
||||
|= [* [her=ship ~] ~]
|
||||
:- %aqua-events
|
||||
[%init-ship her ~]~
|
||||
[%init-ship her `*dawn-event:able:jael]~
|
||||
|
@ -1,6 +1,6 @@
|
||||
/- aquarium
|
||||
=, aquarium
|
||||
:- %say
|
||||
|= [* [label=@ta] ~]
|
||||
|= [* [label=@ta ~] ~]
|
||||
:- %aqua-events
|
||||
[%snap-ships label]~
|
||||
[%restore-snap label]~
|
||||
|
@ -1,7 +1,7 @@
|
||||
/- aquarium
|
||||
=, aquarium
|
||||
:- %say
|
||||
|= [[now=@da eny=@uvJ bec=beak] [label=@ta] ships=(list ship)]
|
||||
|= [[now=@da eny=@uvJ bec=beak] [label=@ta ships=(list ship)] ~]
|
||||
:- %aqua-events
|
||||
=? ships ?=(~ ships)
|
||||
.^((list ship) %gx /(scot %p p.bec)/aqua/(scot %da now)/ships/noun)
|
||||
|
4
pkg/arvo/gen/aqua/spawn.hoon
Normal file
4
pkg/arvo/gen/aqua/spawn.hoon
Normal file
@ -0,0 +1,4 @@
|
||||
:- %say
|
||||
|= [* [her=ship ~] ~]
|
||||
:- %azimuth-action
|
||||
[%spawn her]
|
5
pkg/arvo/gen/sponsor.hoon
Normal file
5
pkg/arvo/gen/sponsor.hoon
Normal file
@ -0,0 +1,5 @@
|
||||
:: Print the sponsor of this ship
|
||||
:- %say
|
||||
|= [[now=time @ our=ship ^] * ~]
|
||||
:- %ship
|
||||
(sein:title our now our)
|
241
pkg/arvo/lib/aqua-azimuth.hoon
Normal file
241
pkg/arvo/lib/aqua-azimuth.hoon
Normal file
@ -0,0 +1,241 @@
|
||||
/- *aquarium
|
||||
::
|
||||
|%
|
||||
::
|
||||
++ extract-request
|
||||
|= [uf=unix-effect dest=@t]
|
||||
^- (unit [num=@ud =request:http])
|
||||
?. ?=(%request -.q.uf) ~
|
||||
?. =(dest url.request.q.uf) ~
|
||||
`[id.q.uf request.q.uf]
|
||||
::
|
||||
++ router
|
||||
|= [our=ship her=ship uf=unix-effect azi=az-state]
|
||||
^- (unit card:agent:gall)
|
||||
=, enjs:format
|
||||
=/ ask (extract-request uf 'http://localhost:8545/')
|
||||
?~ ask
|
||||
~
|
||||
?~ body.request.u.ask
|
||||
~
|
||||
=/ req q.u.body.request.u.ask
|
||||
|^ ^- (unit card:agent:gall)
|
||||
=/ method (get-method req)
|
||||
?: =(method 'eth_blockNumber')
|
||||
:- ~
|
||||
%+ answer-request req
|
||||
s+(crip (num-to-hex:ethereum latest-block))
|
||||
?: =(method 'eth_getBlockByNumber')
|
||||
:- ~
|
||||
%+ answer-request req
|
||||
:- %o
|
||||
=/ number (hex-to-num:ethereum (get-first-param req))
|
||||
=/ hash (number-to-hash number)
|
||||
=/ parent-hash (number-to-hash ?~(number number (dec number)))
|
||||
%- malt
|
||||
^- (list (pair term json))
|
||||
:~ hash+s+(crip (prefix-hex:ethereum (render-hex-bytes:ethereum 32 hash)))
|
||||
number+s+(crip (num-to-hex:ethereum number))
|
||||
'parentHash'^s+(crip (num-to-hex:ethereum parent-hash))
|
||||
==
|
||||
?: =(method 'eth_getLogs')
|
||||
:- ~
|
||||
%+ answer-request req
|
||||
?^ (get-param-obj-maybe req 'blockHash')
|
||||
%- logs-by-hash
|
||||
(get-param-obj req 'blockHash')
|
||||
%+ logs-by-range
|
||||
(get-param-obj req 'fromBlock')
|
||||
(get-param-obj req 'toBlock')
|
||||
~& [%ph-azimuth-miss req]
|
||||
~
|
||||
::
|
||||
++ latest-block
|
||||
(add launch:contracts:azimuth (dec (lent logs.azi)))
|
||||
::
|
||||
++ get-single-req
|
||||
|= req=@t
|
||||
=/ batch
|
||||
((ar:dejs:format same) (need (de-json:html req)))
|
||||
?> ?=([* ~] batch)
|
||||
i.batch
|
||||
::
|
||||
++ get-id
|
||||
|= req=@t
|
||||
=, dejs:format
|
||||
%. (get-single-req req)
|
||||
(ot id+so ~)
|
||||
::
|
||||
++ get-method
|
||||
|= req=@t
|
||||
=, dejs:format
|
||||
~| req=req
|
||||
%. (get-single-req req)
|
||||
(ot method+so ~)
|
||||
::
|
||||
++ get-param-obj
|
||||
|= [req=@t param=@t]
|
||||
=, dejs:format
|
||||
%- hex-to-num:ethereum
|
||||
=/ array
|
||||
%. (get-single-req req)
|
||||
(ot params+(ar (ot param^so ~)) ~)
|
||||
?> ?=([* ~] array)
|
||||
i.array
|
||||
::
|
||||
++ get-param-obj-maybe
|
||||
|= [req=@t param=@t]
|
||||
^- (unit @ud)
|
||||
=, dejs-soft:format
|
||||
=/ array
|
||||
%. (get-single-req req)
|
||||
(ot params+(ar (ot param^so ~)) ~)
|
||||
?~ array
|
||||
~
|
||||
:- ~
|
||||
?> ?=([* ~] u.array)
|
||||
%- hex-to-num:ethereum
|
||||
i.u.array
|
||||
::
|
||||
++ get-first-param
|
||||
|= req=@t
|
||||
=, dejs:format
|
||||
=/ id
|
||||
%. (get-single-req req)
|
||||
(ot params+(at so bo ~) ~)
|
||||
-.id
|
||||
::
|
||||
++ answer-request
|
||||
|= [req=@t result=json]
|
||||
^- card:agent:gall
|
||||
=/ resp
|
||||
%- crip
|
||||
%- en-json:html
|
||||
:- %a :_ ~
|
||||
%- pairs
|
||||
:~ id+s+(get-id req)
|
||||
jsonrpc+s+'2.0'
|
||||
result+result
|
||||
==
|
||||
=/ events=(list aqua-event)
|
||||
:_ ~
|
||||
:* %event
|
||||
her
|
||||
//http-client/0v1n.2m9vh
|
||||
%receive
|
||||
num.u.ask
|
||||
[%start [200 ~] `(as-octs:mimes:html resp) &]
|
||||
==
|
||||
:* %pass /aqua-events
|
||||
%agent [our %aqua]
|
||||
%poke %aqua-events
|
||||
!>(events)
|
||||
==
|
||||
::
|
||||
++ number-to-hash
|
||||
|= =number:block:able:jael
|
||||
^- @
|
||||
?: (lth number launch:contracts:azimuth)
|
||||
(cat 3 0x5364 (sub launch:contracts:azimuth number))
|
||||
(cat 3 0x5363 (sub number launch:contracts:azimuth))
|
||||
::
|
||||
++ hash-to-number
|
||||
|= =hash:block:able:jael
|
||||
(add launch:contracts:azimuth (div hash 0x1.0000))
|
||||
::
|
||||
++ logs-by-range
|
||||
|= [from-block=@ud to-block=@ud]
|
||||
%+ logs-to-json (max launch:contracts:azimuth from-block)
|
||||
?: (lth to-block launch:contracts:azimuth)
|
||||
~
|
||||
%+ swag
|
||||
?: (lth from-block launch:contracts:azimuth)
|
||||
[0 +((sub to-block launch:contracts:azimuth))]
|
||||
:- (sub from-block launch:contracts:azimuth)
|
||||
+((sub to-block from-block))
|
||||
logs.azi
|
||||
::
|
||||
++ logs-by-hash
|
||||
|= =hash:block:able:jael
|
||||
=/ =number:block:able:jael (hash-to-number hash)
|
||||
(logs-by-range number number)
|
||||
::
|
||||
++ logs-to-json
|
||||
|= [count=@ud selected-logs=(list az-log)]
|
||||
^- json
|
||||
:- %a
|
||||
|- ^- (list json)
|
||||
?~ selected-logs
|
||||
~
|
||||
:_ $(selected-logs t.selected-logs, count +(count))
|
||||
%- pairs
|
||||
:~ 'logIndex'^s+'0x0'
|
||||
'transactionIndex'^s+'0x0'
|
||||
:+ 'transactionHash' %s
|
||||
(crip (prefix-hex:ethereum (render-hex-bytes:ethereum 32 `@`0x5362)))
|
||||
::
|
||||
:+ 'blockHash' %s
|
||||
=/ hash (number-to-hash count)
|
||||
(crip (prefix-hex:ethereum (render-hex-bytes:ethereum 32 hash)))
|
||||
::
|
||||
:+ 'blockNumber' %s
|
||||
(crip (num-to-hex:ethereum count))
|
||||
::
|
||||
:+ 'address' %s
|
||||
(crip (address-to-hex:ethereum azimuth:contracts:azimuth))
|
||||
::
|
||||
'type'^s+'mined'
|
||||
::
|
||||
'data'^s+data.i.selected-logs
|
||||
:+ 'topics' %a
|
||||
%+ turn topics.i.selected-logs
|
||||
|= topic=@ux
|
||||
^- json
|
||||
:- %s
|
||||
%- crip
|
||||
%- prefix-hex:ethereum
|
||||
(render-hex-bytes:ethereum 32 `@`topic)
|
||||
==
|
||||
--
|
||||
::
|
||||
++ get-keys
|
||||
|= [who=@p lyfe=life]
|
||||
^- acru:ames
|
||||
%+ pit:nu:crub:crypto 32
|
||||
(can 5 [1 (scot %p who)] [1 (scot %ud lyfe)] ~)
|
||||
::
|
||||
++ get-public
|
||||
|= [who=@p lyfe=life typ=?(%auth %crypt)]
|
||||
=/ bod (rsh 3 1 pub:ex:(get-keys who lyfe))
|
||||
=+ [enc=(rsh 8 1 bod) aut=(end 8 1 bod)]
|
||||
?: =(%auth typ)
|
||||
aut
|
||||
enc
|
||||
::
|
||||
:: Generate logs
|
||||
::
|
||||
++ lo
|
||||
=, azimuth-events:azimuth
|
||||
|%
|
||||
++ broke-continuity
|
||||
|= [who=ship rut=rift]
|
||||
^- az-log
|
||||
:- ~[^broke-continuity who]
|
||||
%- crip
|
||||
%- prefix-hex:ethereum
|
||||
(render-hex-bytes:ethereum 32 `@`rut)
|
||||
::
|
||||
++ changed-keys
|
||||
|= [who=ship enc=@ux aut=@ux crypto=@ud lyfe=life]
|
||||
^- az-log
|
||||
:- ~[^changed-keys who]
|
||||
%- crip
|
||||
%- prefix-hex:ethereum
|
||||
;: welp
|
||||
(render-hex-bytes:ethereum 32 `@`enc)
|
||||
(render-hex-bytes:ethereum 32 `@`aut)
|
||||
(render-hex-bytes:ethereum 32 `@`crypto)
|
||||
(render-hex-bytes:ethereum 32 `@`lyfe)
|
||||
==
|
||||
--
|
||||
--
|
@ -417,6 +417,7 @@
|
||||
::
|
||||
++ remove-group
|
||||
|= =json
|
||||
^- [resource ~]
|
||||
?> ?=(%o -.json)
|
||||
=/ rid=resource
|
||||
(dejs:resource (~(got by p.json) 'resource'))
|
||||
|
@ -1,3 +1,4 @@
|
||||
/+ version
|
||||
=, clay
|
||||
=, space:userlib
|
||||
=, format
|
||||
@ -108,9 +109,13 @@
|
||||
++ on-peek
|
||||
|= =path
|
||||
^- (unit (unit cage))
|
||||
?. ?=([%x %kiln %ota ~] path)
|
||||
[~ ~]
|
||||
``noun+!>(ota)
|
||||
?+ path [~ ~]
|
||||
[%x %kiln %ota ~] ``noun+!>(ota)
|
||||
[%x %kiln %our ~] ``noun+!>(our)
|
||||
[%x %kiln %base-hash ~]
|
||||
=/ ver (base-hash:version our now)
|
||||
``noun+!>(?~(ver 0v0 i.ver))
|
||||
==
|
||||
::
|
||||
++ poke-commit
|
||||
|= [mon/kiln-commit auto=?]
|
||||
|
19
pkg/arvo/lib/migrate.hoon
Normal file
19
pkg/arvo/lib/migrate.hoon
Normal file
@ -0,0 +1,19 @@
|
||||
|%
|
||||
++ remake-set
|
||||
|* s=(tree)
|
||||
(sy ~(tap in s))
|
||||
::
|
||||
++ remake-map
|
||||
|* m=(tree)
|
||||
(my ~(tap by m))
|
||||
::
|
||||
++ remake-jug
|
||||
|* j=(tree [* (tree)])
|
||||
%- remake-map
|
||||
(~(run by j) remake-set)
|
||||
::
|
||||
++ remake-map-of-map
|
||||
|* mm=(tree [* (tree)])
|
||||
%- remake-map
|
||||
(~(run by mm) remake-map)
|
||||
--
|
@ -8,6 +8,12 @@
|
||||
^- form:m
|
||||
(poke-our %aqua %aqua-events !>(events))
|
||||
::
|
||||
++ send-azimuth-action
|
||||
|= =azimuth-action
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
(poke-our %aqua %azimuth-action !>(azimuth-action))
|
||||
::
|
||||
++ take-unix-effect
|
||||
=/ m (strand ,[ship unix-effect])
|
||||
^- form:m
|
||||
@ -34,7 +40,7 @@
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
~& > "starting"
|
||||
;< ~ bind:m (start-threads vane-threads)
|
||||
;< tids=(map term tid:spider) bind:m (start-threads vane-threads)
|
||||
;< ~ bind:m (watch-our /effect %aqua /effect)
|
||||
:: Get our very own event with no mistakes in it... yet.
|
||||
::
|
||||
@ -64,16 +70,20 @@
|
||||
::
|
||||
++ start-threads
|
||||
|= threads=(list term)
|
||||
=/ m (strand ,~)
|
||||
=/ m (strand ,(map term tid:spider))
|
||||
^- form:m
|
||||
;< =bowl:spider bind:m get-bowl
|
||||
=| tids=(map term tid:spider)
|
||||
|- ^- form:m
|
||||
=* loop $
|
||||
?~ threads
|
||||
(pure:m ~)
|
||||
(pure:m tids)
|
||||
=/ tid
|
||||
%+ scot %ta
|
||||
(cat 3 (cat 3 'strand_' i.threads) (scot %uv (sham i.threads eny.bowl)))
|
||||
=/ poke-vase !>([`tid.bowl ~ i.threads *vase])
|
||||
;< ~ bind:m (poke-our %spider %spider-start poke-vase)
|
||||
loop(threads t.threads)
|
||||
loop(threads t.threads, tids (~(put by tids) i.threads tid))
|
||||
::
|
||||
++ stop-threads
|
||||
|= threads=(list term)
|
||||
@ -81,6 +91,29 @@
|
||||
^- form:m
|
||||
(pure:m ~)
|
||||
::
|
||||
:: XX +spawn-aqua and +breach-aqua mean do these actions using aqua's internal
|
||||
:: azimuth management system, eventually these should just replace +spawn
|
||||
:: +breach
|
||||
::
|
||||
++ init-azimuth
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
(send-azimuth-action %init-azimuth ~)
|
||||
::
|
||||
++ spawn-aqua
|
||||
|= =ship
|
||||
~& > "spawning {<ship>}"
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
(send-azimuth-action %spawn ship)
|
||||
::
|
||||
++ breach-aqua
|
||||
|= =ship
|
||||
~& > "breaching {<ship>}"
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
(send-azimuth-action %breach ship)
|
||||
::
|
||||
++ spawn
|
||||
|= [=tid:spider =ship]
|
||||
~& > "spawning {<ship>}"
|
||||
@ -127,6 +160,39 @@
|
||||
(pure:m ~)
|
||||
loop
|
||||
::
|
||||
++ breach-and-hear-aqua
|
||||
|= [who=ship her=ship]
|
||||
=/ m (strand ,~)
|
||||
;< =bowl:spider bind:m get-bowl
|
||||
=/ aqua-pax
|
||||
:- %i
|
||||
/(scot %p her)/j/(scot %p her)/rift/(scot %da now.bowl)/(scot %p who)/noun
|
||||
=/ old-rut ;;((unit @) (scry-aqua:util noun our.bowl now.bowl aqua-pax))
|
||||
=/ new-rut
|
||||
?~ old-rut
|
||||
1
|
||||
+(+.old-rut)
|
||||
;< ~ bind:m (send-azimuth-action %breach who)
|
||||
|- ^- form:m
|
||||
=* loop $
|
||||
;< ~ bind:m (sleep ~s1)
|
||||
;< =bowl:spider bind:m get-bowl
|
||||
=/ aqua-pax
|
||||
:- %i
|
||||
/(scot %p her)/j/(scot %p her)/rift/(scot %da now.bowl)/(scot %p who)/noun
|
||||
=/ rut (scry-aqua:util noun our.bowl now.bowl aqua-pax)
|
||||
?: =([~ new-rut] rut)
|
||||
(pure:m ~)
|
||||
loop
|
||||
::
|
||||
++ init-ship
|
||||
|= =ship
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
~& > "starting {<ship>}"
|
||||
;< ~ bind:m (send-events (init:util ship `*dawn-event:able:jael))
|
||||
(check-ship-booted ship)
|
||||
::
|
||||
++ real-ship
|
||||
|= [=tid:spider =ship]
|
||||
~& > "booting real {<ship>}"
|
||||
@ -275,4 +341,20 @@
|
||||
?: =(warped (need (scry-aqua:util (unit @) our now aqua-pax)))
|
||||
(pure:m ~)
|
||||
loop
|
||||
::
|
||||
:: Turns poke into a dojo command
|
||||
::
|
||||
++ poke-app
|
||||
|= [=ship app=term =mark data=*]
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
=/ command=tape ":{(trip app)} &{(trip mark)} {<data>}"
|
||||
(send-events (dojo:util ship command))
|
||||
::
|
||||
++ dojo-thread
|
||||
|= [=ship ted=term =mark data=*]
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
=/ command=tape "-{(trip ted)} &{(trip mark)} {<data>}"
|
||||
(send-events (dojo:util ship command))
|
||||
--
|
||||
|
@ -196,6 +196,7 @@
|
||||
=. inner-state
|
||||
on-save:og
|
||||
!>(state)
|
||||
::
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
^- [(list card:agent:gall) agent:gall]
|
||||
|
@ -219,6 +219,25 @@
|
||||
;< ~ bind:m (send-raw-card card)
|
||||
(take-poke-ack /poke)
|
||||
::
|
||||
++ raw-poke
|
||||
|= [=dock =cage]
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
=/ =card:agent:gall [%pass /poke %agent dock %poke cage]
|
||||
;< ~ bind:m (send-raw-card card)
|
||||
=/ m (strand ,~)
|
||||
^- form:m
|
||||
|= tin=strand-input:strand
|
||||
?+ in.tin `[%skip ~]
|
||||
~
|
||||
`[%wait ~]
|
||||
::
|
||||
[~ %agent * %poke-ack *]
|
||||
?. =(/poke wire.u.in.tin)
|
||||
`[%skip ~]
|
||||
`[%done ~]
|
||||
==
|
||||
::
|
||||
++ poke-our
|
||||
|= [=term =cage]
|
||||
=/ m (strand ,~)
|
||||
@ -651,11 +670,16 @@
|
||||
::
|
||||
++ start-thread
|
||||
|= file=term
|
||||
(start-thread-with-args file *vase)
|
||||
::
|
||||
++ start-thread-with-args
|
||||
|= [file=term args=vase]
|
||||
=/ m (strand ,tid:spider)
|
||||
^- form:m
|
||||
;< =bowl:spider bind:m get-bowl
|
||||
=/ tid (scot %ta (cat 3 'strand_' (scot %uv (sham file eny.bowl))))
|
||||
=/ poke-vase !>([`tid.bowl `tid file *vase])
|
||||
=/ tid
|
||||
(scot %ta (cat 3 (cat 3 'strand_' file) (scot %uv (sham file eny.bowl))))
|
||||
=/ poke-vase !>([`tid.bowl `tid file args])
|
||||
;< ~ bind:m (poke-our %spider %spider-start poke-vase)
|
||||
;< ~ bind:m (sleep ~s0) :: wait for thread to start
|
||||
(pure:m tid)
|
||||
|
12
pkg/arvo/mar/contact/view-action.hoon
Normal file
12
pkg/arvo/mar/contact/view-action.hoon
Normal file
@ -0,0 +1,12 @@
|
||||
/- *contact-view
|
||||
|_ act=contact-view-action
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
++ noun act
|
||||
--
|
||||
++ grab
|
||||
|%
|
||||
++ noun contact-view-action
|
||||
--
|
||||
--
|
@ -14,7 +14,7 @@
|
||||
--
|
||||
++ grab
|
||||
|% :: convert from
|
||||
++ mime |=({p/mite q/octs} (@t q.q))
|
||||
++ mime |=([p=mite q=octs] (@t q.q))
|
||||
++ noun @t :: clam from %noun
|
||||
--
|
||||
++ grad %mime
|
||||
|
@ -5,8 +5,9 @@
|
||||
++ noun i
|
||||
++ notification-kind
|
||||
?+ index.p.i ~
|
||||
[@ ~] `[%link 0]
|
||||
[@ @ @ ~] `[%comment 1]
|
||||
[@ ~] `[%link 0]
|
||||
[@ @ %1 ~] `[%comment 1]
|
||||
[@ @ @ ~] `[%edit-comment 1]
|
||||
==
|
||||
--
|
||||
++ grab
|
||||
|
@ -8,8 +8,10 @@
|
||||
::
|
||||
++ notification-kind
|
||||
?+ index.p.i ~
|
||||
[@ %1 @ ~] `[%note 0]
|
||||
[@ %2 @ @ ~] `[%comment 1]
|
||||
[@ %1 %1 ~] `[%note 0]
|
||||
[@ %1 @ ~] `[%edit-note 0]
|
||||
[@ %2 @ %1 ~] `[%comment 1]
|
||||
[@ %2 @ @ ~] `[%edit-comment 1]
|
||||
==
|
||||
--
|
||||
++ grab
|
||||
|
@ -41,7 +41,7 @@
|
||||
--
|
||||
++ grab
|
||||
|% :: convert from
|
||||
++ mime |=({p/mite q/octs} q.q)
|
||||
++ mime |=([p=mite q=octs] q.q)
|
||||
++ noun @t :: clam from %noun
|
||||
++ txt of-wain:format
|
||||
--
|
||||
|
@ -17,7 +17,7 @@
|
||||
++ grab ^?
|
||||
|% :: convert from
|
||||
++ noun @t :: clam from %noun
|
||||
++ mime |=({p/mite q/octs} q.q) :: retrieve form $mime
|
||||
++ mime |=([p=mite q=octs] q.q) :: retrieve form $mime
|
||||
--
|
||||
++ grad %mime
|
||||
--
|
||||
|
15
pkg/arvo/mar/import.hoon
Normal file
15
pkg/arvo/mar/import.hoon
Normal file
@ -0,0 +1,15 @@
|
||||
=, mimes:html
|
||||
|_ non=*
|
||||
++ grab
|
||||
|%
|
||||
++ noun *
|
||||
++ mime
|
||||
|= [* p=octs]
|
||||
(cue q.p)
|
||||
--
|
||||
++ grow
|
||||
|%
|
||||
++ mime [/application/x-urb-import (as-octs (jam non))]
|
||||
--
|
||||
++ grad %mime
|
||||
--
|
@ -15,7 +15,7 @@
|
||||
--
|
||||
++ grab
|
||||
|% :: convert from
|
||||
++ mime |=({p/mite q/octs} (@t q.q))
|
||||
++ mime |=([p=mite q=octs] (@t q.q))
|
||||
++ noun cord :: clam from %noun
|
||||
--
|
||||
++ grad %mime
|
||||
|
@ -17,7 +17,7 @@
|
||||
--
|
||||
++ grab
|
||||
|% :: convert from
|
||||
++ mime |=({p/mite q/octs} (fall (rush (@t q.q) apex:de-json) *json))
|
||||
++ mime |=([p=mite q=octs] (fall (rush (@t q.q) apex:de-json) *json))
|
||||
++ noun json :: clam from %noun
|
||||
++ numb numb:enjs
|
||||
++ time time:enjs
|
||||
|
12
pkg/arvo/mar/metadata/hook-action.hoon
Normal file
12
pkg/arvo/mar/metadata/hook-action.hoon
Normal file
@ -0,0 +1,12 @@
|
||||
/- *metadata-hook
|
||||
|_ act=metadata-hook-action
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
++ noun act
|
||||
--
|
||||
++ grab
|
||||
|%
|
||||
++ noun metadata-hook-action
|
||||
--
|
||||
--
|
@ -16,7 +16,7 @@
|
||||
|%
|
||||
+$ noun mime :: clam from %noun
|
||||
++ tape
|
||||
|=(a/_"" [/application/x-urb-unknown (as-octt:mimes:html a)])
|
||||
|=(a=^tape [/application/x-urb-unknown (as-octt:mimes:html a)])
|
||||
--
|
||||
++ grad
|
||||
^?
|
||||
|
@ -5,7 +5,7 @@
|
||||
--
|
||||
++ grab
|
||||
|%
|
||||
++ mime |=({p/mite q/octs} q.q)
|
||||
++ mime |=([p=mite q=octs] q.q)
|
||||
++ noun @t
|
||||
--
|
||||
++ grad %mime
|
||||
|
@ -7,7 +7,7 @@
|
||||
++ words 1
|
||||
++ hedtal
|
||||
=| met/marl
|
||||
|= a/marl ^- {hed/marl tal/marl}
|
||||
|= a=marl ^- {hed/marl tal/marl}
|
||||
?~ a [~ ~]
|
||||
?. ?=($h1 n.g.i.a)
|
||||
?: ?=($meta n.g.i.a)
|
||||
@ -18,7 +18,7 @@
|
||||
[c.i.a (weld (flop met) (limit words t.a))]
|
||||
::
|
||||
++ limit
|
||||
|= {lim/@u mal/marl}
|
||||
|= [lim=@u mal=marl]
|
||||
=< res
|
||||
|- ^- {rem/@u res/marl}
|
||||
?~ mal [lim ~]
|
||||
@ -30,7 +30,7 @@
|
||||
[rem - res]:[hed $(lim lam, mal t.mal)]
|
||||
::
|
||||
++ deword
|
||||
|= {lim/@u tay/tape} ^- {lim/@u tay/tape}
|
||||
|= [lim=@u tay=tape] ^- {lim/@u tay/tape}
|
||||
?~ tay [lim tay]
|
||||
?~ lim [0 ~]
|
||||
=+ wer=(dot 1^1 tay)
|
||||
@ -58,5 +58,5 @@
|
||||
--
|
||||
++ grab |% :: convert from
|
||||
++ noun {marl marl} :: clam from $noun
|
||||
++ elem |=(a/manx (hedtal +.a))
|
||||
++ elem |=(a=manx (hedtal +.a))
|
||||
-- --
|
||||
|
@ -12,11 +12,11 @@
|
||||
++ elem
|
||||
=- ;pre:code:"{(of-wall -)}"
|
||||
^- wall %- zing ^- (list wall)
|
||||
(turn (flop tan) |=(a/tank (wash 0^160 a)))
|
||||
(turn (flop tan) |=(a=tank (wash 0^160 a)))
|
||||
--
|
||||
++ grab :: convert from
|
||||
|%
|
||||
++ noun (list ^tank) :: clam from %noun
|
||||
++ tank |=(a/^tank [a]~)
|
||||
++ tank |=(a=^tank [a]~)
|
||||
--
|
||||
--
|
||||
|
@ -24,18 +24,18 @@
|
||||
|%
|
||||
++ form %txt-diff
|
||||
++ diff
|
||||
|= tyt/wain
|
||||
|= tyt=wain
|
||||
^- (urge cord)
|
||||
(lusk txt tyt (loss txt tyt))
|
||||
::
|
||||
++ pact
|
||||
|= dif/(urge cord)
|
||||
|= dif=(urge cord)
|
||||
~| [%pacting dif]
|
||||
^- wain
|
||||
(lurk txt dif)
|
||||
::
|
||||
++ join
|
||||
|= {ali/(urge cord) bob/(urge cord)}
|
||||
|= [ali=(urge cord) bob=(urge cord)]
|
||||
^- (unit (urge cord))
|
||||
|^
|
||||
=. ali (clean ali)
|
||||
@ -49,20 +49,20 @@
|
||||
%&
|
||||
?: =(p.i.ali p.i.bob)
|
||||
%+ bind $(ali t.ali, bob t.bob)
|
||||
|=(cud/(urge cord) [i.ali cud])
|
||||
|=(cud=(urge cord) [i.ali cud])
|
||||
?: (gth p.i.ali p.i.bob)
|
||||
%+ bind $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob)
|
||||
|=(cud/(urge cord) [i.bob cud])
|
||||
|=(cud=(urge cord) [i.bob cud])
|
||||
%+ bind $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali))
|
||||
|=(cud/(urge cord) [i.ali cud])
|
||||
|=(cud=(urge cord) [i.ali cud])
|
||||
::
|
||||
%|
|
||||
?: =(p.i.ali (lent p.i.bob))
|
||||
%+ bind $(ali t.ali, bob t.bob)
|
||||
|=(cud/(urge cord) [i.bob cud])
|
||||
|=(cud=(urge cord) [i.bob cud])
|
||||
?: (gth p.i.ali (lent p.i.bob))
|
||||
%+ bind $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob)
|
||||
|=(cud/(urge cord) [i.bob cud])
|
||||
|=(cud=(urge cord) [i.bob cud])
|
||||
~
|
||||
==
|
||||
::
|
||||
@ -77,15 +77,15 @@
|
||||
%&
|
||||
?: =(p.i.bob (lent p.i.ali))
|
||||
%+ bind $(ali t.ali, bob t.bob)
|
||||
|=(cud/(urge cord) [i.ali cud])
|
||||
|=(cud=(urge cord) [i.ali cud])
|
||||
?: (gth p.i.bob (lent p.i.ali))
|
||||
%+ bind $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali)))
|
||||
|=(cud/(urge cord) [i.ali cud])
|
||||
|=(cud=(urge cord) [i.ali cud])
|
||||
~
|
||||
==
|
||||
==
|
||||
++ clean :: clean
|
||||
|= wig/(urge cord)
|
||||
|= wig=(urge cord)
|
||||
^- (urge cord)
|
||||
?~ wig ~
|
||||
?~ t.wig wig
|
||||
@ -179,7 +179,7 @@
|
||||
~
|
||||
::
|
||||
++ clean :: clean
|
||||
|= wig/(urge cord)
|
||||
|= wig=(urge cord)
|
||||
^- (urge cord)
|
||||
?~ wig ~
|
||||
?~ t.wig wig
|
||||
@ -192,7 +192,7 @@
|
||||
[i.wig $(wig t.wig)]
|
||||
::
|
||||
++ resolve
|
||||
|= {ali/(urge cord) bob/(urge cord)}
|
||||
|= [ali=(urge cord) bob=(urge cord)]
|
||||
^- {fic/{%| p/(list cord) q/(list cord)} ali/(urge cord) bob/(urge cord)}
|
||||
=- [[%| bac (annotate alc boc bac)] ali bob]
|
||||
|- ^- $: $: bac/(list cord)
|
||||
|
@ -17,5 +17,5 @@
|
||||
-- ::
|
||||
++ grab |% :: convert from
|
||||
++ noun @t :: clam from %noun
|
||||
++ mime |=({p/mite q/octs} q.q) :: retrieve form $mime
|
||||
++ mime |=([p=mite q=octs] q.q) :: retrieve form $mime
|
||||
-- --
|
||||
|
@ -13,6 +13,12 @@
|
||||
/+ pill
|
||||
=, pill-lib=pill
|
||||
|%
|
||||
+$ az-log [topics=(lest @) data=@t]
|
||||
+$ az-state
|
||||
$: logs=(list az-log)
|
||||
lives=(map ship [lyfe=life rut=rift])
|
||||
tym=@da
|
||||
==
|
||||
++ ph-event
|
||||
$% [%test-done p=?]
|
||||
aqua-event
|
||||
@ -29,6 +35,12 @@
|
||||
[%event who=ship ue=unix-event]
|
||||
==
|
||||
::
|
||||
+$ azimuth-action
|
||||
$% [%init-azimuth ~]
|
||||
[%spawn who=ship]
|
||||
[%breach who=ship]
|
||||
==
|
||||
::
|
||||
+$ aqua-effects
|
||||
[who=ship ufs=(list unix-effect)]
|
||||
::
|
||||
@ -57,6 +69,7 @@
|
||||
[%ergo p=@tas q=mode:clay]
|
||||
[%sleep ~]
|
||||
[%restore ~]
|
||||
[%kill ~]
|
||||
[%init ~]
|
||||
[%request id=@ud request=request:http]
|
||||
==
|
||||
|
@ -7896,7 +7896,7 @@
|
||||
:: # constants
|
||||
::
|
||||
:: contract addresses
|
||||
++ contracts mainnet-contracts
|
||||
++ contracts ropsten-contracts
|
||||
++ mainnet-contracts
|
||||
|%
|
||||
:: azimuth: data contract
|
||||
|
@ -85,7 +85,7 @@
|
||||
--
|
||||
--
|
||||
::
|
||||
%+ aqua-vane-thread ~[%sleep %restore %doze]
|
||||
%+ aqua-vane-thread ~[%sleep %restore %doze %kill]
|
||||
|_ =bowl:spider
|
||||
+* this .
|
||||
++ handle-unix-effect
|
||||
@ -96,6 +96,7 @@
|
||||
%sleep abet-pe:handle-sleep:(pe bowl who)
|
||||
%restore abet-pe:handle-restore:(pe bowl who)
|
||||
%doze abet-pe:(handle-doze:(pe bowl who) ue)
|
||||
%kill `(~(del by piers) who)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
|
@ -25,6 +25,7 @@
|
||||
%sag ~& [%save-jamfile-to p.b] line
|
||||
%sav ~& [%save-file-to p.b] line
|
||||
%url ~& [%activate-url p.b] line
|
||||
%klr ~& %unhandled-case-klr ""
|
||||
==
|
||||
~? !=(~ last-line) last-line
|
||||
~
|
||||
|
@ -100,7 +100,7 @@
|
||||
--
|
||||
--
|
||||
::
|
||||
%+ aqua-vane-thread ~[%sleep %restore %thus]
|
||||
%+ aqua-vane-thread ~[%sleep %restore %thus %kill]
|
||||
|_ =bowl:spider
|
||||
+* this .
|
||||
++ handle-unix-effect
|
||||
@ -111,6 +111,7 @@
|
||||
%sleep abet-pe:handle-sleep:(pe bowl who)
|
||||
%restore abet-pe:handle-restore:(pe bowl who)
|
||||
%thus abet-pe:(handle-thus:(pe bowl who) ue)
|
||||
%kill `(~(del by piers) who)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
|
94
pkg/arvo/ted/group/on-leave.hoon
Normal file
94
pkg/arvo/ted/group/on-leave.hoon
Normal file
@ -0,0 +1,94 @@
|
||||
/- spider, grp=group-store, gra=graph-store, met=metadata-store, con=contact-store
|
||||
/+ strandio, res=resource
|
||||
::
|
||||
=* strand strand:spider
|
||||
=* raw-poke raw-poke:strandio
|
||||
=* scry scry:strandio
|
||||
::
|
||||
^- thread:spider
|
||||
|= arg=vase
|
||||
=/ m (strand ,vase)
|
||||
^- form:m
|
||||
=+ !<([=update:grp ~] arg)
|
||||
?. ?=(%remove-group -.update)
|
||||
(pure:m !>(~))
|
||||
;< =bowl:spider bind:m get-bowl:strandio
|
||||
:: tell group host to remove us as member
|
||||
::
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[entity.resource.update %group-push-hook]
|
||||
:- %group-update
|
||||
!> ^- update:grp
|
||||
[%remove-members resource.update (silt [our.bowl ~])]
|
||||
:: stop serving or syncing group updates
|
||||
::
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %group-push-hook]
|
||||
:- %push-hook-action
|
||||
!>([%remove resource.update])
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %group-pull-hook]
|
||||
:- %pull-hook-action
|
||||
!>([%remove resource.update])
|
||||
:: stop serving or syncing contacts associated with group
|
||||
::
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %contact-hook]
|
||||
:- %contact-hook-action
|
||||
!>([%remove (en-path:res resource.update)])
|
||||
:: remove contact data associated with group
|
||||
::
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %contact-store]
|
||||
:- %contact-action
|
||||
!> ^- contact-action:con
|
||||
[%delete (en-path:res resource.update)]
|
||||
:: stop serving or syncing metadata associated with group
|
||||
::
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %metadata-hook]
|
||||
:- %metadata-hook-action
|
||||
!>([%remove (en-path:res resource.update)])
|
||||
:: get metadata associated with group
|
||||
::
|
||||
;< =associations:met bind:m
|
||||
%+ scry associations:met
|
||||
;: weld
|
||||
/gx/metadata-store/group
|
||||
(en-path:res resource.update)
|
||||
/noun
|
||||
==
|
||||
=/ entries=(list [g=group-path:met m=md-resource:met])
|
||||
~(tap in ~(key by associations))
|
||||
|- ^- form:m
|
||||
=* loop $
|
||||
?~ entries
|
||||
(pure:m !>(~))
|
||||
:: remove metadata associated with group
|
||||
::
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %metadata-store]
|
||||
:- %metadata-action
|
||||
!> ^- metadata-action:met
|
||||
[%remove g.i.entries m.i.entries]
|
||||
:: archive graph associated with group
|
||||
::
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %graph-store]
|
||||
:- %graph-update
|
||||
!> ^- update:gra
|
||||
[%0 now.bowl [%archive-graph (de-path:res app-path.m.i.entries)]]
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %graph-pull-hook]
|
||||
:- %pull-hook-action
|
||||
!>([%remove (de-path:res app-path.m.i.entries)])
|
||||
loop(entries t.entries)
|
19
pkg/arvo/ted/ph/breach-hi-aqua.hoon
Normal file
19
pkg/arvo/ted/ph/breach-hi-aqua.hoon
Normal file
@ -0,0 +1,19 @@
|
||||
/- spider
|
||||
/+ *ph-io, *ph-util
|
||||
=, strand=strand:spider
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< =bowl:spider bind:m get-bowl
|
||||
;< ~ bind:m start-simple
|
||||
;< ~ bind:m init-azimuth
|
||||
;< ~ bind:m (spawn-aqua ~bud)
|
||||
;< ~ bind:m (spawn-aqua ~dev)
|
||||
;< ~ bind:m (init-ship ~bud)
|
||||
;< ~ bind:m (init-ship ~dev)
|
||||
;< ~ bind:m (send-hi ~bud ~dev)
|
||||
;< ~ bind:m (breach-and-hear-aqua ~dev ~bud)
|
||||
;< ~ bind:m (send-hi-not-responding ~bud ~dev)
|
||||
;< ~ bind:m (init-ship ~dev)
|
||||
;< ~ bind:m (wait-for-output ~bud "hi ~dev successful")
|
||||
(pure:m *vase)
|
22
pkg/arvo/ted/ph/migrate/breach.hoon
Normal file
22
pkg/arvo/ted/ph/migrate/breach.hoon
Normal file
@ -0,0 +1,22 @@
|
||||
/- spider
|
||||
/+ *ph-io
|
||||
=, strand=strand:spider
|
||||
^- thread:spider
|
||||
|= arg=vase
|
||||
=+ !<(who=(list @p) arg)
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
=? who ?=(~ who) ~[~zod ~bus ~web]
|
||||
|-
|
||||
=* loop $
|
||||
?~ who
|
||||
:: ;< ~ bind:m (send-hi ~zod ~bus)
|
||||
:: ;< ~ bind:m (send-hi ~zod ~web)
|
||||
:: ;< ~ bind:m (send-hi ~bus ~zod)
|
||||
:: ;< ~ bind:m (send-hi ~bus ~web)
|
||||
:: ;< ~ bind:m (send-hi ~web ~zod)
|
||||
:: ;< ~ bind:m (send-hi ~web ~bus)
|
||||
(pure:m *vase)
|
||||
;< ~ bind:m (breach-aqua i.who)
|
||||
;< ~ bind:m (init-ship i.who)
|
||||
loop(who t.who)
|
61
pkg/arvo/ted/ph/migrate/commit-home.hoon
Normal file
61
pkg/arvo/ted/ph/migrate/commit-home.hoon
Normal file
@ -0,0 +1,61 @@
|
||||
::
|
||||
:: warning: using this thread will clobber aqua's currently active piers
|
||||
::
|
||||
/- spider, *aquarium
|
||||
/+ *ph-io
|
||||
=, strand=strand:spider
|
||||
=>
|
||||
|%
|
||||
++ commit
|
||||
|= [our=@p now=@da ships=(list @p)]
|
||||
^- (list aqua-event)
|
||||
%+ turn ships
|
||||
|= her=@p
|
||||
:+ %event her
|
||||
=/ paths .^((list path) %ct /(scot %p our)/home/(scot %da now))
|
||||
=/ mod=mode:clay
|
||||
%+ murn paths
|
||||
|= pat=path
|
||||
^- (unit [path (unit mime)])
|
||||
?. =((snag (dec (lent pat)) pat) %hoon)
|
||||
~
|
||||
=/ clay-pax=path (weld /(scot %p our)/home/(scot %da now) pat)
|
||||
=/ file [/text/plain (as-octs:mimes:html .^(@ %cx clay-pax))]
|
||||
`[pat `file]
|
||||
:- //sync/0v1n.2m9vh
|
||||
[%into %home | mod]
|
||||
::
|
||||
++ restore-fleet
|
||||
|= label=term
|
||||
^- (list aqua-event)
|
||||
[%restore-snap label]~
|
||||
::
|
||||
++ snap-fleet
|
||||
|= [label=term ships=(list @p)]
|
||||
^- (list aqua-event)
|
||||
[%snap-ships label ships]~
|
||||
--
|
||||
^- thread:spider
|
||||
|= arg=vase
|
||||
=+ !<(fleets=(list term) arg)
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
=/ ships=(list @p) ~[~zod ~bus ~web]
|
||||
;< =bowl:spider bind:m get-bowl
|
||||
=/ commit-events (commit our.bowl now.bowl ships)
|
||||
|-
|
||||
=* fleet-loop $
|
||||
?~ fleets
|
||||
(pure:m *vase)
|
||||
::
|
||||
;< ~ bind:m (send-events (restore-fleet i.fleets))
|
||||
;< ~ bind:m (sleep ~s0)
|
||||
;< ~ bind:m (send-events commit-events)
|
||||
;< ~ bind:m (sleep ~s0)
|
||||
;< =bowl:spider bind:m get-bowl
|
||||
=/ full-ships
|
||||
.^((list @p) %gx /(scot %p our.bowl)/aqua/(scot %da now.bowl)/ships/noun)
|
||||
;< ~ bind:m (send-events (snap-fleet i.fleets full-ships))
|
||||
;< ~ bind:m (sleep ~s0)
|
||||
::
|
||||
fleet-loop(fleets t.fleets)
|
22
pkg/arvo/ted/ph/migrate/import.hoon
Normal file
22
pkg/arvo/ted/ph/migrate/import.hoon
Normal file
@ -0,0 +1,22 @@
|
||||
/- spider
|
||||
/+ *ph-io
|
||||
=, strand=strand:spider
|
||||
=>
|
||||
|%
|
||||
++ import-all
|
||||
|= [who=@p by-app=(list [@tas *])]
|
||||
=/ m (strand:spider ,~)
|
||||
^- form:m
|
||||
=* loop $
|
||||
?~ by-app (pure:m ~)
|
||||
=/ [app=@tas data=*] i.by-app
|
||||
;< ~ bind:m (poke-app who app %import data)
|
||||
loop(by-app t.by-app)
|
||||
--
|
||||
^- thread:spider
|
||||
|= arg=vase
|
||||
=+ !<([who=@p by-app=(list [@tas *]) ~] arg)
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< ~ bind:m (import-all who by-app)
|
||||
(pure:m *vase)
|
24
pkg/arvo/ted/ph/migrate/init.hoon
Normal file
24
pkg/arvo/ted/ph/migrate/init.hoon
Normal file
@ -0,0 +1,24 @@
|
||||
/- spider
|
||||
/+ *ph-io
|
||||
=, strand=strand:spider
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< ~ bind:m init-azimuth
|
||||
;< ~ bind:m (spawn-aqua ~zod)
|
||||
;< ~ bind:m (spawn-aqua ~bus)
|
||||
;< ~ bind:m (spawn-aqua ~web)
|
||||
::
|
||||
;< ~ bind:m (init-ship ~zod)
|
||||
;< ~ bind:m (init-ship ~bus)
|
||||
;< ~ bind:m (init-ship ~web)
|
||||
::
|
||||
;< ~ bind:m (send-hi ~zod ~web)
|
||||
;< ~ bind:m (send-hi ~zod ~bus)
|
||||
;< ~ bind:m (send-hi ~web ~zod)
|
||||
;< ~ bind:m (send-hi ~bus ~zod)
|
||||
;< ~ bind:m (send-hi ~bus ~web)
|
||||
;< ~ bind:m (send-hi ~web ~bus)
|
||||
::
|
||||
(pure:m *vase)
|
96
pkg/arvo/ted/ph/migrate/make-chats.hoon
Normal file
96
pkg/arvo/ted/ph/migrate/make-chats.hoon
Normal file
@ -0,0 +1,96 @@
|
||||
/- spider,
|
||||
chat-view,
|
||||
*resource,
|
||||
chat-store
|
||||
/+ *ph-io, strandio
|
||||
=, strand=strand:spider
|
||||
=>
|
||||
|%
|
||||
++ chat-message
|
||||
|= [our=@p =path wen=@da mes=cord]
|
||||
=/ act=action:chat-store
|
||||
:* %message path `@uvH`(sham [our path mes])
|
||||
0 our wen [%text mes]
|
||||
==
|
||||
(poke-app our %chat-hook %chat-action act)
|
||||
--
|
||||
::
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< bol=bowl:spider bind:m get-bowl:strandio
|
||||
::
|
||||
:: chat setup
|
||||
:: - ~zod creates a chat associated with group-1
|
||||
:: - ~bus creates a chat associated with group-1
|
||||
:: - ~web creates a dm with ~zod
|
||||
::
|
||||
=/ chat-1=action:chat-view
|
||||
:* %create
|
||||
'Chat 1' ''
|
||||
/~zod/chat-1
|
||||
/ship/~zod/group-1
|
||||
[%invite ~]
|
||||
~
|
||||
%.y
|
||||
%.n
|
||||
==
|
||||
=/ chat-2=action:chat-view
|
||||
:* %create
|
||||
'Chat 2' ''
|
||||
/~bus/chat-2
|
||||
/ship/~zod/group-1
|
||||
[%invite ~]
|
||||
~
|
||||
%.y
|
||||
%.n
|
||||
==
|
||||
=/ web-zod-dm=action:chat-view
|
||||
:* %create
|
||||
'~web <-> ~zod' ''
|
||||
/~web/dm--zod
|
||||
/ship/~web/dm--zod
|
||||
[%invite (sy ~zod ~)]
|
||||
(sy ~zod ~)
|
||||
%.y
|
||||
%.n
|
||||
==
|
||||
=/ join-1 [%join ~zod /~zod/chat-1 %.y]
|
||||
=/ join-2 [%join ~bus /~bus/chat-2 %.y]
|
||||
=/ join-3 [%join ~web /~web/dm--zod %.y]
|
||||
;< ~ bind:m (poke-app ~zod %chat-view %chat-view-action chat-1)
|
||||
;< ~ bind:m (wait-for-output ~zod ">=")
|
||||
;< ~ bind:m (poke-app ~bus %chat-view %chat-view-action chat-2)
|
||||
;< ~ bind:m (wait-for-output ~bus ">=")
|
||||
;< ~ bind:m (poke-app ~web %chat-view %chat-view-action web-zod-dm)
|
||||
;< ~ bind:m (wait-for-output ~web ">=")
|
||||
;< ~ bind:m (sleep ~s20)
|
||||
::
|
||||
;< ~ bind:m (poke-app ~bus %chat-view %chat-view-action join-1)
|
||||
;< ~ bind:m (wait-for-output ~bus ">=")
|
||||
;< ~ bind:m (poke-app ~web %chat-view %chat-view-action join-1)
|
||||
;< ~ bind:m (wait-for-output ~web ">=")
|
||||
::
|
||||
;< ~ bind:m (poke-app ~zod %chat-view %chat-view-action join-2)
|
||||
;< ~ bind:m (wait-for-output ~zod ">=")
|
||||
;< ~ bind:m (poke-app ~web %chat-view %chat-view-action join-2)
|
||||
;< ~ bind:m (wait-for-output ~web ">=")
|
||||
::
|
||||
;< ~ bind:m (poke-app ~zod %chat-view %chat-view-action join-3)
|
||||
;< ~ bind:m (wait-for-output ~zod ">=")
|
||||
;< ~ bind:m (sleep ~s20)
|
||||
::
|
||||
;< ~ bind:m (chat-message ~zod /~zod/chat-1 now.bol 'message 1')
|
||||
;< ~ bind:m (chat-message ~bus /~zod/chat-1 now.bol 'message 2')
|
||||
;< ~ bind:m (chat-message ~web /~bus/chat-2 now.bol 'message 3')
|
||||
;< ~ bind:m (chat-message ~zod /~web/dm--zod now.bol 'message 4')
|
||||
::
|
||||
;< ~ bind:m (send-hi ~zod ~bus)
|
||||
;< ~ bind:m (send-hi ~zod ~web)
|
||||
;< ~ bind:m (send-hi ~bus ~zod)
|
||||
;< ~ bind:m (send-hi ~bus ~web)
|
||||
;< ~ bind:m (send-hi ~web ~zod)
|
||||
;< ~ bind:m (send-hi ~web ~bus)
|
||||
::
|
||||
(pure:m *vase)
|
112
pkg/arvo/ted/ph/migrate/make-graphs.hoon
Normal file
112
pkg/arvo/ted/ph/migrate/make-graphs.hoon
Normal file
@ -0,0 +1,112 @@
|
||||
/- spider,
|
||||
graph-store,
|
||||
graph-view,
|
||||
post,
|
||||
*resource
|
||||
/+ *ph-io, strandio
|
||||
=, strand=strand:spider
|
||||
=>
|
||||
|%
|
||||
::
|
||||
++ graph-post
|
||||
|= [our=@p wen=@da rid=resource body=cord id=@]
|
||||
=/ =index:post [id]~
|
||||
=/ =post:post [our index wen [%text body]~ ~ ~]
|
||||
=/ =node:graph-store [post %empty ~]
|
||||
=/ act=update:graph-store [%0 wen %add-nodes rid (my [index node] ~)]
|
||||
(poke-app our %graph-push-hook %graph-update act)
|
||||
--
|
||||
::
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< bol=bowl:spider bind:m get-bowl:strandio
|
||||
::
|
||||
:: create graphs
|
||||
::
|
||||
=/ group-rid [~zod %group-1]
|
||||
=/ group-path /ship/~zod/group-1
|
||||
=/ create-1=action:graph-view
|
||||
:* %create
|
||||
[~zod %graph-1]
|
||||
'graph 1'
|
||||
'desc 1'
|
||||
~
|
||||
[%group group-rid]
|
||||
'fake'
|
||||
==
|
||||
::
|
||||
=/ create-2=action:graph-view
|
||||
:* %create
|
||||
[~bus %graph-2]
|
||||
'graph 2'
|
||||
'desc 2'
|
||||
~
|
||||
[%group group-rid]
|
||||
'fake'
|
||||
==
|
||||
::
|
||||
=/ create-3=action:graph-view
|
||||
:* %create
|
||||
[~web %graph-3]
|
||||
'graph 3'
|
||||
'desc 3'
|
||||
~
|
||||
[%policy %invite (sy ~zod ~bus ~)]
|
||||
'fake'
|
||||
==
|
||||
::
|
||||
;< ~ bind:m (dojo-thread ~zod %graph-create %graph-view-action create-1)
|
||||
;< ~ bind:m (dojo-thread ~bus %graph-create %graph-view-action create-2)
|
||||
;< ~ bind:m (dojo-thread ~web %graph-create %graph-view-action create-3)
|
||||
;< ~ bind:m (sleep ~s30)
|
||||
::
|
||||
:: join graphs
|
||||
::
|
||||
=/ join-1=action:graph-view
|
||||
[%join [~zod %graph-1] ~zod]
|
||||
=/ join-2=action:graph-view
|
||||
[%join [~bus %graph-2] ~bus]
|
||||
=/ join-3=action:graph-view
|
||||
[%join [~web %graph-3] ~web]
|
||||
::
|
||||
;< ~ bind:m (dojo-thread ~zod %graph-join %graph-view-action join-2)
|
||||
;< ~ bind:m (dojo-thread ~zod %graph-join %graph-view-action join-3)
|
||||
;< ~ bind:m (dojo-thread ~bus %graph-join %graph-view-action join-1)
|
||||
;< ~ bind:m (dojo-thread ~bus %graph-join %graph-view-action join-3)
|
||||
;< ~ bind:m (dojo-thread ~web %graph-join %graph-view-action join-1)
|
||||
;< ~ bind:m (dojo-thread ~web %graph-join %graph-view-action join-2)
|
||||
;< ~ bind:m (sleep ~s30)
|
||||
::
|
||||
:: make posts
|
||||
::
|
||||
;< ~ bind:m (graph-post ~zod now.bol [~zod %graph-1] 'post 1' 1)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~bus now.bol [~zod %graph-1] 'post 2' 2)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~web now.bol [~zod %graph-1] 'post 3' 3)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
::
|
||||
;< ~ bind:m (graph-post ~zod now.bol [~bus %graph-2] 'post 4' 4)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~bus now.bol [~bus %graph-2] 'post 5' 5)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~web now.bol [~bus %graph-2] 'post 6' 6)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
::
|
||||
;< ~ bind:m (graph-post ~zod now.bol [~web %graph-3] 'post 7' 7)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~bus now.bol [~web %graph-3] 'post 8' 8)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~web now.bol [~web %graph-3] 'post 9' 9)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
::
|
||||
;< ~ bind:m (send-hi ~zod ~bus)
|
||||
;< ~ bind:m (send-hi ~zod ~web)
|
||||
;< ~ bind:m (send-hi ~bus ~zod)
|
||||
;< ~ bind:m (send-hi ~bus ~web)
|
||||
;< ~ bind:m (send-hi ~web ~zod)
|
||||
;< ~ bind:m (send-hi ~web ~bus)
|
||||
::
|
||||
(pure:m *vase)
|
46
pkg/arvo/ted/ph/migrate/make-groups.hoon
Normal file
46
pkg/arvo/ted/ph/migrate/make-groups.hoon
Normal file
@ -0,0 +1,46 @@
|
||||
/- spider,
|
||||
contact-view,
|
||||
*resource
|
||||
/+ *ph-io, strandio
|
||||
=, strand=strand:spider
|
||||
::
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< bol=bowl:spider bind:m get-bowl:strandio
|
||||
::
|
||||
:: group setup
|
||||
:: - ~zod creates an open group
|
||||
:: - ~zod creates and invite-only group, and invites ~bus and ~web
|
||||
:: - ~bus and ~web join the first, but not the second group, to keep
|
||||
:: invite-store populated
|
||||
::
|
||||
=/ group-1=contact-view-action:contact-view
|
||||
:* %create
|
||||
%group-1
|
||||
[%open ~ ~]
|
||||
'Group 1'
|
||||
'this is group 1'
|
||||
==
|
||||
=/ group-2=contact-view-action:contact-view
|
||||
:* %create
|
||||
%group-2
|
||||
[%invite (sy ~bus ~web ~)]
|
||||
'Group 2'
|
||||
'this is group 2'
|
||||
==
|
||||
=/ join=contact-view-action:contact-view [%join ~zod %group-1]
|
||||
;< ~ bind:m (poke-app ~zod %contact-view %contact-view-action group-1)
|
||||
;< ~ bind:m (wait-for-output ~zod ">=")
|
||||
;< ~ bind:m (poke-app ~zod %contact-view %contact-view-action group-2)
|
||||
;< ~ bind:m (wait-for-output ~zod ">=")
|
||||
;< ~ bind:m (sleep ~s10)
|
||||
;< ~ bind:m (poke-app ~bus %contact-view %contact-view-action join)
|
||||
;< ~ bind:m (wait-for-output ~bus ">=")
|
||||
;< ~ bind:m (poke-app ~web %contact-view %contact-view-action join)
|
||||
;< ~ bind:m (wait-for-output ~web ">=")
|
||||
;< ~ bind:m (send-hi ~bus ~zod)
|
||||
;< ~ bind:m (send-hi ~web ~zod)
|
||||
;< ~ bind:m (sleep ~s2)
|
||||
(pure:m *vase)
|
36
pkg/arvo/ted/ph/migrate/post-import-chat.hoon
Normal file
36
pkg/arvo/ted/ph/migrate/post-import-chat.hoon
Normal file
@ -0,0 +1,36 @@
|
||||
/- spider,
|
||||
chat-view,
|
||||
*resource,
|
||||
chat-store
|
||||
/+ *ph-io, strandio
|
||||
=, strand=strand:spider
|
||||
=>
|
||||
|%
|
||||
++ chat-message
|
||||
|= [our=@p =path wen=@da mes=cord]
|
||||
=/ act=action:chat-store
|
||||
:* %message path `@uvH`(sham [our path mes])
|
||||
0 our wen [%text mes]
|
||||
==
|
||||
(poke-app our %chat-hook %chat-action act)
|
||||
--
|
||||
::
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< bol=bowl:spider bind:m get-bowl:strandio
|
||||
::
|
||||
;< ~ bind:m (chat-message ~zod /~zod/chat-1 now.bol 'message 5')
|
||||
;< ~ bind:m (chat-message ~bus /~zod/chat-1 now.bol 'message 6')
|
||||
;< ~ bind:m (chat-message ~web /~bus/chat-2 now.bol 'message 7')
|
||||
;< ~ bind:m (chat-message ~zod /~web/dm--zod now.bol 'message 8')
|
||||
::
|
||||
;< ~ bind:m (send-hi ~zod ~bus)
|
||||
;< ~ bind:m (send-hi ~zod ~web)
|
||||
;< ~ bind:m (send-hi ~bus ~zod)
|
||||
;< ~ bind:m (send-hi ~bus ~web)
|
||||
;< ~ bind:m (send-hi ~web ~zod)
|
||||
;< ~ bind:m (send-hi ~web ~bus)
|
||||
::
|
||||
(pure:m *vase)
|
56
pkg/arvo/ted/ph/migrate/post-import-graphs.hoon
Normal file
56
pkg/arvo/ted/ph/migrate/post-import-graphs.hoon
Normal file
@ -0,0 +1,56 @@
|
||||
/- spider,
|
||||
graph-store,
|
||||
graph-view,
|
||||
post,
|
||||
*resource
|
||||
/+ *ph-io, strandio
|
||||
=, strand=strand:spider
|
||||
=>
|
||||
|%
|
||||
::
|
||||
++ graph-post
|
||||
|= [our=@p wen=@da rid=resource body=cord id=@]
|
||||
=/ =index:post [id]~
|
||||
=/ =post:post [our index wen [%text body]~ ~ ~]
|
||||
=/ =node:graph-store [post %empty ~]
|
||||
=/ act=update:graph-store [%0 wen %add-nodes rid (my [index node] ~)]
|
||||
(poke-app our %graph-push-hook %graph-update act)
|
||||
--
|
||||
::
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< bol=bowl:spider bind:m get-bowl:strandio
|
||||
::
|
||||
:: make posts
|
||||
::
|
||||
;< ~ bind:m (graph-post ~zod now.bol [~zod %graph-1] 'post 10' 10)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~bus now.bol [~zod %graph-1] 'post 20' 20)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~web now.bol [~zod %graph-1] 'post 30' 30)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
::
|
||||
;< ~ bind:m (graph-post ~zod now.bol [~bus %graph-2] 'post 40' 40)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~bus now.bol [~bus %graph-2] 'post 50' 50)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~web now.bol [~bus %graph-2] 'post 60' 60)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
::
|
||||
;< ~ bind:m (graph-post ~zod now.bol [~web %graph-3] 'post 70' 70)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~bus now.bol [~web %graph-3] 'post 80' 80)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (graph-post ~web now.bol [~web %graph-3] 'post 90' 90)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
::
|
||||
;< ~ bind:m (send-hi ~zod ~bus)
|
||||
;< ~ bind:m (send-hi ~zod ~web)
|
||||
;< ~ bind:m (send-hi ~bus ~zod)
|
||||
;< ~ bind:m (send-hi ~bus ~web)
|
||||
;< ~ bind:m (send-hi ~web ~zod)
|
||||
;< ~ bind:m (send-hi ~web ~bus)
|
||||
::
|
||||
(pure:m *vase)
|
24
pkg/arvo/ted/ph/migrate/post-import-groups.hoon
Normal file
24
pkg/arvo/ted/ph/migrate/post-import-groups.hoon
Normal file
@ -0,0 +1,24 @@
|
||||
/- spider,
|
||||
contact-view,
|
||||
*resource,
|
||||
group-store
|
||||
/+ *ph-io, strandio
|
||||
=, strand=strand:spider
|
||||
::
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< bol=bowl:spider bind:m get-bowl:strandio
|
||||
::
|
||||
=/ join-2=contact-view-action:contact-view [%join ~zod %group-2]
|
||||
=/ add-members-1=action:group-store
|
||||
[%add-members [~zod %group-1] (sy ~def ~ten ~)]
|
||||
=/ add-members-2=action:group-store
|
||||
[%add-members [~zod %group-2] (sy ~def ~ten ~)]
|
||||
;< ~ bind:m (poke-app ~bus %contact-view %contact-view-action join-2)
|
||||
;< ~ bind:m (poke-app ~web %contact-view %contact-view-action join-2)
|
||||
;< ~ bind:m (poke-app ~zod %group-store %group-action add-members-1)
|
||||
;< ~ bind:m (poke-app ~zod %group-store %group-action add-members-2)
|
||||
::
|
||||
(pure:m *vase)
|
61
pkg/arvo/ted/ph/migrate/post-import-metadata-contacts.hoon
Normal file
61
pkg/arvo/ted/ph/migrate/post-import-metadata-contacts.hoon
Normal file
@ -0,0 +1,61 @@
|
||||
/- spider,
|
||||
contact-view,
|
||||
contact-store,
|
||||
group-store,
|
||||
metadata-store,
|
||||
post,
|
||||
graph-store,
|
||||
*resource
|
||||
/+ *ph-io, strandio
|
||||
=, strand=strand:spider
|
||||
::
|
||||
::
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< bol=bowl:spider bind:m get-bowl:strandio
|
||||
::
|
||||
:: test metadata import
|
||||
::
|
||||
=/ change-group-1=metadata-action:metadata-store
|
||||
:* %add
|
||||
/ship/~zod/group-1
|
||||
[%contacts /ship/~zod/group-1]
|
||||
'New Group 1 Title'
|
||||
'new description'
|
||||
0x0
|
||||
now.bol
|
||||
~zod
|
||||
'fake'
|
||||
==
|
||||
=/ change-web-book=metadata-action:metadata-store
|
||||
:* %add
|
||||
/ship/~web/graph-3
|
||||
[%graph /ship/~web/graph-3]
|
||||
'New Graph 3 Title'
|
||||
'new description'
|
||||
0x0
|
||||
now.bol
|
||||
~web
|
||||
'fake'
|
||||
==
|
||||
;< ~ bind:m (poke-app ~zod %metadata-hook %metadata-action change-group-1)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (poke-app ~web %metadata-hook %metadata-action change-web-book)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
::
|
||||
:: test contacts import
|
||||
::
|
||||
=/ add-zod=contact-action:contact-store
|
||||
:* %add /ship/~zod/group-1 ~zod
|
||||
'ZOD' '' '' '' '' 0x0 ~
|
||||
==
|
||||
=/ add-bus=contact-action:contact-store
|
||||
:* %add /ship/~zod/group-2 ~bus
|
||||
'BUS' '' '' '' '' 0x0 ~
|
||||
==
|
||||
;< ~ bind:m (poke-app ~zod %contact-hook %contact-action add-zod)
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
;< ~ bind:m (poke-app ~bus %contact-hook %contact-action add-bus)
|
||||
(pure:m *vase)
|
18
pkg/arvo/ted/ph/migrate/send-his.hoon
Normal file
18
pkg/arvo/ted/ph/migrate/send-his.hoon
Normal file
@ -0,0 +1,18 @@
|
||||
/- spider
|
||||
/+ *ph-io, strandio
|
||||
=, strand=strand:spider
|
||||
::
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
;< bol=bowl:spider bind:m get-bowl:strandio
|
||||
::
|
||||
;< ~ bind:m (send-hi ~zod ~bus)
|
||||
;< ~ bind:m (send-hi ~zod ~web)
|
||||
;< ~ bind:m (send-hi ~bus ~zod)
|
||||
;< ~ bind:m (send-hi ~bus ~web)
|
||||
;< ~ bind:m (send-hi ~web ~zod)
|
||||
;< ~ bind:m (send-hi ~web ~bus)
|
||||
::
|
||||
(pure:m *vase)
|
73
pkg/arvo/ted/ph/migrate/start.hoon
Normal file
73
pkg/arvo/ted/ph/migrate/start.hoon
Normal file
@ -0,0 +1,73 @@
|
||||
/- spider
|
||||
/+ *ph-io
|
||||
=, strand=strand:spider
|
||||
=>
|
||||
|%
|
||||
++ start-agent
|
||||
|= [=ship agent=term]
|
||||
=/ m (strand:spider ,~)
|
||||
^- form:m
|
||||
=* loop $
|
||||
;< ~ bind:m (dojo ship "|start {<agent>}")
|
||||
;< ~ bind:m ::(wait-for-agent-start ship agent)
|
||||
(wait-for-output ship "activated app home/{(trip agent)}")
|
||||
(pure:m ~)
|
||||
::
|
||||
++ wait-for-agent-start
|
||||
|= [=ship agent=term]
|
||||
=/ m (strand:spider ,~)
|
||||
^- form:m
|
||||
=* loop $
|
||||
;< [her=^ship =unix-effect] bind:m take-unix-effect
|
||||
?: (is-dojo-output:util ship her unix-effect "activated app home/{(trip agent)}")
|
||||
(pure:m ~)
|
||||
loop
|
||||
::
|
||||
++ start-agents
|
||||
|= =ship
|
||||
=/ m (strand:spider ,~)
|
||||
~& %starting-agents
|
||||
^- form:m
|
||||
;< ~ bind:m (start-agent ship %group-store)
|
||||
;< ~ bind:m (start-agent ship %group-pull-hook)
|
||||
;< ~ bind:m (start-agent ship %group-push-hook)
|
||||
::
|
||||
;< ~ bind:m (start-agent ship %metadata-store)
|
||||
;< ~ bind:m (start-agent ship %metadata-hook)
|
||||
::
|
||||
;< ~ bind:m (start-agent ship %invite-store)
|
||||
;< ~ bind:m (start-agent ship %invite-hook)
|
||||
::
|
||||
;< ~ bind:m (start-agent ship %chat-store)
|
||||
;< ~ bind:m (start-agent ship %chat-hook)
|
||||
;< ~ bind:m (start-agent ship %chat-view)
|
||||
::
|
||||
;< ~ bind:m (start-agent ship %contact-store)
|
||||
;< ~ bind:m (start-agent ship %contact-hook)
|
||||
;< ~ bind:m (start-agent ship %contact-view)
|
||||
::
|
||||
;< ~ bind:m (start-agent ship %graph-store)
|
||||
;< ~ bind:m (start-agent ship %graph-push-hook)
|
||||
;< ~ bind:m (start-agent ship %graph-pull-hook)
|
||||
::
|
||||
(pure:m ~)
|
||||
::
|
||||
--
|
||||
^- thread:spider
|
||||
|= arg=vase
|
||||
=+ !<(who=?(~ [@p ~]) arg)
|
||||
=/ m (strand ,vase)
|
||||
;< ~ bind:m start-simple
|
||||
::
|
||||
?~ who
|
||||
;< ~ bind:m (dojo ~zod "|mount %")
|
||||
;< ~ bind:m (dojo ~bus "|mount %")
|
||||
;< ~ bind:m (dojo ~web "|mount %")
|
||||
;< ~ bind:m (start-agents ~zod)
|
||||
;< ~ bind:m (start-agents ~bus)
|
||||
;< ~ bind:m (start-agents ~web)
|
||||
(pure:m *vase)
|
||||
::
|
||||
;< ~ bind:m (dojo -.who "|mount %")
|
||||
;< ~ bind:m (start-agents -.who)
|
||||
(pure:m *vase)
|
13
pkg/arvo/ted/ph/start-drivers.hoon
Normal file
13
pkg/arvo/ted/ph/start-drivers.hoon
Normal file
@ -0,0 +1,13 @@
|
||||
/- spider
|
||||
/+ *ph-io, *ph-util
|
||||
=, strand=strand:spider
|
||||
^- thread:spider
|
||||
|= vase
|
||||
=/ m (strand ,vase)
|
||||
;< =bowl:spider bind:m get-bowl
|
||||
;< ~ bind:m start-simple
|
||||
:: must be a better way to background threads
|
||||
|-
|
||||
=* loop $
|
||||
;< ~ bind:m (sleep ~s5)
|
||||
loop
|
@ -32,10 +32,6 @@ export default class ContactsApi extends BaseApi<StoreState> {
|
||||
});
|
||||
}
|
||||
|
||||
delete(path: Path) {
|
||||
return this.viewAction({ delete: { path } });
|
||||
}
|
||||
|
||||
remove(path: Path, ship: Patp) {
|
||||
return this.viewAction({ remove: { path, ship } });
|
||||
}
|
||||
|
@ -26,6 +26,10 @@ export default class GroupsApi extends BaseApi<StoreState> {
|
||||
return this.proxyAction({ addMembers: { resource, ships } });
|
||||
}
|
||||
|
||||
removeGroup(resource: Resource) {
|
||||
return this.storeAction({ removeGroup: { resource } });
|
||||
}
|
||||
|
||||
changePolicy(resource: Resource, diff: Enc<GroupPolicyDiff>) {
|
||||
return this.proxyAction({ changePolicy: { resource, diff } });
|
||||
}
|
||||
@ -35,6 +39,7 @@ export default class GroupsApi extends BaseApi<StoreState> {
|
||||
}
|
||||
|
||||
private storeAction(action: GroupAction) {
|
||||
return this.action('group-store', 'group-action', action);
|
||||
console.log(action);
|
||||
return this.action('group-store', 'group-update', action);
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ export default class LaunchApi extends BaseApi<StoreState> {
|
||||
return this.launchAction({ 'change-is-shown': { name, isShown }});
|
||||
}
|
||||
|
||||
weather(latlng: any) {
|
||||
return this.action('weather', 'json', latlng);
|
||||
weather(location: string) {
|
||||
return this.action('weather', 'json', location);
|
||||
}
|
||||
|
||||
private launchAction(data) {
|
||||
|
@ -106,13 +106,13 @@ export function getLatestCommentRevision(node: GraphNode): [number, Post] {
|
||||
export function getComments(node: GraphNode): GraphNode {
|
||||
const comments = node.children.get(bigInt(2));
|
||||
if(!comments) {
|
||||
return { post: buntPost(), children: new BigIntOrderedMap() }
|
||||
return { post: buntPost(), children: new BigIntOrderedMap() }
|
||||
}
|
||||
return comments;
|
||||
}
|
||||
|
||||
export function getSnippet(body: string) {
|
||||
const start = body.slice(0, 400);
|
||||
return start === body ? start : `${start}...`;
|
||||
const start = body.slice(0, body.indexOf('\n', 2));
|
||||
return (start === body || start.startsWith("![")) ? start : `${start}...`;
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,6 +14,8 @@ import './css/fonts.css';
|
||||
import light from './themes/light';
|
||||
import dark from './themes/old-dark';
|
||||
|
||||
import { Text, Anchor, Row } from '@tlon/indigo-react';
|
||||
|
||||
import { Content } from './landscape/components/Content';
|
||||
import StatusBar from './components/StatusBar';
|
||||
import Omnibox from './components/leap/Omnibox';
|
||||
@ -25,6 +27,7 @@ import GlobalApi from '~/logic/api/global';
|
||||
import { uxToHex } from '~/logic/lib/util';
|
||||
import { foregroundFromBackground } from '~/logic/lib/sigil';
|
||||
|
||||
|
||||
const Root = styled.div`
|
||||
font-family: ${p => p.theme.fonts.sans};
|
||||
height: 100%;
|
||||
@ -128,6 +131,9 @@ class App extends React.Component {
|
||||
const notificationsCount = state.notificationsCount || 0;
|
||||
const doNotDisturb = state.doNotDisturb || false;
|
||||
|
||||
const showBanner = localStorage.getItem("2020BreachBanner") || "flex";
|
||||
let banner = null;
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<Helmet>
|
||||
@ -136,6 +142,21 @@ class App extends React.Component {
|
||||
: null}
|
||||
</Helmet>
|
||||
<Root background={background}>
|
||||
<Row
|
||||
ref={e => banner = e}
|
||||
display={showBanner}
|
||||
justifyContent="space-between"
|
||||
width='100%'
|
||||
p='2'
|
||||
backgroundColor='yellow'>
|
||||
<Text color='#000000'>
|
||||
A network-wide breach is scheduled for early December 2020. Please visit <Anchor target="_blank" href="https://urbit.org/breach" color='inherit'>urbit.org/breach</Anchor> for more information.
|
||||
</Text>
|
||||
<Text cursor='pointer' fontWeight='500' onClick={() => {
|
||||
banner.style.display = "none";
|
||||
localStorage.setItem("2020BreachBanner", "none");
|
||||
}}>Dismiss</Text>
|
||||
</Row>
|
||||
<Router>
|
||||
<ErrorBoundary>
|
||||
<StatusBarWithRouter
|
||||
|
@ -3,7 +3,7 @@ import moment from "moment";
|
||||
import _ from "lodash";
|
||||
import { Box, Row, Text, Rule } from "@tlon/indigo-react";
|
||||
|
||||
import { OverlaySigil } from './overlay-sigil';
|
||||
import OverlaySigil from '~/views/components/OverlaySigil';
|
||||
import { uxToHex, cite, writeText } from '~/logic/lib/util';
|
||||
import { Envelope, IMessage } from "~/types/chat-update";
|
||||
import { Group, Association, Contacts, LocalUpdateRemoteContentPolicy } from "~/types";
|
||||
@ -191,7 +191,7 @@ export class MessageWithSigil extends PureComponent<MessageProps> {
|
||||
} = this.props;
|
||||
|
||||
const datestamp = moment.unix(msg.when / 1000).format(DATESTAMP_FORMAT);
|
||||
const contact = msg.author in contacts ? contacts[msg.author] : false;
|
||||
const contact = msg.author in contacts ? contacts[msg.author] : undefined;
|
||||
const showNickname = !hideNicknames && contact && contact.nickname;
|
||||
const name = showNickname ? contact.nickname : cite(msg.author);
|
||||
const color = contact ? `#${uxToHex(contact.color)}` : this.isDark ? '#000000' :'#FFFFFF'
|
||||
@ -215,16 +215,16 @@ export class MessageWithSigil extends PureComponent<MessageProps> {
|
||||
contact={contact}
|
||||
color={color}
|
||||
sigilClass={sigilClass}
|
||||
association={association}
|
||||
group={group}
|
||||
hideAvatars={hideAvatars}
|
||||
hideNicknames={hideNicknames}
|
||||
scrollWindow={scrollWindow}
|
||||
history={history}
|
||||
api={api}
|
||||
bg="white"
|
||||
className="fl pr3 v-top pt1"
|
||||
/>
|
||||
<Box flexGrow='1' display='block' className="clamp-message">
|
||||
<Box flexGrow={1} display='block' className="clamp-message">
|
||||
<Box
|
||||
className="hide-child"
|
||||
pt={1}
|
||||
@ -245,7 +245,7 @@ export class MessageWithSigil extends PureComponent<MessageProps> {
|
||||
}}
|
||||
title={`~${msg.author}`}
|
||||
>{name}</Text>
|
||||
<Text flexShrink='0' gray mono className="v-mid">{timestamp}</Text>
|
||||
<Text flexShrink={0} gray mono className="v-mid">{timestamp}</Text>
|
||||
<Text gray mono ml={2} className="v-mid child dn-s">{datestamp}</Text>
|
||||
</Box>
|
||||
<Box fontSize={fontSize ? fontSize : '14px'}><MessageContent content={msg.letter} remoteContentPolicy={remoteContentPolicy} measure={measure} fontSize={fontSize} /></Box>
|
||||
@ -279,6 +279,11 @@ export const MessageContent = ({ content, remoteContentPolicy, measure, fontSize
|
||||
}}}
|
||||
videoProps={{style: {
|
||||
maxWidth: '18rem'
|
||||
}
|
||||
}}
|
||||
textProps={{style: {
|
||||
fontSize: 'inherit',
|
||||
textDecoration: 'underline'
|
||||
}}}
|
||||
/>
|
||||
</Text>
|
||||
|
@ -182,6 +182,7 @@ export default class ChatWindow extends Component<ChatWindowProps, ChatWindowSta
|
||||
if (this.props.unreadCount === 0) return;
|
||||
this.props.api.chat.read(this.props.station);
|
||||
this.props.api.hark.readIndex({ chat: { chat: this.props.station, mention: false }});
|
||||
this.props.api.hark.readIndex({ chat: { chat: this.props.station, mention: true }});
|
||||
}
|
||||
|
||||
fetchMessages(start, end, force = false): Promise<void> {
|
||||
|
@ -1,100 +0,0 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import {
|
||||
ProfileOverlay,
|
||||
OVERLAY_HEIGHT
|
||||
} from './profile-overlay';
|
||||
import { Box, BaseImage } from '@tlon/indigo-react';
|
||||
|
||||
export class OverlaySigil extends PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
clicked: false,
|
||||
captured: false,
|
||||
topSpace: 0,
|
||||
bottomSpace: 0
|
||||
};
|
||||
|
||||
this.containerRef = React.createRef();
|
||||
|
||||
this.profileShow = this.profileShow.bind(this);
|
||||
this.profileHide = this.profileHide.bind(this);
|
||||
this.updateContainerOffset = this.updateContainerOffset.bind(this);
|
||||
this.updateContainerInterval = null;
|
||||
}
|
||||
|
||||
profileShow() {
|
||||
this.updateContainerOffset();
|
||||
this.setState({ profileClicked: true });
|
||||
this.props.scrollWindow.addEventListener('scroll', this.updateContainerOffset);
|
||||
}
|
||||
|
||||
profileHide() {
|
||||
this.setState({ profileClicked: false });
|
||||
this.props.scrollWindow.removeEventListener('scroll', this.updateContainerOffset, true);
|
||||
}
|
||||
|
||||
updateContainerOffset() {
|
||||
if (this.containerRef && this.containerRef.current) {
|
||||
const container = this.containerRef.current;
|
||||
const scrollWindow = this.props.scrollWindow;
|
||||
|
||||
const bottomSpace = scrollWindow.scrollHeight - container.offsetTop - scrollWindow.scrollTop;
|
||||
const topSpace = scrollWindow.offsetHeight - bottomSpace - OVERLAY_HEIGHT;
|
||||
|
||||
this.setState({
|
||||
topSpace,
|
||||
bottomSpace
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.scrollWindow?.removeEventListener('scroll', this.updateContainerOffset, true);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { props, state } = this;
|
||||
const { hideAvatars } = props;
|
||||
|
||||
const img = (props.contact && (props.contact.avatar !== null) && !hideAvatars)
|
||||
? <BaseImage display='inline-block' src={props.contact.avatar} height={16} width={16} />
|
||||
: <Sigil
|
||||
ship={props.ship}
|
||||
size={16}
|
||||
color={props.color}
|
||||
classes={props.sigilClass}
|
||||
icon
|
||||
padded
|
||||
/>;
|
||||
|
||||
return (
|
||||
<Box
|
||||
cursor='pointer'
|
||||
position='relative'
|
||||
onClick={this.profileShow}
|
||||
className={props.className}
|
||||
ref={this.containerRef}
|
||||
>
|
||||
{state.profileClicked && (
|
||||
<ProfileOverlay
|
||||
ship={props.ship}
|
||||
contact={props.contact}
|
||||
color={props.color}
|
||||
topSpace={state.topSpace}
|
||||
bottomSpace={state.bottomSpace}
|
||||
association={props.association}
|
||||
group={props.group}
|
||||
onDismiss={this.profileHide}
|
||||
hideAvatars={hideAvatars}
|
||||
hideNicknames={props.hideNicknames}
|
||||
history={props.history}
|
||||
api={props.api}
|
||||
/>
|
||||
)}
|
||||
{img}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
@ -10,7 +10,10 @@ import Tiles from './components/tiles';
|
||||
import Tile from './components/tiles/tile';
|
||||
import Welcome from './components/welcome';
|
||||
import Groups from './components/Groups';
|
||||
import ModalButton from './components/ModalButton';
|
||||
import { writeText } from '~/logic/lib/util';
|
||||
import { NewGroup } from "~/views/landscape/components/NewGroup";
|
||||
import { JoinGroup } from "~/views/landscape/components/JoinGroup";
|
||||
|
||||
const ScrollbarLessBox = styled(Box)`
|
||||
scrollbar-width: none !important;
|
||||
@ -39,19 +42,18 @@ export default function LaunchApp(props) {
|
||||
pt={0}
|
||||
>
|
||||
<Tile
|
||||
bg="transparent"
|
||||
color="green"
|
||||
bg="white"
|
||||
color="scales.black20"
|
||||
to="/~landscape/home"
|
||||
p={0}
|
||||
>
|
||||
<Box p={2} height='100%' width='100%' bg='green'>
|
||||
<Box p={2} height='100%' width='100%' bg='scales.black20'>
|
||||
<Row alignItems='center'>
|
||||
<Icon
|
||||
color="white"
|
||||
// fill="rgba(0,0,0,0)"
|
||||
icon="Boot"
|
||||
color="black"
|
||||
icon="Mail"
|
||||
/>
|
||||
<Text ml="1" mt='1px' color="white">DMs + Drafts</Text>
|
||||
<Text ml="1" mt='1px' color="black">DMs + Drafts</Text>
|
||||
</Row>
|
||||
</Box>
|
||||
</Tile>
|
||||
@ -62,7 +64,23 @@ export default function LaunchApp(props) {
|
||||
location={props.userLocation}
|
||||
weather={props.weather}
|
||||
/>
|
||||
<Box display={["none", "block"]} width="100%" gridColumn="1 / -1"></Box>
|
||||
<ModalButton
|
||||
icon="Plus"
|
||||
bg="blue"
|
||||
color="#fff"
|
||||
text="Join a Group"
|
||||
style={{ gridColumnStart: 1 }}
|
||||
>
|
||||
<JoinGroup {...props} />
|
||||
</ModalButton>
|
||||
<ModalButton
|
||||
icon="CreateGroup"
|
||||
bg="green"
|
||||
color="#fff"
|
||||
text="Create a Group"
|
||||
>
|
||||
<NewGroup {...props} />
|
||||
</ModalButton>
|
||||
<Groups unreads={props.unreads} groups={props.groups} associations={props.associations} />
|
||||
</Box>
|
||||
</ScrollbarLessBox>
|
||||
|
@ -34,7 +34,7 @@ export default function Groups(props: GroupsProps & Parameters<typeof Box>[0]) {
|
||||
|
||||
return (
|
||||
<>
|
||||
{groups.map((group) => {
|
||||
{groups.map((group, index) => {
|
||||
const path = group?.["group-path"];
|
||||
const unreadCount = (["chat", "graph"] as const)
|
||||
.map(getUnreads(path))
|
||||
@ -42,6 +42,7 @@ export default function Groups(props: GroupsProps & Parameters<typeof Box>[0]) {
|
||||
.reduce(f.add, 0);
|
||||
return (
|
||||
<Group
|
||||
first={index === 0}
|
||||
unreads={unreadCount}
|
||||
path={group?.["group-path"]}
|
||||
title={group.metadata.title}
|
||||
@ -56,11 +57,12 @@ interface GroupProps {
|
||||
path: string;
|
||||
title: string;
|
||||
unreads: number;
|
||||
first: boolean;
|
||||
}
|
||||
function Group(props: GroupProps) {
|
||||
const { path, title, unreads } = props;
|
||||
const { path, title, unreads, first = false } = props;
|
||||
return (
|
||||
<Tile to={`/~landscape${path}`}>
|
||||
<Tile to={`/~landscape${path}`} gridColumnStart={first ? '1' : null}>
|
||||
<Col height="100%" justifyContent="space-between">
|
||||
<Text>{title}</Text>
|
||||
{unreads > 0 &&
|
||||
|
@ -0,0 +1,81 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { Box, Button, Icon, Text } from "@tlon/indigo-react"
|
||||
import { NewGroup } from "~/views/landscape/components/NewGroup";
|
||||
import { JoinGroup } from "~/views/landscape/components/JoinGroup";
|
||||
|
||||
const ModalButton = (props) => {
|
||||
const {
|
||||
childen,
|
||||
icon,
|
||||
text,
|
||||
bg,
|
||||
color,
|
||||
...rest
|
||||
} = props;
|
||||
const [modalShown, setModalShown] = useState(false);
|
||||
|
||||
const handleKeyDown = (event) => {
|
||||
if (event.key === 'Escape') {
|
||||
setModalShown(false);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
};
|
||||
}, [modalShown]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{modalShown && (
|
||||
<Box
|
||||
backgroundColor='scales.black30'
|
||||
left="0px"
|
||||
top="0px"
|
||||
width="100%"
|
||||
height="100%"
|
||||
zIndex={4}
|
||||
position="fixed"
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
onClick={() => setModalShown(false)}
|
||||
>
|
||||
<Box
|
||||
maxWidth="500px"
|
||||
width="100%"
|
||||
bg="white"
|
||||
borderRadius={2}
|
||||
border={[0, 1]}
|
||||
borderColor={["washedGray", "washedGray"]}
|
||||
onClick={e => e.stopPropagation()}
|
||||
display="flex"
|
||||
alignItems="stretch"
|
||||
flexDirection="column"
|
||||
>
|
||||
{props.children}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
<Box
|
||||
onClick={() => setModalShown(true)}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
cursor="pointer"
|
||||
bg={bg}
|
||||
p={2}
|
||||
borderRadius={2}
|
||||
boxShadow="0 0 0px 1px inset"
|
||||
color="scales.black20"
|
||||
{...rest}
|
||||
>
|
||||
<Icon icon={props.icon} mr={2} color={color}></Icon><Text color={color}>{props.text}</Text>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalButton;
|
@ -23,7 +23,7 @@ const routeList = defaultApps.map(a => `/~${a}`);
|
||||
|
||||
export default class Tile extends React.Component {
|
||||
render() {
|
||||
const { bg, to, href, p, boxShadow, ...props } = this.props;
|
||||
const { bg, to, href, p, boxShadow, gridColumnStart, ...props } = this.props;
|
||||
|
||||
let childElement = (
|
||||
<Box p={typeof p === 'undefined' ? 2 : p} width="100%" height="100%">
|
||||
@ -32,7 +32,7 @@ export default class Tile extends React.Component {
|
||||
);
|
||||
|
||||
if (to) {
|
||||
if (routeList.indexOf(to) !== -1 || to === '/~landscape/home' || to === '/~profile' || to.startsWith('/~landscape/ship')) {
|
||||
if (routeList.indexOf(to) !== -1 || to === '/~profile' || to.startsWith('/~landscape/')) {
|
||||
childElement= (<Link to={to}>{childElement}</Link>);
|
||||
} else {
|
||||
childElement= (<a href={to}>{childElement}</a>);
|
||||
@ -48,6 +48,7 @@ export default class Tile extends React.Component {
|
||||
bg={bg || "white"}
|
||||
color={props?.color || 'scales.black20'}
|
||||
boxShadow={boxShadow || '0 0 0px 1px inset'}
|
||||
style={{ gridColumnStart }}
|
||||
>
|
||||
<Box
|
||||
{...props}
|
||||
|
@ -1,14 +1,43 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { Box, Icon, Text, BaseAnchor, BaseInput } from '@tlon/indigo-react';
|
||||
import ErrorBoundary from '~/views/components/ErrorBoundary';
|
||||
|
||||
import Tile from './tile';
|
||||
|
||||
export const weatherStyleMap = {
|
||||
Sunny: 'rgba(67, 169, 255, 0.4)',
|
||||
PartlyCloudy: 'rgba(178, 211, 255, 0.33)',
|
||||
Cloudy: 'rgba(136, 153, 176, 0.43)',
|
||||
VeryCloudy: 'rgba(78, 90, 106, 0.43)',
|
||||
Fog: 'rgba(100, 119, 128, 0.12)',
|
||||
LightShowers: 'rgba(121, 148, 185, 0.33)',
|
||||
LightSleetShowers: 'rgba(114, 130, 153, 0.33)',
|
||||
LightSleet: 'rgba(155, 164, 177, 0.33)',
|
||||
ThunderyShowers: 'rgba(53, 77, 103, 0.33)',
|
||||
LightSnow: 'rgba(179, 182, 200, 0.33)',
|
||||
HeavySnow: 'rgba(179, 182, 200, 0.33)',
|
||||
LightRain: 'rgba(58, 79, 107, 0.33)',
|
||||
HeavyShowers: 'rgba(36, 54, 77, 0.33)',
|
||||
HeavyRain: 'rgba(5, 9, 13, 0.39)',
|
||||
LightSnowShowers: 'rgba(174, 184, 198, 0.33)',
|
||||
HeavySnowShowers: 'rgba(55, 74, 107, 0.33)',
|
||||
ThunderyHeavyRain: 'rgba(45, 56, 66, 0.61)',
|
||||
ThunderySnowShowers: 'rgba(40, 54, 79, 0.46)',
|
||||
default: 'transparent'
|
||||
};
|
||||
|
||||
const imperialCountries = [
|
||||
'United States of America',
|
||||
'Myanmar',
|
||||
'Liberia',
|
||||
];
|
||||
|
||||
export default class WeatherTile extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
latlong: '',
|
||||
location: '',
|
||||
manualEntry: false,
|
||||
error: false
|
||||
};
|
||||
@ -17,89 +46,45 @@ export default class WeatherTile extends React.Component {
|
||||
// geolocation and manual input functions
|
||||
locationSubmit() {
|
||||
navigator.geolocation.getCurrentPosition((res) => {
|
||||
const latlng = `${res.coords.latitude},${res.coords.longitude}`;
|
||||
const location = `${res.coords.latitude},${res.coords.longitude}`;
|
||||
this.setState({
|
||||
latlng
|
||||
location
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
}, { maximumAge: Infinity, timeout: 10000 });
|
||||
this.props.api.launch.weather(latlng);
|
||||
this.props.api.launch.weather(location);
|
||||
this.setState({ manualEntry: !this.state.manualEntry });
|
||||
});
|
||||
}
|
||||
|
||||
manualLocationSubmit() {
|
||||
manualLocationSubmit(event) {
|
||||
event.preventDefault();
|
||||
const gpsInput = document.getElementById('gps');
|
||||
const latlngNoSpace = gpsInput.value.replace(/\s+/g, '');
|
||||
const latlngParse = /-?[0-9]+(?:\.[0-9]*)?,-?[0-9]+(?:\.[0-9]*)?/g;
|
||||
if (latlngParse.test(latlngNoSpace)) {
|
||||
const latlng = latlngNoSpace;
|
||||
this.setState({ latlng }, (err) => {
|
||||
const location = document.getElementById('location').value;
|
||||
this.setState({ location }, (err) => {
|
||||
console.log(err);
|
||||
}, { maximumAge: Infinity, timeout: 10000 });
|
||||
this.props.api.launch.weather(latlng);
|
||||
this.props.api.launch.weather(location);
|
||||
this.setState({ manualEntry: !this.state.manualEntry });
|
||||
} else {
|
||||
this.setState({ error: true });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// set appearance based on weather
|
||||
setColors(data) {
|
||||
let weatherStyle = {
|
||||
bg: '',
|
||||
text: ''
|
||||
};
|
||||
|
||||
switch (data.currently.icon) {
|
||||
case 'clear-day':
|
||||
weatherStyle = { bg: '#E9F5FF', text: '#333' };
|
||||
break;
|
||||
case 'clear-night':
|
||||
weatherStyle = { bg: '#14263C', text: '#fff' };
|
||||
break;
|
||||
case 'rain':
|
||||
weatherStyle = { bg: '#2E1611', text: '#fff' };
|
||||
break;
|
||||
case 'snow':
|
||||
weatherStyle = { bg: '#F9F9FB', text: '#333' };
|
||||
break;
|
||||
case 'sleet':
|
||||
weatherStyle = { bg: '#EFF1F3', text: '#333' };
|
||||
break;
|
||||
case 'wind':
|
||||
weatherStyle = { bg: '#F7FEF6', text: '#333' };
|
||||
break;
|
||||
case 'fog':
|
||||
weatherStyle = { bg: '#504D44', text: '#fff' };
|
||||
break;
|
||||
case 'cloudy':
|
||||
weatherStyle = { bg: '#EEF1F5', text: '#333' };
|
||||
break;
|
||||
case 'partly-cloudy-day':
|
||||
weatherStyle = { bg: '#F3F6FA', text: '#333' };
|
||||
break;
|
||||
case 'partly-cloudy-night':
|
||||
weatherStyle = { bg: '#283442', text: '#fff' };
|
||||
break;
|
||||
default:
|
||||
weatherStyle = { bg: 'white', text: 'black' };
|
||||
}
|
||||
return weatherStyle;
|
||||
// set appearance based on weather
|
||||
colorFromCondition(data) {
|
||||
let weatherDesc = data['current-condition'][0].weatherDesc[0].value;
|
||||
return weatherStyleMap[weatherDesc] || weatherStyleMap.default;
|
||||
}
|
||||
|
||||
// all tile views
|
||||
renderWrapper(child,
|
||||
weatherStyle = { bg: 'white', text: 'black' }
|
||||
) {
|
||||
renderWrapper(child, backgroundColor = 'white') {
|
||||
return (
|
||||
<Tile bg={weatherStyle.bg}>
|
||||
{child}
|
||||
</Tile>
|
||||
<ErrorBoundary>
|
||||
<Tile bg='white' backgroundColor={backgroundColor}>
|
||||
{child}
|
||||
</Tile>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
renderManualEntry() {
|
||||
renderManualEntry(data) {
|
||||
let secureCheck;
|
||||
let error;
|
||||
if (this.state.error === true) {
|
||||
@ -114,6 +99,10 @@ export default class WeatherTile extends React.Component {
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
let locationName;
|
||||
if ('nearest-area' in data) {
|
||||
locationName = data['nearest-area'][0].areaName[0].value;
|
||||
}
|
||||
return this.renderWrapper(
|
||||
<Box
|
||||
display='flex'
|
||||
@ -132,21 +121,13 @@ export default class WeatherTile extends React.Component {
|
||||
</Text>
|
||||
{secureCheck}
|
||||
<Text pb={1} mb='auto'>
|
||||
Please enter your{' '}
|
||||
<BaseAnchor
|
||||
borderBottom='1px solid'
|
||||
color='black'
|
||||
href="https://latitudeandlongitude.org/"
|
||||
target="_blank"
|
||||
>
|
||||
latitude and longitude
|
||||
</BaseAnchor>
|
||||
.
|
||||
Please enter your location.
|
||||
{locationName ? ` Current location is near ${locationName}.` : ''}
|
||||
</Text>
|
||||
{error}
|
||||
<Box mt='auto' display='flex' marginBlockEnd='0'>
|
||||
<BaseInput
|
||||
id="gps"
|
||||
id="location"
|
||||
size="10"
|
||||
width='100%'
|
||||
color='black'
|
||||
@ -154,11 +135,11 @@ export default class WeatherTile extends React.Component {
|
||||
backgroundColor='transparent'
|
||||
border='0'
|
||||
type="text"
|
||||
placeholder="29.55, -95.08"
|
||||
autoFocus
|
||||
placeholder="GPS, ZIP, City"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
this.manualLocationSubmit(e.target.value);
|
||||
this.manualLocationSubmit(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@ -171,7 +152,7 @@ export default class WeatherTile extends React.Component {
|
||||
fontSize='0'
|
||||
border='0'
|
||||
type="submit"
|
||||
onClick={() => this.manualLocationSubmit()}
|
||||
onClick={this.manualLocationSubmit.bind(this)}
|
||||
value="->"
|
||||
/>
|
||||
</Box>
|
||||
@ -182,7 +163,6 @@ export default class WeatherTile extends React.Component {
|
||||
renderNoData() {
|
||||
return this.renderWrapper(
|
||||
<Box
|
||||
bg='white'
|
||||
display='flex'
|
||||
flexDirection='column'
|
||||
justifyContent='space-between'
|
||||
@ -200,14 +180,16 @@ export default class WeatherTile extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderWithData(data, weatherStyle) {
|
||||
const c = data.currently;
|
||||
const d = data.daily.data[0];
|
||||
renderWithData(data) {
|
||||
const locationName = data['nearest-area'][0].areaName[0].value;
|
||||
const c = data['current-condition'][0];
|
||||
const d = data['weather'][0];
|
||||
const bg = this.colorFromCondition(data);
|
||||
|
||||
const sunset = moment.unix(d.sunsetTime);
|
||||
const sunset = moment(d.date + ' ' + d.astronomy[0].sunset, 'YYYY-MM-DD hh:mm A');
|
||||
const sunsetDiff = sunset.diff(moment(), 'hours');
|
||||
|
||||
const sunrise = moment.unix(d.sunriseTime);
|
||||
const sunrise = moment(d.date + ' ' + d.astronomy[0].sunrise, 'YYYY-MM-DD hh:mm A');
|
||||
let sunriseDiff = sunrise.diff(moment(), 'hours');
|
||||
|
||||
if (sunriseDiff > 24) {
|
||||
@ -220,6 +202,10 @@ export default class WeatherTile extends React.Component {
|
||||
? `Sun sets in ${sunsetDiff}h`
|
||||
: `Sun rises in ${sunriseDiff}h`;
|
||||
|
||||
const temp = data['nearest-area'] && imperialCountries.includes(data['nearest-area'][0].country[0].value)
|
||||
? `${Math.round(c.temp_F)}℉`
|
||||
: `${Math.round(c.temp_C)}℃`;
|
||||
|
||||
return this.renderWrapper(
|
||||
<Box
|
||||
width='100%'
|
||||
@ -227,12 +213,12 @@ export default class WeatherTile extends React.Component {
|
||||
display='flex'
|
||||
flexDirection='column'
|
||||
alignItems='space-between'
|
||||
title={`${locationName} Weather`}
|
||||
>
|
||||
<Text color={weatherStyle.text}>
|
||||
<Icon icon='Weather' color={weatherStyle.text} display='inline' style={{ position: 'relative', top: '.3em' }} />
|
||||
<Text>
|
||||
<Icon icon='Weather' display='inline' style={{ position: 'relative', top: '.3em' }} />
|
||||
Weather
|
||||
<Text
|
||||
color={weatherStyle.text}
|
||||
cursor='pointer'
|
||||
onClick={() =>
|
||||
this.setState({ manualEntry: !this.state.manualEntry })
|
||||
@ -248,42 +234,56 @@ export default class WeatherTile extends React.Component {
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
>
|
||||
<Text color={weatherStyle.text}>{c.summary}</Text>
|
||||
<Text color={weatherStyle.text}>{Math.round(c.temperature)}°</Text>
|
||||
<Text color={weatherStyle.text}>{nextSolarEvent}</Text>
|
||||
<Text>{c.weatherDesc[0].value.replace(/([a-z])([A-Z])/g, '$1 $2')}</Text>
|
||||
<Text>{temp}</Text>
|
||||
<Text>{nextSolarEvent}</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
, weatherStyle);
|
||||
</Box>, bg);
|
||||
}
|
||||
|
||||
render() {
|
||||
const data = this.props.weather ? this.props.weather : {};
|
||||
|
||||
if (this.state.manualEntry === true) {
|
||||
return this.renderManualEntry();
|
||||
return this.renderManualEntry(data);
|
||||
}
|
||||
|
||||
if ('currently' in data && 'daily' in data) {
|
||||
const weatherStyle = this.setColors(data);
|
||||
return this.renderWithData(data, weatherStyle);
|
||||
if ('currently' in data) { // Old weather source
|
||||
this.props.api.launch.weather(this.props.location);
|
||||
}
|
||||
|
||||
if ('current-condition' in data && 'weather' in data) {
|
||||
return this.renderWithData(data);
|
||||
}
|
||||
|
||||
if (this.props.location) {
|
||||
return this.renderWrapper((
|
||||
return this.renderWrapper(
|
||||
<Box
|
||||
p='2'
|
||||
width='100%'
|
||||
height='100%'
|
||||
backgroundColor='white'
|
||||
color='black'
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
justifyContent="flex-start"
|
||||
>
|
||||
<Icon icon='Weather' color='black' display='inline' style={{ position: 'relative', top: '.3em' }} />
|
||||
<Text>Weather</Text>
|
||||
<Text pt='2' width='100%' display='flex' flexDirection='column'>
|
||||
Loading, please check again later...
|
||||
<Text><Icon icon='Weather' color='black' display='inline' style={{ position: 'relative', top: '.3em' }} /> Weather</Text>
|
||||
<Text width='100%' display='flex' flexDirection='column' mt={1}>
|
||||
Loading, please check again later...
|
||||
</Text>
|
||||
<Text mt="auto">
|
||||
Set new location{' '}
|
||||
<Text
|
||||
cursor='pointer'
|
||||
onClick={() =>
|
||||
this.setState({ manualEntry: !this.state.manualEntry })
|
||||
}
|
||||
>
|
||||
->
|
||||
</Text>
|
||||
</Text>
|
||||
</Box>
|
||||
));
|
||||
);
|
||||
}
|
||||
return this.renderNoData();
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { Box, Row, Col, Center, LoadingSpinner } from "@tlon/indigo-react";
|
||||
import { Box, Row, Col, Center, LoadingSpinner, Text } from "@tlon/indigo-react";
|
||||
import { Switch, Route, Link } from "react-router-dom";
|
||||
import bigInt from 'big-integer';
|
||||
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import { StoreState } from "~/logic/store/type";
|
||||
import { uxToHex } from '~/logic/lib/util';
|
||||
import { Association, GraphNode } from "~/types";
|
||||
import { RouteComponentProps } from "react-router-dom";
|
||||
|
||||
import { LinkItem } from "./components/link-item";
|
||||
import { LinkItem } from "./components/LinkItem";
|
||||
import { LinkSubmit } from "./components/link-submit";
|
||||
import { LinkPreview } from "./components/link-preview";
|
||||
import { Comments } from "~/views/components/comments";
|
||||
@ -77,16 +76,18 @@ export function LinkResource(props: LinkResourceProps) {
|
||||
const contact = contactDetails[node.post.author];
|
||||
return (
|
||||
<LinkItem
|
||||
contacts={contacts}
|
||||
key={date.toString()}
|
||||
resource={resourcePath}
|
||||
node={node}
|
||||
nickname={contact?.nickname}
|
||||
hideAvatars={hideAvatars}
|
||||
hideNicknames={hideNicknames}
|
||||
remoteContentPolicy={remoteContentPolicy}
|
||||
baseUrl={resourceUrl}
|
||||
color={uxToHex(contact?.color || '0x0')}
|
||||
group={group}
|
||||
path={resource["group-path"]}
|
||||
api={api}
|
||||
mb={3}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@ -95,7 +96,7 @@ export function LinkResource(props: LinkResourceProps) {
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path={relativePath("/:index/:commentId?")}
|
||||
path={relativePath("/:index(\\d+)/:commentId?")}
|
||||
render={(props) => {
|
||||
const index = bigInt(props.match.params.index);
|
||||
const editCommentId = props.match.params.commentId || null;
|
||||
@ -113,15 +114,21 @@ export function LinkResource(props: LinkResourceProps) {
|
||||
const contact = contactDetails[node.post.author];
|
||||
|
||||
return (
|
||||
<Col width="100%" p={3} maxWidth="640px">
|
||||
<Link to={resourceUrl}>{"<- Back"}</Link>
|
||||
<LinkPreview
|
||||
resourcePath={resourcePath}
|
||||
post={node.post}
|
||||
nickname={contact?.nickname}
|
||||
<Col width="100%" p={3} maxWidth="768px">
|
||||
<Link to={resourceUrl}><Text bold>{"<- Back"}</Text></Link>
|
||||
<LinkItem
|
||||
contacts={contacts}
|
||||
key={node.post.index}
|
||||
resource={resourcePath}
|
||||
node={node}
|
||||
hideAvatars={hideAvatars}
|
||||
hideNicknames={hideNicknames}
|
||||
commentNumber={node.children.size}
|
||||
remoteContentPolicy={remoteContentPolicy}
|
||||
baseUrl={resourceUrl}
|
||||
group={group}
|
||||
path={resource["group-path"]}
|
||||
api={api}
|
||||
mt={3}
|
||||
/>
|
||||
<Comments
|
||||
ship={ship}
|
||||
@ -136,6 +143,8 @@ export function LinkResource(props: LinkResourceProps) {
|
||||
editCommentId={editCommentId}
|
||||
history={props.history}
|
||||
baseUrl={`${resourceUrl}/${props.match.params.index}`}
|
||||
association={association}
|
||||
group={group}
|
||||
/>
|
||||
</Col>
|
||||
);
|
||||
|
164
pkg/interface/src/views/apps/links/components/LinkItem.tsx
Normal file
164
pkg/interface/src/views/apps/links/components/LinkItem.tsx
Normal file
@ -0,0 +1,164 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Row, Col, Anchor, Box, Text, BaseImage, Icon, Action } from '@tlon/indigo-react';
|
||||
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import { writeText } from '~/logic/lib/util';
|
||||
import Author from '~/views/components/Author';
|
||||
|
||||
import { roleForShip } from '~/logic/lib/group';
|
||||
import { Contacts, GraphNode, Group, LocalUpdateRemoteContentPolicy, Rolodex } from '~/types';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { Dropdown } from '~/views/components/Dropdown';
|
||||
import RemoteContent from '~/views/components/RemoteContent';
|
||||
|
||||
interface LinkItemProps {
|
||||
node: GraphNode;
|
||||
resource: string;
|
||||
hideAvatars: boolean;
|
||||
hideNicknames: boolean;
|
||||
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
|
||||
api: GlobalApi;
|
||||
group: Group;
|
||||
path: string;
|
||||
contacts: Rolodex[];
|
||||
}
|
||||
|
||||
export const LinkItem = (props: LinkItemProps) => {
|
||||
const {
|
||||
node,
|
||||
resource,
|
||||
hideAvatars,
|
||||
hideNicknames,
|
||||
remoteContentPolicy,
|
||||
api,
|
||||
group,
|
||||
path,
|
||||
contacts,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const URLparser = new RegExp(
|
||||
/((?:([\w\d\.-]+)\:\/\/?){1}(?:(www)\.?){0,1}(((?:[\w\d-]+\.)*)([\w\d-]+\.[\w\d]+))){1}(?:\:(\d+)){0,1}((\/(?:(?:[^\/\s\?]+\/)*))(?:([^\?\/\s#]+?(?:.[^\?\s]+){0,1}){0,1}(?:\?([^\s#]+)){0,1})){0,1}(?:#([^#\s]+)){0,1}/
|
||||
);
|
||||
|
||||
const author = node.post.author;
|
||||
const index = node.post.index.split('/')[1];
|
||||
const size = node.children ? node.children.size : 0;
|
||||
const contents = node.post.contents;
|
||||
const hostname = URLparser.exec(contents[1].url) ? URLparser.exec(contents[1].url)[4] : null;
|
||||
|
||||
const baseUrl = props.baseUrl || `/~404/${resource}`;
|
||||
|
||||
const ourRole = group ? roleForShip(group, window.ship) : undefined;
|
||||
const [ship, name] = resource.split('/');
|
||||
|
||||
const [locationText, setLocationText] = useState('Copy Link Location');
|
||||
|
||||
const copyLocation = () => {
|
||||
setLocationText('Copied');
|
||||
writeText(contents[1].url);
|
||||
setTimeout(() => {
|
||||
setLocationText('Copy Link Location');
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
const deleteLink = () => {
|
||||
if (confirm('Are you sure you want to delete this link?')) {
|
||||
api.graph.removeNodes(`~${ship}`, name, [node.post.index]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box width="100%" {...rest}>
|
||||
|
||||
<Box
|
||||
lineHeight="tall"
|
||||
display='flex'
|
||||
flexDirection='column'
|
||||
width="100%"
|
||||
color='washedGray'
|
||||
border={1}
|
||||
borderRadius={2}
|
||||
alignItems="flex-start"
|
||||
overflow="hidden"
|
||||
>
|
||||
<RemoteContent
|
||||
url={contents[1].url}
|
||||
text={contents[0].text}
|
||||
remoteContentPolicy={remoteContentPolicy}
|
||||
unfold={true}
|
||||
style={{ alignSelf: 'center' }}
|
||||
oembedProps={{
|
||||
p: 2,
|
||||
className: 'links embed-container',
|
||||
}}
|
||||
imageProps={{
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
display: 'block'
|
||||
}}
|
||||
textProps={{
|
||||
overflow: 'hidden',
|
||||
color: 'black',
|
||||
display: 'block',
|
||||
alignSelf: 'center',
|
||||
style: { textOverflow: 'ellipsis', whiteSpace: 'pre', width: '100%' },
|
||||
p: 2
|
||||
}} />
|
||||
<Text color="gray" p={2} flexShrink={0}>
|
||||
<Anchor target="_blank" rel="noopener noreferrer" style={{ textDecoration: 'none' }} href={contents[1].url}>
|
||||
<Box display='flex'>
|
||||
<Icon icon='ArrowExternal' mr={1} />{hostname}
|
||||
</Box>
|
||||
</Anchor>
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Row minWidth='0' flexShrink={0} width="100%" justifyContent="space-between" py={3} bg="white">
|
||||
|
||||
<Author
|
||||
showImage
|
||||
contacts={contacts[path]}
|
||||
ship={author}
|
||||
date={node.post['time-sent']}
|
||||
hideAvatars={hideAvatars}
|
||||
hideNicknames={hideNicknames}
|
||||
remoteContentPolicy={remoteContentPolicy}
|
||||
group={group}
|
||||
api={api}
|
||||
></Author>
|
||||
|
||||
<Box ml="auto" mr={1}>
|
||||
<Link to={`${baseUrl}/${index}`}>
|
||||
<Box display='flex'>
|
||||
<Icon color='blue' icon='Chat' />
|
||||
<Text color='blue' ml={1}>{node.children.size}</Text>
|
||||
</Box>
|
||||
</Link>
|
||||
</Box>
|
||||
|
||||
<Dropdown
|
||||
width="200px"
|
||||
alignX="right"
|
||||
alignY="top"
|
||||
options={
|
||||
<Col backgroundColor="white" border={1} borderRadius={1} borderColor="lightGray">
|
||||
<Row alignItems="center" p={1}>
|
||||
<Action bg="white" m={1} color="black" onClick={copyLocation}>{locationText}</Action>
|
||||
</Row>
|
||||
{(ourRole === 'admin' || node.post.author === window.ship) &&
|
||||
<Row alignItems="center" p={1}>
|
||||
<Action bg="white" m={1} color="red" destructive onClick={deleteLink}>Delete Link</Action>
|
||||
</Row>
|
||||
}
|
||||
</Col>
|
||||
}
|
||||
>
|
||||
<Icon display="block" icon="Ellipsis" color="gray" />
|
||||
</Dropdown>
|
||||
|
||||
</Row>
|
||||
</Box>);
|
||||
};
|
||||
|
@ -1,76 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Row, Col, Anchor, Box, Text, BaseImage } from '@tlon/indigo-react';
|
||||
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
|
||||
import { roleForShip } from '~/logic/lib/group';
|
||||
|
||||
export const LinkItem = (props) => {
|
||||
const {
|
||||
node,
|
||||
nickname,
|
||||
avatar,
|
||||
resource,
|
||||
hideAvatars,
|
||||
hideNicknames,
|
||||
api,
|
||||
group
|
||||
} = props;
|
||||
|
||||
const URLparser = new RegExp(
|
||||
/((?:([\w\d\.-]+)\:\/\/?){1}(?:(www)\.?){0,1}(((?:[\w\d-]+\.)*)([\w\d-]+\.[\w\d]+))){1}(?:\:(\d+)){0,1}((\/(?:(?:[^\/\s\?]+\/)*))(?:([^\?\/\s#]+?(?:.[^\?\s]+){0,1}){0,1}(?:\?([^\s#]+)){0,1})){0,1}(?:#([^#\s]+)){0,1}/
|
||||
);
|
||||
|
||||
const author = node.post.author;
|
||||
const index = node.post.index.split('/')[1];
|
||||
const size = node.children ? node.children.size : 0;
|
||||
const contents = node.post.contents;
|
||||
const hostname = URLparser.exec(contents[1].url) ? URLparser.exec(contents[1].url)[4] : null;
|
||||
|
||||
const showAvatar = avatar && !hideAvatars;
|
||||
const showNickname = nickname && !hideNicknames;
|
||||
|
||||
const img = showAvatar
|
||||
? <BaseImage display='inline-block' src={props.avatar} height={36} width={36} />
|
||||
: <Sigil ship={`~${author}`} size={36} color={'#' + props.color} />;
|
||||
|
||||
const baseUrl = props.baseUrl || `/~404/${resource}`;
|
||||
|
||||
const ourRole = group ? roleForShip(group, window.ship) : undefined;
|
||||
const [ship, name] = resource.split('/');
|
||||
|
||||
return (
|
||||
<Row minWidth='0' flexShrink='0' width="100%" alignItems="center" py={3} bg="white">
|
||||
{img}
|
||||
<Col minWidth='0' height="100%" width='100%' justifyContent="space-between" ml={2}>
|
||||
<Anchor
|
||||
lineHeight="tall"
|
||||
display='flex'
|
||||
style={{ textDecoration: 'none' }}
|
||||
href={contents[1].url}
|
||||
width="100%"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Text display='inline-block' overflow='hidden' style={{ textOverflow: 'ellipsis', whiteSpace: 'pre' }}>{contents[0].text}</Text>
|
||||
<Text ml="2" color="gray" display='inline-block' flexShrink='0'>{hostname} ↗</Text>
|
||||
</Anchor>
|
||||
<Box width="100%">
|
||||
<Text
|
||||
fontFamily={showNickname ? 'sans' : 'mono'} pr={2}
|
||||
>
|
||||
{showNickname ? nickname : cite(author) }
|
||||
</Text>
|
||||
<Link to={`${baseUrl}/${index}`}>
|
||||
<Text color="gray">{size} comments</Text>
|
||||
</Link>
|
||||
{(ourRole === 'admin' || node.post.author === window.ship)
|
||||
&& (<Text color='red' ml='2' cursor='pointer' onClick={() => api.graph.removeNodes(`~${ship}`, name, [node.post.index])}>Delete</Text>)}
|
||||
</Box>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
@ -42,8 +42,12 @@ function describeNotification(description: string, plural: boolean) {
|
||||
return `added ${pluralize("new link", plural)} to`;
|
||||
case "comment":
|
||||
return `left ${pluralize("comment", plural)} on`;
|
||||
case "edit-comment":
|
||||
return `updated ${pluralize("comment", plural)} on`;
|
||||
case "note":
|
||||
return `posted ${pluralize("note", plural)} to`;
|
||||
case "edit-note":
|
||||
return `updated ${pluralize("note", plural)} in`;
|
||||
case "mention":
|
||||
return "mentioned you on";
|
||||
default:
|
||||
|
@ -9,7 +9,7 @@ import { Comments } from "~/views/components/Comments";
|
||||
import { NoteNavigation } from "./NoteNavigation";
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import { getLatestRevision, getComments } from '~/logic/lib/publish';
|
||||
import { Author } from "./Author";
|
||||
import Author from "~/views/components/Author";
|
||||
import { Contacts, GraphNode, Graph, LocalUpdateRemoteContentPolicy } from "~/types";
|
||||
|
||||
interface NoteProps {
|
||||
|
@ -1,26 +1,29 @@
|
||||
import React from "react";
|
||||
import { Col, Box } from "@tlon/indigo-react";
|
||||
import { cite } from "~/logic/lib/util";
|
||||
import { Note } from "~/types/publish-update";
|
||||
import { Contact } from "~/types/contact-update";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import moment from "moment";
|
||||
import { Link } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import { GraphNode } from "~/types/graph-update";
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
import { Col, Row, Box, Text, Icon, Image } from '@tlon/indigo-react';
|
||||
|
||||
import Author from '~/views/components/Author';
|
||||
import { GraphNode } from '~/types/graph-update';
|
||||
import { Contacts, Group } from '~/types';
|
||||
import {
|
||||
getComments,
|
||||
getLatestRevision,
|
||||
getSnippet,
|
||||
} from "~/logic/lib/publish";
|
||||
getSnippet
|
||||
} from '~/logic/lib/publish';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
|
||||
interface NotePreviewProps {
|
||||
host: string;
|
||||
book: string;
|
||||
node: GraphNode;
|
||||
contact?: Contact;
|
||||
hideAvatars?: boolean;
|
||||
hideNicknames?: boolean;
|
||||
baseUrl: string;
|
||||
contacts: Contacts;
|
||||
api: GlobalApi;
|
||||
group: Group;
|
||||
}
|
||||
|
||||
const WrappedBox = styled(Box)`
|
||||
@ -28,29 +31,14 @@ const WrappedBox = styled(Box)`
|
||||
`;
|
||||
|
||||
export function NotePreview(props: NotePreviewProps) {
|
||||
const { node, contact } = props;
|
||||
const { node, contacts, hideAvatars, hideNicknames, group } = props;
|
||||
const { post } = node;
|
||||
if (!post) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let name = post?.author;
|
||||
if (contact && !props.hideNicknames) {
|
||||
name = contact.nickname.length > 0 ? contact.nickname : post?.author;
|
||||
}
|
||||
if (name === post?.author) {
|
||||
name = cite(post?.author);
|
||||
}
|
||||
|
||||
const numComments = getComments(node).children.size;
|
||||
const commentDesc =
|
||||
numComments === 0
|
||||
? "No Comments"
|
||||
: numComments === 1
|
||||
? "1 Comment"
|
||||
: `${numComments} Comments`;
|
||||
const date = moment(post["time-sent"]).fromNow();
|
||||
const url = `${props.baseUrl}/note/${post.index.split("/")[1]}`;
|
||||
const url = `${props.baseUrl}/note/${post.index.split('/')[1]}`;
|
||||
|
||||
// stubbing pending notification-store
|
||||
const isRead = true;
|
||||
@ -60,32 +48,53 @@ export function NotePreview(props: NotePreviewProps) {
|
||||
const snippet = getSnippet(body);
|
||||
|
||||
return (
|
||||
<Link to={url}>
|
||||
<Col mb={4}>
|
||||
<WrappedBox mb={1}>{title}</WrappedBox>
|
||||
<WrappedBox mb={1}>
|
||||
<ReactMarkdown
|
||||
unwrapDisallowed
|
||||
allowedTypes={["text", "root", "break", "paragraph"]}
|
||||
source={snippet}
|
||||
/>
|
||||
</WrappedBox>
|
||||
<Box color="gray" display="flex">
|
||||
<Box
|
||||
mr={3}
|
||||
fontFamily={
|
||||
contact?.nickname && !props.hideNicknames ? "sans" : "mono"
|
||||
}
|
||||
>
|
||||
{name}
|
||||
</Box>
|
||||
<Box color={isRead ? "gray" : "green"} mr={3}>
|
||||
{date}
|
||||
</Box>
|
||||
<Box mr={3}>{commentDesc}</Box>
|
||||
<Box>{rev.valueOf() === 1 ? `1 Revision` : `${rev} Revisions`}</Box>
|
||||
<Box width='100%'>
|
||||
<Link to={url}>
|
||||
<Col
|
||||
lineHeight='tall'
|
||||
width='100%'
|
||||
color={isRead ? 'washedGray' : 'blue'}
|
||||
border={1}
|
||||
borderRadius={2}
|
||||
alignItems='flex-start'
|
||||
overflow='hidden'
|
||||
p='2'
|
||||
>
|
||||
<WrappedBox mb={2}><Text bold fontSize='0'>{title}</Text></WrappedBox>
|
||||
<WrappedBox>
|
||||
<Text fontSize='14px'>
|
||||
<ReactMarkdown
|
||||
unwrapDisallowed
|
||||
allowedTypes={['text', 'root', 'break', 'paragraph', 'image']}
|
||||
renderers={{
|
||||
image: props => <Image src={props.src} maxHeight='300px' style={{ objectFit: 'cover' }} />
|
||||
}}
|
||||
source={snippet}
|
||||
/>
|
||||
</Text>
|
||||
</WrappedBox>
|
||||
</Col>
|
||||
</Link>
|
||||
<Row minWidth='0' flexShrink={0} width="100%" justifyContent="space-between" py={3} bg="white">
|
||||
<Author
|
||||
showImage
|
||||
contacts={contacts}
|
||||
ship={post?.author}
|
||||
date={post?.['time-sent']}
|
||||
hideAvatars={hideAvatars || false}
|
||||
hideNicknames={hideNicknames || false}
|
||||
group={group}
|
||||
api={props.api}
|
||||
/>
|
||||
<Box ml="auto" mr={1}>
|
||||
<Link to={url}>
|
||||
<Box display='flex'>
|
||||
<Icon color='blue' icon='Chat' />
|
||||
<Text color='blue' ml={1}>{numComments}</Text>
|
||||
</Box>
|
||||
</Link>
|
||||
</Box>
|
||||
</Col>
|
||||
</Link>
|
||||
</Row>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import { RouteComponentProps } from "react-router-dom";
|
||||
import Note from "./Note";
|
||||
import { EditPost } from "./EditPost";
|
||||
|
||||
import { GraphNode, Graph, Contacts, LocalUpdateRemoteContentPolicy } from "~/types";
|
||||
import { GraphNode, Graph, Contacts, LocalUpdateRemoteContentPolicy, Group } from "~/types";
|
||||
|
||||
interface NoteRoutesProps {
|
||||
ship: string;
|
||||
@ -24,8 +24,6 @@ interface NoteRoutesProps {
|
||||
}
|
||||
|
||||
export function NoteRoutes(props: NoteRoutesProps & RouteComponentProps) {
|
||||
const { ship, book, noteId } = props;
|
||||
|
||||
const baseUrl = props.baseUrl || '/~404';
|
||||
const rootUrl = props.rootUrl || '/~404';
|
||||
|
||||
|
@ -1,15 +1,11 @@
|
||||
import React, { PureComponent } from "react";
|
||||
import { Link, RouteComponentProps, Route, Switch } from "react-router-dom";
|
||||
import { NotebookPosts } from "./NotebookPosts";
|
||||
import { roleForShip } from "~/logic/lib/group";
|
||||
import { Box, Button, Text, Row, Col } from "@tlon/indigo-react";
|
||||
import { Groups } from "~/types/group-update";
|
||||
import { Contacts, Rolodex } from "~/types/contact-update";
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import styled from "styled-components";
|
||||
import { Associations, Graph, Association } from "~/types";
|
||||
import { deSig } from "~/logic/lib/util";
|
||||
import { StatelessAsyncButton } from "~/views/components/StatelessAsyncButton";
|
||||
import React from 'react';
|
||||
import { Link, RouteComponentProps } from 'react-router-dom';
|
||||
import { NotebookPosts } from './NotebookPosts';
|
||||
import { Box, Button, Text, Row, Col } from '@tlon/indigo-react';
|
||||
import { Groups } from '~/types/group-update';
|
||||
import { Contacts, Rolodex } from '~/types/contact-update';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { Associations, Graph, Association } from '~/types';
|
||||
|
||||
interface NotebookProps {
|
||||
api: GlobalApi;
|
||||
@ -22,9 +18,9 @@ interface NotebookProps {
|
||||
contacts: Rolodex;
|
||||
groups: Groups;
|
||||
hideNicknames: boolean;
|
||||
hideAvatars: boolean;
|
||||
baseUrl: string;
|
||||
rootUrl: string;
|
||||
associations: Associations;
|
||||
}
|
||||
|
||||
interface NotebookState {
|
||||
@ -39,39 +35,42 @@ export function Notebook(props: NotebookProps & RouteComponentProps) {
|
||||
notebookContacts,
|
||||
groups,
|
||||
hideNicknames,
|
||||
hideAvatars,
|
||||
association,
|
||||
graph,
|
||||
graph
|
||||
} = props;
|
||||
const { metadata } = association;
|
||||
|
||||
const group = groups[association?.["group-path"]];
|
||||
if (!group) return null; // Waitin on groups to populate
|
||||
const group = groups[association?.['group-path']];
|
||||
if (!group) {
|
||||
return null; // Waitin on groups to populate
|
||||
}
|
||||
|
||||
const relativePath = (p: string) => props.baseUrl + p;
|
||||
|
||||
const contact = notebookContacts?.[ship];
|
||||
const role = group ? roleForShip(group, window.ship) : undefined;
|
||||
const isOwn = `~${window.ship}` === ship;
|
||||
let isWriter = true;
|
||||
|
||||
const isWriter =
|
||||
isOwn || group.tags?.publish?.[`writers-${book}`]?.has(window.ship);
|
||||
if (group.tags?.publish?.[`writers-${book}`]) {
|
||||
isWriter = isOwn || group.tags?.publish?.[`writers-${book}`]?.has(window.ship);
|
||||
}
|
||||
|
||||
const showNickname = contact?.nickname && !hideNicknames;
|
||||
|
||||
return (
|
||||
<Col gapY="4" pt={4} mx="auto" px={3} maxWidth="500px">
|
||||
<Col gapY="4" pt={4} mx="auto" px={3} maxWidth="768px">
|
||||
<Row justifyContent="space-between">
|
||||
<Box>
|
||||
<Text> {metadata?.title}</Text>
|
||||
<br />
|
||||
<Text display='block'>{metadata?.title}</Text>
|
||||
<Text color="lightGray">by </Text>
|
||||
<Text fontFamily={showNickname ? "sans" : "mono"}>
|
||||
<Text fontFamily={showNickname ? 'sans' : 'mono'}>
|
||||
{showNickname ? contact?.nickname : ship}
|
||||
</Text>
|
||||
</Box>
|
||||
{isWriter && (
|
||||
<Link to={relativePath("/new")}>
|
||||
<Button primary style={{ cursor: "pointer" }}>
|
||||
<Link to={relativePath('/new')}>
|
||||
<Button primary style={{ cursor: 'pointer' }}>
|
||||
New Post
|
||||
</Button>
|
||||
</Link>
|
||||
@ -82,9 +81,12 @@ export function Notebook(props: NotebookProps & RouteComponentProps) {
|
||||
graph={graph}
|
||||
host={ship}
|
||||
book={book}
|
||||
contacts={!!notebookContacts ? notebookContacts : {}}
|
||||
contacts={notebookContacts ? notebookContacts : {}}
|
||||
hideNicknames={hideNicknames}
|
||||
hideAvatars={hideAvatars}
|
||||
baseUrl={props.baseUrl}
|
||||
api={props.api}
|
||||
group={group}
|
||||
/>
|
||||
</Col>
|
||||
);
|
||||
|
@ -1,15 +1,19 @@
|
||||
import React, { Component } from "react";
|
||||
import { Col } from "@tlon/indigo-react";
|
||||
import { NotePreview } from "./NotePreview";
|
||||
import { Contacts, Graph } from "~/types";
|
||||
import React from 'react';
|
||||
import { Col } from '@tlon/indigo-react';
|
||||
import { NotePreview } from './NotePreview';
|
||||
import { Contacts, Graph, Group } from '~/types';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
|
||||
interface NotebookPostsProps {
|
||||
contacts: Contacts;
|
||||
graph: Graph;
|
||||
host: string;
|
||||
book: string;
|
||||
hideNicknames?: boolean;
|
||||
baseUrl: string;
|
||||
hideAvatars?: boolean;
|
||||
hideNicknames?: boolean;
|
||||
api: GlobalApi;
|
||||
group: Group;
|
||||
}
|
||||
|
||||
export function NotebookPosts(props: NotebookPostsProps) {
|
||||
@ -22,10 +26,11 @@ export function NotebookPosts(props: NotebookPostsProps) {
|
||||
key={date.toString()}
|
||||
host={props.host}
|
||||
book={props.book}
|
||||
contact={props.contacts[node.post.author]}
|
||||
contacts={props.contacts}
|
||||
node={node}
|
||||
hideNicknames={props.hideNicknames}
|
||||
baseUrl={props.baseUrl}
|
||||
api={props.api}
|
||||
group={props.group}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { RouteComponentProps, Route, Switch } from "react-router-dom";
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import {
|
||||
import {
|
||||
Association,
|
||||
Associations,
|
||||
Graphs,
|
||||
@ -55,15 +55,18 @@ export function NotebookRoutes(
|
||||
<Route
|
||||
path={baseUrl}
|
||||
exact
|
||||
render={(routeProps) => (
|
||||
<Notebook
|
||||
render={(routeProps) => {
|
||||
if (!graph) {
|
||||
return <Center height="100%"><LoadingSpinner /></Center>;
|
||||
}
|
||||
return <Notebook
|
||||
{...props}
|
||||
graph={graph}
|
||||
contacts={notebookContacts}
|
||||
association={props.association}
|
||||
rootUrl={rootUrl}
|
||||
baseUrl={baseUrl} />
|
||||
)}
|
||||
baseUrl={baseUrl} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path={relativePath("/new")}
|
||||
@ -83,7 +86,7 @@ export function NotebookRoutes(
|
||||
path={relativePath("/note/:noteId")}
|
||||
render={(routeProps) => {
|
||||
const { noteId } = routeProps.match.params;
|
||||
const noteIdNum = bigInt(noteId)
|
||||
const noteIdNum = bigInt(noteId);
|
||||
|
||||
if(!graph) {
|
||||
return <Center height="100%"><LoadingSpinner /></Center>;
|
||||
|
@ -4,6 +4,7 @@ import { ShipSearch } from '~/views/components/ShipSearch';
|
||||
import { Formik, Form, FormikHelpers } from 'formik';
|
||||
import { resourceFromPath } from '~/logic/lib/group';
|
||||
import { AsyncButton } from '~/views/components/AsyncButton';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
|
||||
export class Writers extends Component {
|
||||
render() {
|
||||
@ -27,6 +28,7 @@ export class Writers extends Component {
|
||||
actions.setStatus({ error: e.message });
|
||||
}
|
||||
};
|
||||
const writers = Array.from(groups?.[association?.['group-path']]?.tags.publish?.[`writers-${name}`] || new Set()).map(e => cite(`~${e}`)).join(', ');
|
||||
|
||||
return (
|
||||
<Box maxWidth='512px'>
|
||||
@ -49,6 +51,10 @@ export class Writers extends Component {
|
||||
</AsyncButton>
|
||||
</Form>
|
||||
</Formik>
|
||||
{writers.length > 0 && <>
|
||||
<Text display='block' mt='2'>Current writers:</Text>
|
||||
<Text mt='2' display='block' mono>{writers}</Text>
|
||||
</>}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -187,7 +187,7 @@
|
||||
color:var(--gray);
|
||||
}
|
||||
|
||||
.md p {
|
||||
.md {
|
||||
line-height: 1.5;
|
||||
}
|
||||
.md code, .md pre {
|
||||
@ -201,7 +201,7 @@
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
md img {
|
||||
.md img {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@ import Helmet from 'react-helmet';
|
||||
import { History } from './components/history';
|
||||
import { Input } from './components/input';
|
||||
|
||||
import { Box, Col } from '@tlon/indigo-react';
|
||||
|
||||
import Api from './api';
|
||||
import Store from './store';
|
||||
import Subscription from './subscription';
|
||||
@ -47,30 +49,30 @@ export default class TermApp extends Component {
|
||||
<Helmet>
|
||||
<title>OS1 - Terminal</title>
|
||||
</Helmet>
|
||||
<div
|
||||
style={{ height: '100%' }}
|
||||
<Box
|
||||
height='100%'
|
||||
>
|
||||
<Route
|
||||
exact
|
||||
path="/~term/"
|
||||
render={(props) => {
|
||||
return (
|
||||
<div className="w-100 h-100 flex-m flex-l flex-xl">
|
||||
<div
|
||||
className="db dn-m dn-l dn-xl inter dt w-100"
|
||||
style={{ height: 40 }}
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
'pa3 bg-white bg-gray0-d black white-d mono w-100 f8 relative' +
|
||||
' h-100-m40-s b--gray2 br1 flex-auto flex flex-column ' +
|
||||
'mh4-m mh4-l mh4-xl mb4-m mb4-l mb4-xl ba-m ba-l ba-xl'
|
||||
}
|
||||
style={{
|
||||
lineHeight: '1.4',
|
||||
cursor: 'text'
|
||||
}}
|
||||
<Box
|
||||
width='100%'
|
||||
height='100%'
|
||||
display='flex'
|
||||
>
|
||||
<Col
|
||||
p='3'
|
||||
backgroundColor='white'
|
||||
width='100%'
|
||||
minHeight='0'
|
||||
color='washedGray'
|
||||
borderRadius='2'
|
||||
mx={['0','3']}
|
||||
mb={['0','3']}
|
||||
border={['0','1']}
|
||||
cursor='text'
|
||||
>
|
||||
<History log={this.state.lines.slice(0, -1)} />
|
||||
<Input
|
||||
@ -80,12 +82,12 @@ export default class TermApp extends Component {
|
||||
store={this.store}
|
||||
line={this.state.lines.slice(-1)[0]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Box>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
|
||||
import Line from './line';
|
||||
|
||||
@ -9,16 +10,22 @@ export class History extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
className="h-100 relative flex flex-column-reverse overflow-container flex-auto"
|
||||
<Box
|
||||
height='100%'
|
||||
minHeight='0'
|
||||
display='flex'
|
||||
flexDirection='column-reverse'
|
||||
overflowY='scroll'
|
||||
style={{ resize: 'none' }}
|
||||
>
|
||||
<div style={{ marginTop: 'auto' }}>
|
||||
<Box
|
||||
mt='auto'
|
||||
>
|
||||
{this.props.log.map((line, i) => {
|
||||
return <Line key={i} line={line} />;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Row, Box, BaseInput } from '@tlon/indigo-react';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
|
||||
export class Input extends Component {
|
||||
constructor(props) {
|
||||
@ -85,15 +83,19 @@ export class Input extends Component {
|
||||
}
|
||||
return (
|
||||
<Row flexGrow='1' position='relative'>
|
||||
<Box flexShrink='0' className="w-100">
|
||||
<Box flexShrink='0' width='100%' color='black' fontSize='0'>
|
||||
<BaseInput
|
||||
autoFocus
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
color='black'
|
||||
minHeight='0'
|
||||
display='inline-block'
|
||||
width='100%'
|
||||
spellCheck="false"
|
||||
tabindex="0"
|
||||
wrap="off"
|
||||
className="mono ml1 flex-auto dib w-100"
|
||||
className="mono"
|
||||
id="term"
|
||||
cursor={this.props.cursor}
|
||||
onKeyDown={this.keyPress}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user