mirror of
https://github.com/urbit/shrub.git
synced 2024-11-24 13:06:09 +03:00
Merge branch 'master' into langserver-rpc-rewrite
This commit is contained in:
commit
3c74888c9d
@ -10,7 +10,7 @@ A personal server operating function.
|
||||
|
||||
[azim]: https://etherscan.io/address/0x223c067f8cf28ae173ee5cafea60ca44c335fecb
|
||||
[aens]: https://etherscan.io/address/azimuth.eth
|
||||
[brid]: https://github.com/urbit/bridge/releases
|
||||
[brid]: https://github.com/urbit/bridge
|
||||
[arvo]: https://github.com/urbit/urbit/tree/master/pkg/arvo
|
||||
|
||||
## Install
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:23ec7d497dd53f180b8753bd196f92695c7d60dad52f2b57061fc8642cdae4e2
|
||||
size 9645510
|
||||
oid sha256:e6232e5bcb64be057ccd9b4c23bbd636814d50778e4f3a01fbf2ee0042fe3d44
|
||||
size 9635072
|
||||
|
@ -256,8 +256,8 @@
|
||||
%- zing
|
||||
%+ turn ufs
|
||||
|= uf=unix-effect
|
||||
:~ [%give %fact `/effect %aqua-effect !>(`aqua-effect`[ship uf])]
|
||||
[%give %fact `/effect/[-.q.uf] %aqua-effect !>(`aqua-effect`[ship uf])]
|
||||
:~ [%give %fact ~[/effect] %aqua-effect !>(`aqua-effect`[ship uf])]
|
||||
[%give %fact ~[/effect/[-.q.uf]] %aqua-effect !>(`aqua-effect`[ship uf])]
|
||||
==
|
||||
::
|
||||
=. this
|
||||
@ -265,7 +265,7 @@
|
||||
%- emit-cards
|
||||
%+ turn ~(tap by unix-effects)
|
||||
|= [=ship ufs=(list unix-effect)]
|
||||
[%give %fact `path %aqua-effects !>(`aqua-effects`[ship (flop ufs)])]
|
||||
[%give %fact ~[path] %aqua-effects !>(`aqua-effects`[ship (flop ufs)])]
|
||||
::
|
||||
=. this
|
||||
%- emit-cards
|
||||
@ -275,28 +275,28 @@
|
||||
=/ =path /effect/(scot %p ship)
|
||||
%+ turn ufs
|
||||
|= uf=unix-effect
|
||||
[%give %fact `path %aqua-effect !>(`aqua-effect`[ship uf])]
|
||||
[%give %fact ~[path] %aqua-effect !>(`aqua-effect`[ship uf])]
|
||||
::
|
||||
=. this
|
||||
%- emit-cards
|
||||
%+ turn ~(tap by unix-effects)
|
||||
|= [=ship ufs=(list unix-effect)]
|
||||
=/ =path /effects/(scot %p ship)
|
||||
[%give %fact `path %aqua-effects !>(`aqua-effects`[ship (flop ufs)])]
|
||||
[%give %fact ~[path] %aqua-effects !>(`aqua-effects`[ship (flop ufs)])]
|
||||
::
|
||||
=. this
|
||||
%- emit-cards
|
||||
%+ turn ~(tap by unix-events)
|
||||
|= [=ship ve=(list unix-timed-event)]
|
||||
=/ =path /events/(scot %p ship)
|
||||
[%give %fact `path %aqua-events !>(`aqua-events`[ship (flop ve)])]
|
||||
[%give %fact ~[path] %aqua-events !>(`aqua-events`[ship (flop ve)])]
|
||||
::
|
||||
=. this
|
||||
%- emit-cards
|
||||
%+ turn ~(tap by unix-boths)
|
||||
|= [=ship bo=(list unix-both)]
|
||||
=/ =path /boths/(scot %p ship)
|
||||
[%give %fact `path %aqua-boths !>(`aqua-boths`[ship (flop bo)])]
|
||||
[%give %fact ~[path] %aqua-boths !>(`aqua-boths`[ship (flop bo)])]
|
||||
::
|
||||
[(flop cards) all-state]
|
||||
::
|
||||
|
@ -78,8 +78,8 @@
|
||||
?~ udiffs
|
||||
~
|
||||
=/ =path /(scot %p ship.i.udiffs)
|
||||
:* [%give %fact `/ %azimuth-udiff !>(i.udiffs)]
|
||||
[%give %fact `path %azimuth-udiff !>(i.udiffs)]
|
||||
:* [%give %fact ~[/] %azimuth-udiff !>(i.udiffs)]
|
||||
[%give %fact ~[path] %azimuth-udiff !>(i.udiffs)]
|
||||
$(udiffs t.udiffs)
|
||||
==
|
||||
::
|
||||
|
@ -122,7 +122,7 @@
|
||||
?- -.sign
|
||||
%poke-ack [- all-state]:(on-agent:def wire sign)
|
||||
%watch-ack [- all-state]:(on-agent:def wire sign)
|
||||
%kick [?:(?=([%chat-store ~] wire) ~[connect] ~) all-state]
|
||||
%kick [?:(?=([%chat-store ~] wire) ~[connect:tc] ~) all-state]
|
||||
%fact
|
||||
?+ p.cage.sign ~|([%chat-cli-bad-sub-mark wire p.cage.sign] !!)
|
||||
%chat-update (diff-chat-update:tc wire !<(chat-update q.cage.sign))
|
||||
@ -1044,7 +1044,7 @@
|
||||
|= fec=sole-effect:sole-sur
|
||||
^- card
|
||||
::TODO don't hard-code session id 'drum' here
|
||||
[%give %fact `/sole/drum %sole-effect !>(fec)]
|
||||
[%give %fact ~[/sole/drum] %sole-effect !>(fec)]
|
||||
:: +tab: print tab-complete list
|
||||
::
|
||||
++ tab
|
||||
|
@ -77,7 +77,7 @@
|
||||
?+ -.sign (on-agent:def wire sign)
|
||||
%watch-ack
|
||||
=^ cards state
|
||||
(watch-ack:cc wire p.sign)
|
||||
(watch-ack:cc wire p.sign)
|
||||
[cards this]
|
||||
::
|
||||
%kick
|
||||
@ -186,7 +186,7 @@
|
||||
:~ (pull-wire [%backlog (weld path.act /0)])
|
||||
(pull-wire [%mailbox path.act])
|
||||
(delete-permission [%chat path.act])
|
||||
[%give %kick `[%mailbox path.act] ~]~
|
||||
[%give %kick [%mailbox path.act]~ ~]~
|
||||
==
|
||||
?. |(=(u.ship src.bol) (team:title our.bol src.bol))
|
||||
:: if neither ship = source or source = us, do nothing
|
||||
@ -229,7 +229,7 @@
|
||||
?: ?&(?=(^ backlog-start) (~(got by allow-history) pas))
|
||||
(paginate-messages pas u.box u.backlog-start)
|
||||
~
|
||||
[%give %kick `[%backlog pax] `src.bol]~
|
||||
[%give %kick [%backlog pax]~ `src.bol]~
|
||||
==
|
||||
::
|
||||
++ paginate-messages
|
||||
@ -302,7 +302,7 @@
|
||||
:: if ship is not permitted, kick their subscription
|
||||
=/ mail-path
|
||||
(oust [(dec (lent t.pax)) (lent t.pax)] `(list @t)`t.pax)
|
||||
[%give %kick `[%mailbox mail-path] `ship]~
|
||||
[%give %kick [%mailbox mail-path]~ `ship]~
|
||||
::
|
||||
++ fact-chat-update
|
||||
|= [wir=wire fact=chat-update]
|
||||
@ -327,11 +327,11 @@
|
||||
::
|
||||
%message
|
||||
:_ state
|
||||
[%give %fact `[%mailbox path.fact] %chat-update !>(fact)]~
|
||||
[%give %fact [%mailbox path.fact]~ %chat-update !>(fact)]~
|
||||
::
|
||||
%messages
|
||||
:_ state
|
||||
[%give %fact `[%mailbox path.fact] %chat-update !>(fact)]~
|
||||
[%give %fact [%mailbox path.fact]~ %chat-update !>(fact)]~
|
||||
==
|
||||
::
|
||||
++ handle-foreign
|
||||
|
@ -245,7 +245,7 @@
|
||||
++ update-subscribers
|
||||
|= [pax=path update=chat-update]
|
||||
^- (list card)
|
||||
[%give %fact `pax %chat-update !>(update)]~
|
||||
[%give %fact ~[pax] %chat-update !>(update)]~
|
||||
::
|
||||
++ send-diff
|
||||
|= [pax=path upd=chat-update]
|
||||
|
@ -137,7 +137,7 @@
|
||||
==
|
||||
==
|
||||
::
|
||||
++ on-arvo
|
||||
++ on-arvo
|
||||
|= [=wire =sign-arvo]
|
||||
^- (quip card _this)
|
||||
?. ?=(%bound +<.sign-arvo)
|
||||
@ -176,7 +176,7 @@
|
||||
=/ pax t.t.t.t.site.url
|
||||
=/ envelopes (envelope-scry [(scot %ud start) (scot %ud end) pax])
|
||||
%- json-response:gen
|
||||
%- json-to-octs
|
||||
%- json-to-octs
|
||||
%- update-to-json
|
||||
[%messages pax start end envelopes]
|
||||
::
|
||||
@ -239,8 +239,8 @@
|
||||
^- (list card)
|
||||
=/ updates-json (update-to-json upd)
|
||||
=/ configs-json (configs-to-json configs-scry)
|
||||
:~ [%give %fact `/primary %json !>(updates-json)]
|
||||
[%give %fact `/configs %json !>(configs-json)]
|
||||
:~ [%give %fact ~[/primary] %json !>(updates-json)]
|
||||
[%give %fact ~[/configs] %json !>(configs-json)]
|
||||
==
|
||||
::
|
||||
:: +utilities
|
||||
|
File diff suppressed because one or more lines are too long
@ -12,12 +12,12 @@
|
||||
<link rel="stylesheet" href="/~chat/css/index.css" />
|
||||
<link rel="icon" type="image/png" href="/~launch/img/Favicon.png">
|
||||
<link rel="manifest"
|
||||
href='data:application/manifest+json,{
|
||||
"name": "Chat",
|
||||
"short_name": "Chat",
|
||||
"description": "A%20Chat%20application%20for%20your%20Urbit%20ship.",
|
||||
"display": "standalone",
|
||||
"background_color": "%23FFFFFF",
|
||||
href='data:application/manifest+json,{
|
||||
"name": "Chat",
|
||||
"short_name": "Chat",
|
||||
"description": "A%20Chat%20application%20for%20your%20Urbit%20ship.",
|
||||
"display": "standalone",
|
||||
"background_color": "%23FFFFFF",
|
||||
"theme_color": "%23000000"}' />
|
||||
|
||||
</head>
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -28,7 +28,7 @@
|
||||
++ give-result
|
||||
|= [=the=path =cage]
|
||||
^- card
|
||||
[%give %fact `the-path cage]
|
||||
[%give %fact ~[the-path] cage]
|
||||
--
|
||||
::
|
||||
^- agent:gall
|
||||
|
@ -538,7 +538,7 @@
|
||||
$poke
|
||||
%- he-card(poy ~)
|
||||
:* %pass
|
||||
/poke
|
||||
/poke
|
||||
%agent
|
||||
p.p.mad
|
||||
%poke
|
||||
@ -830,7 +830,7 @@
|
||||
++ he-diff :: emit update
|
||||
|= fec/sole-effect
|
||||
^+ +>
|
||||
(he-card %give %fact `/sole/[id] %sole-effect !>(fec))
|
||||
(he-card %give %fact ~[/sole/[id]] %sole-effect !>(fec))
|
||||
::
|
||||
++ he-stop :: abort work
|
||||
^+ .
|
||||
@ -1141,11 +1141,11 @@
|
||||
:: If couldn't search (eg cursor not in appropriate position), do
|
||||
:: nothing.
|
||||
::
|
||||
?: ?=(~ tl)
|
||||
?: ?=(~ tl)
|
||||
res
|
||||
:: If no options, ring the bell
|
||||
::
|
||||
?: =([~ ~] tl)
|
||||
?: =([~ ~] tl)
|
||||
(he-diff %bel ~)
|
||||
:: If only one option, don't print unless the option is already
|
||||
:: typed in.
|
||||
|
@ -337,7 +337,7 @@
|
||||
:_ dog(history actual-history)
|
||||
%+ turn actual-vows
|
||||
|= =id:block
|
||||
[%give %fact `[%logs path] %eth-watcher-diff !>([%disavow id])]
|
||||
[%give %fact [%logs path]~ %eth-watcher-diff !>([%disavow id])]
|
||||
::
|
||||
++ release-logs
|
||||
|= [=path dog=watchdog]
|
||||
@ -362,7 +362,7 @@
|
||||
%+ turn loglist
|
||||
|= =event-log:rpc:ethereum
|
||||
^- card
|
||||
[%give %fact `[%logs path] %eth-watcher-diff !>([%log event-log])]
|
||||
[%give %fact [%logs path]~ %eth-watcher-diff !>([%log event-log])]
|
||||
=^ cards-2 dog $(numbers t.numbers)
|
||||
[(weld cards-1 cards-2) dog]
|
||||
--
|
||||
|
@ -126,7 +126,7 @@
|
||||
:_ state(synced (~(del by synced.state) path.act))
|
||||
%+ snoc
|
||||
(pull-wire group-wire path.act)
|
||||
[%give %kick `[%group path.act] ~]
|
||||
[%give %kick [%group path.act]~ ~]
|
||||
?: |(=(u.ship src.bol) (team:title our.bol src.bol))
|
||||
:: delete a foreign ship's path
|
||||
=/ group-wire [(scot %p u.ship) %group path.act]
|
||||
@ -150,7 +150,7 @@
|
||||
:_ state(synced (~(del by synced.state) pax.diff))
|
||||
%+ snoc
|
||||
(update-subscribers [%group pax.diff] diff)
|
||||
[%give %kick `[%group pax.diff] ~]
|
||||
[%give %kick [%group pax.diff]~ ~]
|
||||
==
|
||||
::
|
||||
++ handle-foreign
|
||||
@ -212,7 +212,7 @@
|
||||
++ update-subscribers
|
||||
|= [pax=path diff=group-update]
|
||||
^- (list card)
|
||||
[%give %fact `pax %group-update !>(diff)]~
|
||||
[%give %fact ~[pax] %group-update !>(diff)]~
|
||||
::
|
||||
++ pull-wire
|
||||
|= [wir=wire pax=path]
|
||||
|
@ -1,4 +1,4 @@
|
||||
:: group-store: data store for groups of ships
|
||||
:: group-store: data store for groups of ships
|
||||
::
|
||||
/- *group-store
|
||||
/+ default-agent
|
||||
@ -27,7 +27,7 @@
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
group-core +>
|
||||
gc ~(. group-core bowl)
|
||||
gc ~(. group-core bowl)
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
::
|
||||
++ on-init on-init:def
|
||||
@ -75,9 +75,9 @@
|
||||
[%x *] ``noun+!>((~(get by groups) t.path))
|
||||
==
|
||||
::
|
||||
++ on-agent on-agent:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-fail on-fail:def
|
||||
++ on-agent on-agent:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
::
|
||||
|_ bol=bowl:gall
|
||||
@ -148,7 +148,7 @@
|
||||
++ update-subscribers
|
||||
|= [pax=path act=group-action]
|
||||
^- (list card)
|
||||
[%give %fact `pax %group-update !>(act)]~
|
||||
[%give %fact ~[pax] %group-update !>(act)]~
|
||||
::
|
||||
++ send-diff
|
||||
|= [pax=path act=group-action]
|
||||
|
@ -54,7 +54,7 @@
|
||||
?: (team:title our.bowl src.bowl)
|
||||
:: outgoing. we must be inviting another ship. send them the invite.
|
||||
::
|
||||
?> !(team:title our.bowl ship.invite.act)
|
||||
?> !(team:title our.bowl recipient.invite.act)
|
||||
[(invite-hook-poke:do recipient.invite.act act)]~
|
||||
:: else incoming. ensure invitatory exists and invite is not a duplicate.
|
||||
::
|
||||
|
@ -169,7 +169,7 @@
|
||||
++ update-subscribers
|
||||
|= [pax=path upd=invite-update]
|
||||
^- card
|
||||
[%give %fact `pax %invite-update !>(upd)]
|
||||
[%give %fact ~[pax] %invite-update !>(upd)]
|
||||
::
|
||||
++ send-diff
|
||||
|= [pax=path upd=invite-update]
|
||||
|
@ -59,7 +59,7 @@
|
||||
?> ?=(%invite-update p.cage.sign)
|
||||
:~ :*
|
||||
%give %fact
|
||||
`/primary %json
|
||||
~[/primary] %json
|
||||
!>((update-to-json !<(invite-update q.cage.sign)))
|
||||
== ==
|
||||
==
|
||||
|
@ -153,7 +153,7 @@
|
||||
=/ dat=(unit [json url=@t]) (~(get by data) name)
|
||||
?~ dat [~ this]
|
||||
:_ this(data (~(put by data) name [jon url.u.dat]))
|
||||
[%give %fact `/main %json !>((frond:enjs:format name jon))]~
|
||||
[%give %fact ~[/main] %json !>((frond:enjs:format name jon))]~
|
||||
::
|
||||
++ on-arvo
|
||||
|= [wir=wire sin=sign-arvo]
|
||||
|
@ -83,7 +83,7 @@
|
||||
%+ give-simple-payload:app eyre-id.u.job.state
|
||||
[[200 ~] `(as-octt:mimes:html "\"Imported data\"")]
|
||||
::
|
||||
[%export ~]
|
||||
[%export ~]
|
||||
?+ -.sign (on-agent:def wire sign)
|
||||
%watch-ack
|
||||
?~ p.sign
|
||||
@ -94,7 +94,8 @@
|
||||
::
|
||||
%fact
|
||||
=^ cards this (take-export !<(* q.cage.sign))
|
||||
:_ this :_ cards
|
||||
:_ this(job.state ~)
|
||||
:_ cards
|
||||
?> ?=(^ job.state)
|
||||
?> ?=(%export -.source.com.u.job.state)
|
||||
[%pass /export %agent [our.bowl app.source.com.u.job.state] %leave ~]
|
||||
@ -135,7 +136,7 @@
|
||||
=/ enc (en:base64 octs)
|
||||
(pairs:enjs:format file+s+output data+s+enc ~)
|
||||
::
|
||||
:_ this(job.state ~)
|
||||
:_ this
|
||||
%+ give-simple-payload:app eyre-id.u.job.state
|
||||
(json-response:gen (json-to-octs jon))
|
||||
::
|
||||
|
@ -165,14 +165,14 @@
|
||||
++ kick-proxy
|
||||
|= [who=ship =path]
|
||||
^- card
|
||||
[%give %kick `path `who]
|
||||
[%give %kick ~[path] `who]
|
||||
::
|
||||
++ handle-proxy-sign
|
||||
|= [=path =sign:agent:gall]
|
||||
^- (quip card _state)
|
||||
?- -.sign
|
||||
%poke-ack ~|([dap.bowl %unexpected-poke-ack path] !!)
|
||||
%fact [[%give %fact `path cage.sign]~ state]
|
||||
%fact [[%give %fact ~[path] cage.sign]~ state]
|
||||
%kick [[(proxy-pass-link-store path %watch path)]~ state]
|
||||
::
|
||||
%watch-ack
|
||||
|
@ -131,7 +131,7 @@
|
||||
:_ state
|
||||
:_ cards
|
||||
:+ %give %fact
|
||||
:+ `[%local-pages path]
|
||||
:+ [%local-pages path]~
|
||||
%link-update
|
||||
!>([%local-pages path [page]~])
|
||||
:: +hear-submission: record page someone else saved
|
||||
@ -154,7 +154,7 @@
|
||||
:_ state
|
||||
:_ ~
|
||||
:+ %give %fact
|
||||
:+ `[%submissions path]
|
||||
:+ [%submissions path]~
|
||||
%link-update
|
||||
!>([%submissions path [submission]~])
|
||||
::
|
||||
|
@ -140,7 +140,7 @@
|
||||
==
|
||||
:: delete the permission path and its subscriptions from this hook.
|
||||
::
|
||||
:- :- [%give %kick `[%permission path.act] ~]
|
||||
:- :- [%give %kick [%permission path.act]~ ~]
|
||||
(leave-permission path.act)
|
||||
%_ state
|
||||
synced (~(del by synced) path.act)
|
||||
@ -278,7 +278,7 @@
|
||||
^- (list card)
|
||||
%+ turn ~(tap in access-paths)
|
||||
|= access-path=path
|
||||
[%give %kick `[%permission access-path] `check-ship]
|
||||
[%give %kick [%permission access-path]~ `check-ship]
|
||||
::
|
||||
++ permission-scry
|
||||
|= pax=path
|
||||
@ -313,7 +313,7 @@
|
||||
++ update-subscribers
|
||||
|= [=path upd=permission-update]
|
||||
^- card
|
||||
[%give %fact `path %permission-update !>(upd)]
|
||||
[%give %fact ~[path] %permission-update !>(upd)]
|
||||
::
|
||||
++ leave-permission
|
||||
|= =path
|
||||
|
@ -184,7 +184,7 @@
|
||||
++ update-subscribers
|
||||
|= [pax=path upd=permission-update]
|
||||
^- (list card)
|
||||
[%give %fact `pax %permission-update !>(upd)]~
|
||||
[%give %fact ~[pax] %permission-update !>(upd)]~
|
||||
::
|
||||
++ send-diff
|
||||
|= [pax=path upd=permission-update]
|
||||
|
@ -243,7 +243,7 @@
|
||||
++ write-file
|
||||
=, space:userlib
|
||||
|= [pax=path cay=cage]
|
||||
^- card
|
||||
^- card
|
||||
=. pax (weld our-beak pax)
|
||||
[%pass (weld /write-file pax) %arvo %c %info (foal pax cay)]
|
||||
::
|
||||
@ -730,15 +730,15 @@
|
||||
++ affection-primary
|
||||
|= del=delta
|
||||
^- (list card)
|
||||
[%give %fact `/primary %publish-rumor !>(del)]~
|
||||
[%give %fact ~[/primary] %publish-rumor !>(del)]~
|
||||
:: +affection: rumors to interested
|
||||
::
|
||||
++ affection
|
||||
|= del=delta
|
||||
^- (list card)
|
||||
=/ wir=wire /collection/[col.del]
|
||||
:~ [%give %fact `/primary %publish-rumor !>(del)]
|
||||
[%give %fact `wir %publish-rumor !>(del)]
|
||||
:~ [%give %fact ~[/primary] %publish-rumor !>(del)]
|
||||
[%give %fact ~[wir] %publish-rumor !>(del)]
|
||||
==
|
||||
::
|
||||
++ get-post-by-index
|
||||
@ -1263,7 +1263,7 @@
|
||||
=/ upd=update [%invite %.y src.bol coll.act title.act]
|
||||
:_ state
|
||||
%+ welp make-tile-moves
|
||||
[%give %fact `/primary %publish-update !>(upd)]~
|
||||
[%give %fact ~[/primary] %publish-update !>(upd)]~
|
||||
::
|
||||
:: %reject-invite: remove invite from list, acceptance is handled by
|
||||
:: %subscribe action
|
||||
@ -1276,7 +1276,7 @@
|
||||
=/ upd=update [%invite %.n who.act coll.act u.title]
|
||||
:_ state
|
||||
%+ welp make-tile-moves
|
||||
[%give %fact `/primary %publish-update !>(upd)]~
|
||||
[%give %fact ~[/primary] %publish-update !>(upd)]~
|
||||
::
|
||||
:: %serve:
|
||||
::
|
||||
@ -1406,7 +1406,7 @@
|
||||
[%pass wir %agent [who.act %publish] %watch wir]~
|
||||
?~ title ~
|
||||
=/ upd=update [%invite %.n who.act coll.act u.title]
|
||||
[%give %fact `/primary %publish-update !>(upd)]~
|
||||
[%give %fact ~[/primary] %publish-update !>(upd)]~
|
||||
==
|
||||
::
|
||||
:: %unsubscribe: unsub from a foreign blog, delete all state related to it
|
||||
@ -1435,7 +1435,7 @@
|
||||
:- [%pass wir %agent [who.act %publish] %leave ~]
|
||||
%+ welp make-tile-moves
|
||||
=/ rum=rumor [%remove who.act coll.act ~]
|
||||
[%give %fact `/primary %publish-rumor !>(rum)]~
|
||||
[%give %fact ~[/primary] %publish-rumor !>(rum)]~
|
||||
::
|
||||
:: %read: notify that we've seen a post
|
||||
::
|
||||
@ -1445,7 +1445,7 @@
|
||||
%+ welp make-tile-moves
|
||||
::
|
||||
=/ upd=update [%unread %.n (sy [who.act coll.act post.act] ~)]
|
||||
[%give %fact `/primary %publish-update !>(upd)]~
|
||||
[%give %fact ~[/primary] %publish-update !>(upd)]~
|
||||
::
|
||||
==
|
||||
::
|
||||
@ -1597,7 +1597,7 @@
|
||||
::
|
||||
++ make-tile-moves
|
||||
^- (list card)
|
||||
[%give %fact `/publishtile %json !>(make-tile-json)]~
|
||||
[%give %fact ~[/publishtile] %json !>(make-tile-json)]~
|
||||
::
|
||||
++ make-tile-json
|
||||
^- json
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,3 @@
|
||||
:: Thread manager
|
||||
::
|
||||
/- spider
|
||||
/+ libstrand=strand, default-agent, verb
|
||||
=, strand=strand:libstrand
|
||||
@ -127,9 +125,6 @@
|
||||
|- ^- (quip card _this)
|
||||
?~ yarns
|
||||
`this
|
||||
?. ?=([@ ~] i.yarns)
|
||||
$(yarns t.yarns)
|
||||
~| killing=i.yarns
|
||||
=^ cards-1 state
|
||||
(handle-stop-thread:sc (yarn-to-tid i.yarns) |)
|
||||
=^ cards-2 this
|
||||
@ -139,8 +134,6 @@
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
^- (quip card _this)
|
||||
?: ?=(%spider-kill mark)
|
||||
(on-load on-save)
|
||||
=^ cards state
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%spider-input (on-poke-input:sc !<(input vase))
|
||||
@ -357,15 +350,12 @@
|
||||
^- ^card
|
||||
?+ card card
|
||||
[%pass * *] [%pass [%thread tid p.card] q.card]
|
||||
[%give %fact *]
|
||||
?~ path.p.card
|
||||
card
|
||||
card(path.p `[%thread tid u.path.p.card])
|
||||
::
|
||||
[%give %kick *]
|
||||
?~ path.p.card
|
||||
card
|
||||
card(path.p `[%thread tid u.path.p.card])
|
||||
[%give ?(%fact %kick) *]
|
||||
=- card(paths.p -)
|
||||
%+ turn paths.p.card
|
||||
|= =path
|
||||
^- ^path
|
||||
[%thread tid path]
|
||||
==
|
||||
=. cards (weld cards cards.r)
|
||||
=^ final-cards=(list card) state
|
||||
@ -391,13 +381,14 @@
|
||||
++ thread-say-fail
|
||||
|= [=tid =term =tang]
|
||||
^- (list card)
|
||||
:~ [%give %fact `/thread-result/[tid] %thread-fail !>([term tang])]
|
||||
[%give %kick `/thread-result/[tid] ~]
|
||||
:~ [%give %fact ~[/thread-result/[tid]] %thread-fail !>([term tang])]
|
||||
[%give %kick ~[/thread-result/[tid]] ~]
|
||||
==
|
||||
::
|
||||
++ thread-fail
|
||||
|= [=yarn =term =tang]
|
||||
^- (quip card ^state)
|
||||
%- (slog leaf+"strand {<yarn>} failed" leaf+<term> tang)
|
||||
=/ =tid (yarn-to-tid yarn)
|
||||
=/ fail-cards (thread-say-fail tid term tang)
|
||||
=^ cards state (thread-clean yarn)
|
||||
@ -409,8 +400,8 @@
|
||||
:: %- (slog leaf+"strand {<yarn>} finished" (sell vase) ~)
|
||||
=/ =tid (yarn-to-tid yarn)
|
||||
=/ done-cards=(list card)
|
||||
:~ [%give %fact `/thread-result/[tid] %thread-done vase]
|
||||
[%give %kick `/thread-result/[tid] ~]
|
||||
:~ [%give %fact ~[/thread-result/[tid]] %thread-done vase]
|
||||
[%give %kick ~[/thread-result/[tid]] ~]
|
||||
==
|
||||
=^ cards state (thread-clean yarn)
|
||||
[(weld done-cards cards) state]
|
||||
|
@ -101,7 +101,7 @@
|
||||
=/ lismov [%pass /[(scot %da now.bol)] %arvo %i %request req out]~
|
||||
?~ timer
|
||||
:- [[%pass /timer %arvo %b %wait (add now.bol ~h3)] lismov]
|
||||
%= state
|
||||
%= state
|
||||
location str
|
||||
timer `(add now.bol ~h3)
|
||||
==
|
||||
@ -135,7 +135,7 @@
|
||||
currently+(~(got by p.u.ujon) 'currently')
|
||||
daily+(~(got by p.u.ujon) 'daily')
|
||||
==
|
||||
:- [%give %fact `/weathertile %json !>(jon)]~
|
||||
:- [%give %fact ~[/weathertile] %json !>(jon)]~
|
||||
%= state
|
||||
data jon
|
||||
time now.bol
|
||||
|
@ -291,7 +291,7 @@
|
||||
?~ biz (flop moz)
|
||||
:_ (flop moz)
|
||||
=/ =dill-blit:dill ?~(t.biz i.biz [%mor (flop biz)])
|
||||
[%give %fact `/drum %dill-blit !>(dill-blit)]
|
||||
[%give %fact ~[/drum] %dill-blit !>(dill-blit)]
|
||||
::
|
||||
++ se-adit :: update servers
|
||||
^+ .
|
||||
@ -478,7 +478,7 @@
|
||||
::
|
||||
++ se-blit-sys :: output to system
|
||||
|= bil/dill-blit:dill ^+ +>
|
||||
(se-emit %give %fact `/drum %dill-blit !>(bil))
|
||||
(se-emit %give %fact ~[/drum] %dill-blit !>(bil))
|
||||
::
|
||||
++ se-show :: show buffer, raw
|
||||
|= lin/(pair @ud stub)
|
||||
|
@ -312,11 +312,11 @@
|
||||
++ take-agent
|
||||
|= [=wire =sign:agent:gall]
|
||||
?+ wire ~|([%kiln-bad-take-agent wire -.sign] !!)
|
||||
[%kiln %fancy *] ?> ?=(%poke-ack -.sign)
|
||||
[%kiln %fancy *] ?> ?=(%poke-ack -.sign)
|
||||
(take-coup-fancy t.t.wire p.sign)
|
||||
[%kiln %reload *] ?> ?=(%poke-ack -.sign)
|
||||
(take-coup-reload t.t.wire p.sign)
|
||||
[%kiln %spam *] ?> ?=(%poke-ack -.sign)
|
||||
[%kiln %spam *] ?> ?=(%poke-ack -.sign)
|
||||
(take-coup-spam t.t.wire p.sign)
|
||||
==
|
||||
::
|
||||
|
@ -117,7 +117,7 @@
|
||||
:- "%_"
|
||||
"""
|
||||
$\{1:target}
|
||||
$\{2:wing} $\{3:new-value}
|
||||
$\{2:wing} $\{3:new-value}
|
||||
==
|
||||
"""
|
||||
:- "%."
|
||||
@ -139,7 +139,7 @@
|
||||
:- "%*"
|
||||
"""
|
||||
$\{1:target-wing} $\{2:from}
|
||||
$\{3:wing} $\{4:new-value}
|
||||
$\{3:wing} $\{4:new-value}
|
||||
==
|
||||
"""
|
||||
:- "%^"
|
||||
@ -164,7 +164,7 @@
|
||||
:- "%="
|
||||
"""
|
||||
$\{1:target}
|
||||
$\{2:wing} $\{3:new-value}
|
||||
$\{2:wing} $\{3:new-value}
|
||||
==
|
||||
"""
|
||||
::
|
||||
@ -422,7 +422,7 @@
|
||||
:- "?-"
|
||||
"""
|
||||
$\{1:case}
|
||||
$\{2:type} $\{3:value}
|
||||
$\{2:type} $\{3:value}
|
||||
==
|
||||
"""
|
||||
:- "?:"
|
||||
@ -455,8 +455,8 @@
|
||||
"""
|
||||
:- "?+"
|
||||
"""
|
||||
$\{1:case} $\{2:else}
|
||||
$\{3:type} $\{4:value}
|
||||
$\{1:case} $\{2:else}
|
||||
$\{3:type} $\{4:value}
|
||||
==
|
||||
"""
|
||||
:- "?&"
|
||||
|
@ -49,9 +49,9 @@
|
||||
[%http-response-header !>(response-header.simple-payload)]
|
||||
=/ data-cage
|
||||
[%http-response-data !>(data.simple-payload)]
|
||||
:~ [%give %fact `/http-response/[eyre-id] header-cage]
|
||||
[%give %fact `/http-response/[eyre-id] data-cage]
|
||||
[%give %kick `/http-response/[eyre-id] ~]
|
||||
:~ [%give %fact ~[/http-response/[eyre-id]] header-cage]
|
||||
[%give %fact ~[/http-response/[eyre-id]] data-cage]
|
||||
[%give %kick ~[/http-response/[eyre-id]] ~]
|
||||
==
|
||||
--
|
||||
++ gen
|
||||
|
@ -83,7 +83,7 @@
|
||||
++ wush
|
||||
|= [wid=@u tan=tang]
|
||||
^- tape
|
||||
%- of-wall:format
|
||||
%- of-wall:format
|
||||
%+ turn (flop tan)
|
||||
|= =tank
|
||||
~! wid
|
||||
|
@ -4,7 +4,7 @@
|
||||
++ grab
|
||||
|%
|
||||
++ noun chat-action
|
||||
++ json
|
||||
++ json
|
||||
|= jon=^json
|
||||
(json-to-action jon)
|
||||
--
|
||||
|
@ -19,7 +19,7 @@
|
||||
++ add-owned
|
||||
%- ot
|
||||
:~ [%path pa]
|
||||
[%security sec]
|
||||
[%security sec]
|
||||
[%allow-history bo]
|
||||
==
|
||||
::
|
||||
|
@ -4,7 +4,7 @@
|
||||
++ grab
|
||||
|%
|
||||
++ noun chat-view-action
|
||||
++ json
|
||||
++ json
|
||||
|= jon=^json
|
||||
(json-to-view-action jon)
|
||||
--
|
||||
|
@ -4,7 +4,7 @@
|
||||
++ grab
|
||||
|%
|
||||
++ noun invite-action
|
||||
++ json
|
||||
++ json
|
||||
|= jon=^json
|
||||
(json-to-action jon)
|
||||
--
|
||||
|
@ -4,7 +4,7 @@
|
||||
++ grab
|
||||
|%
|
||||
++ noun permission-action
|
||||
++ json
|
||||
++ json
|
||||
|= jon=^json
|
||||
=< (parse-permission-action jon)
|
||||
|%
|
||||
|
@ -4,7 +4,7 @@
|
||||
++ grab
|
||||
|%
|
||||
++ noun permission-group-hook-action
|
||||
++ json
|
||||
++ json
|
||||
|= jon=^json
|
||||
(json-to-perm-group-hook-action jon)
|
||||
--
|
||||
|
@ -43,10 +43,10 @@
|
||||
:* %+ rash creator.txs
|
||||
;~(pfix (jest 'creator: ~') fed:ag)
|
||||
::
|
||||
%+ rash collection.txs
|
||||
%+ rash collection.txs
|
||||
;~(pfix (jest 'collection: ') (cook crip (star next)))
|
||||
::
|
||||
%+ rash post.txs
|
||||
%+ rash post.txs
|
||||
;~(pfix (jest 'post: ') (cook crip (star next)))
|
||||
::
|
||||
%+ rash date-created.txs
|
||||
|
@ -46,10 +46,10 @@
|
||||
:* %+ rash owner.txs
|
||||
;~(pfix (jest 'owner: ~') fed:ag)
|
||||
::
|
||||
%+ rash title.txs
|
||||
%+ rash title.txs
|
||||
;~(pfix (jest 'title: ') (cook crip (star next)))
|
||||
::
|
||||
%+ rash filename.txs
|
||||
%+ rash filename.txs
|
||||
;~(pfix (jest 'filename: ') (cook crip (star next)))
|
||||
::
|
||||
%+ rash comments.txs
|
||||
|
@ -13,14 +13,14 @@
|
||||
%+ frond -.rum
|
||||
?- -.rum
|
||||
%collection
|
||||
%- pairs
|
||||
%- pairs
|
||||
:~ [%coll s+col.rum]
|
||||
[%who (ship who.rum)]
|
||||
[%data (collection-build-to-json dat.rum)]
|
||||
==
|
||||
::
|
||||
%post
|
||||
%- pairs
|
||||
%- pairs
|
||||
:~ [%coll s+col.rum]
|
||||
[%post s+pos.rum]
|
||||
[%who (ship who.rum)]
|
||||
@ -28,7 +28,7 @@
|
||||
==
|
||||
::
|
||||
%comments
|
||||
%- pairs
|
||||
%- pairs
|
||||
:~ [%coll s+col.rum]
|
||||
[%post s+pos.rum]
|
||||
[%who (ship who.rum)]
|
||||
|
@ -2,7 +2,7 @@
|
||||
/+ publish
|
||||
/= result
|
||||
/^ (list comment:publish)
|
||||
/;
|
||||
/;
|
||||
|= comments=(map knot comment:publish)
|
||||
^- (list [comment-info:publish @t])
|
||||
%+ sort ~(val by comments)
|
||||
|
@ -3,7 +3,7 @@
|
||||
/= args /$ ,[beam *]
|
||||
/= result
|
||||
/^ [post-info:publish manx @t]
|
||||
/;
|
||||
/;
|
||||
|= $: post-front=(map knot cord)
|
||||
post-content=manx
|
||||
post-raw=wain
|
||||
|
@ -5,7 +5,7 @@
|
||||
:: if ship is foreign, delete any local
|
||||
:: group at that path and mirror the
|
||||
:: foreign group at our local path
|
||||
::
|
||||
::
|
||||
[%remove =path] :: remove the path.
|
||||
==
|
||||
--
|
||||
|
@ -1,55 +1,89 @@
|
||||
:: Ames extends Arvo's %pass/%give move semantics across the network.
|
||||
::
|
||||
:: A "forward flow" message, which is like a request, is passed to
|
||||
:: Ames from a local vane. Ames transmits the message to the peer's
|
||||
:: Ames, which passes the message to the destination vane.
|
||||
:: Ames receives packets as Arvo events and emits packets as Arvo
|
||||
:: effects. The runtime is responsible for transferring the bytes in
|
||||
:: an Ames packet across a physical network to another ship.
|
||||
::
|
||||
:: Once the peer has processed the "forward flow" message, it sends a
|
||||
:: message acknowledgment over the wire back to the local Ames. This
|
||||
:: ack can either be positive or negative, in which case we call it a
|
||||
:: "nack". (Don't confuse Ames nacks with TCP nacks, which are a
|
||||
:: different concept).
|
||||
:: The runtime tells Ames which physical address a packet came from,
|
||||
:: represented as an opaque atom. Ames can emit a packet effect to
|
||||
:: one of those opaque atoms or to the Urbit address of a galaxy
|
||||
:: (root node), which the runtime is responsible for translating to a
|
||||
:: physical address. One runtime implementation sends UDP packets
|
||||
:: using IPv4 addresses for ships and DNS lookups for galaxies, but
|
||||
:: other implementations may overlay over other kinds of networks.
|
||||
::
|
||||
:: When the local Ames receives either a positive message ack or a
|
||||
:: combination of a nack and nack-trace (explained in more detail
|
||||
:: A local vane can pass Ames a %plea request message. Ames
|
||||
:: transmits the message over the wire to the peer ship's Ames, which
|
||||
:: passes the message to the destination vane.
|
||||
::
|
||||
:: Once the peer has processed the %plea message, it sends a
|
||||
:: message-acknowledgment packet over the wire back to the local
|
||||
:: Ames. This ack can either be positive to indicate the request was
|
||||
:: processed, or negative to indicate the request failed, in which
|
||||
:: case it's called a "nack". (Don't confuse Ames nacks with TCP
|
||||
:: nacks, which are a different concept).
|
||||
::
|
||||
:: When the local Ames receives either a positive message-ack or a
|
||||
:: combination of a nack and naxplanation (explained in more detail
|
||||
:: below), it gives an %done move to the local vane that had
|
||||
:: requested the original "forward flow" message be sent.
|
||||
:: requested the original %plea message be sent.
|
||||
::
|
||||
:: A "backward flow" message, which is similar to a response or a
|
||||
:: subscription update, is given to Ames from a local vane. Ames
|
||||
:: transmits the message to the peer's Ames, which gives the message
|
||||
:: to the destination vane.
|
||||
:: A local vane can give Ames zero or more %boon response messages in
|
||||
:: response to a %plea, on the same duct that Ames used to pass the
|
||||
:: %plea to the vane. Ames transmits a %boon over the wire to the
|
||||
:: peer's Ames, which gives it to the destination vane on the same
|
||||
:: duct the vane had used to pass the original %plea to Ames.
|
||||
::
|
||||
:: Ames will give a %memo to a vane upon hearing the message from a
|
||||
:: remote. This message is a "backward flow" message, forming one of
|
||||
:: potentially many responses to a "forward flow" message that a
|
||||
:: local vane had passed to our local Ames, and which local Ames had
|
||||
:: relayed to the remote. Ames gives the %memo on the same duct the
|
||||
:: local vane had originally used to pass Ames the "forward flow"
|
||||
:: message.
|
||||
:: %boon messages are acked automatically by the receiver Ames. They
|
||||
:: cannot be nacked, and Ames only uses the ack internally, without
|
||||
:: notifying the client vane that gave Ames the %boon.
|
||||
::
|
||||
:: Backward flow messages are acked automatically by the receiver.
|
||||
:: They cannot be nacked, and Ames only uses the ack internally,
|
||||
:: without notifying the client vane.
|
||||
:: If the Arvo event that completed receipt of a %boon message
|
||||
:: crashes, Ames instead sends the client vane a %lost message
|
||||
:: indicating the %boon was missed.
|
||||
::
|
||||
:: Forward flow messages can be nacked, in which case the peer will
|
||||
:: send both a message-nack packet and a nack-trace message, which is
|
||||
:: sent on a special diagnostic flow so as not to interfere with
|
||||
:: normal operation. The nack-trace is sent as a full Ames message,
|
||||
:: instead of just a packet, because the contained error information
|
||||
:: can be arbitrarily large.
|
||||
:: %plea messages can be nacked, in which case the peer will send
|
||||
:: both a message-nack packet and a naxplanation message, which is
|
||||
:: sent in a way that does not interfere with normal operation. The
|
||||
:: naxplanation is sent as a full Ames message, instead of just a
|
||||
:: packet, because the contained error information can be arbitrarily
|
||||
:: large. A naxplanation can only give rise to a positive ack --
|
||||
:: never ack an ack, and never nack a naxplanation.
|
||||
::
|
||||
:: Once the local Ames has received the nack-trace, it knows the peer
|
||||
:: has received the full message and failed to process it. This
|
||||
:: means if we later hear an ack packet on the failed message, we can
|
||||
:: ignore it.
|
||||
:: Ames guarantees a total ordering of messages within a "flow",
|
||||
:: identified in other vanes by a duct and over the wire by a "bone":
|
||||
:: an opaque number. Each flow has a FIFO queue of %plea requests
|
||||
:: from the requesting ship to the responding ship and a FIFO queue
|
||||
:: of %boon's in the other direction.
|
||||
::
|
||||
:: Also, due to Ames's exactly-once delivery semantics, we know that
|
||||
:: when we receive a nack-trace for message n, we know the peer has
|
||||
:: positively acked all messages m+1 through n-1, where m is the last
|
||||
:: message for which we heard a nack-trace. If we haven't heard acks
|
||||
:: on all those messages, we apply positive acks when we hear the
|
||||
:: nack-trace.
|
||||
:: Message order across flows is not specified and may vary based on
|
||||
:: network conditions.
|
||||
::
|
||||
:: Ames guarantees that a message will only be delivered once to the
|
||||
:: destination vane.
|
||||
::
|
||||
:: Ames encrypts every message using symmetric-key encryption by
|
||||
:: performing an elliptic curve Diffie-Hellman using our private key
|
||||
:: and the public key of the peer. For ships in the Jael PKI
|
||||
:: (public-key infrastructure), Ames looks up the peer's public key
|
||||
:: from Jael. Comets (128-bit ephemeral addresses) are not
|
||||
:: cryptographic assets and must self-attest over Ames by sending a
|
||||
:: single self-signed packet containing their public key.
|
||||
::
|
||||
:: When a peer suffers a continuity breach, Ames removes all
|
||||
:: messaging state related to it. Ames does not guarantee that all
|
||||
:: messages will be fully delivered to the now-stale peer. From
|
||||
:: Ames's perspective, the newly restarted peer is a new ship.
|
||||
:: Ames's guarantees are not maintained across a breach.
|
||||
::
|
||||
:: A vane can pass Ames a %heed $task to request Ames track a peer's
|
||||
:: responsiveness. If our %boon's to it start backing up locally,
|
||||
:: Ames will give a %clog back to the requesting vane containing the
|
||||
:: unresponsive peer's urbit address. This interaction does not use
|
||||
:: ducts as unique keys. Stop tracking a peer by sending Ames a
|
||||
:: %jilt $task.
|
||||
::
|
||||
:: Debug output can be adjusted using %sift and %spew $task's.
|
||||
::
|
||||
:: protocol-version: current version of the ames wire protocol
|
||||
::
|
||||
@ -530,7 +564,15 @@
|
||||
:: The first bone is 0. They increment by 4, since each flow includes
|
||||
:: a bit for each message determining forward vs. backward and a
|
||||
:: second bit for whether the message is on the normal flow or the
|
||||
:: associated diagnostic flow (for nack-traces).
|
||||
:: associated diagnostic flow (for naxplanations).
|
||||
::
|
||||
:: The least significant bit of a $bone is:
|
||||
:: 1 if "forward", i.e. we send %plea's on this flow, or
|
||||
:: 0 if "backward", i.e. we receive %plea's on this flow.
|
||||
::
|
||||
:: The second-least significant bit is 1 if the bone is a
|
||||
:: naxplanation bone, and 0 otherwise. Only naxplanation
|
||||
:: messages can be sent on a naxplanation bone, as %boon's.
|
||||
::
|
||||
+$ ossuary
|
||||
$: =next=bone
|
||||
@ -542,43 +584,40 @@
|
||||
:: Messages queue up in |message-pump's .unsent-messages until they
|
||||
:: can be packetized and fed into |packet-pump for sending. When we
|
||||
:: pop a message off .unsent-messages, we push as many fragments as
|
||||
:: we can into |packet-pump, then place the remaining in
|
||||
:: .unsent-fragments.
|
||||
:: we can into |packet-pump, which sends every packet it eats.
|
||||
:: Packets rejected by |packet-pump are placed in .unsent-fragments.
|
||||
::
|
||||
:: When we hear a packet ack, we send it to |packet-pump. If we
|
||||
:: haven't seen it before, |packet-pump reports the fresh ack.
|
||||
:: When we hear a packet ack, we send it to |packet-pump to be
|
||||
:: removed from its queue of unacked packets.
|
||||
::
|
||||
:: When we hear a message ack (positive or negative), we treat that
|
||||
:: as though all fragments have been acked. If this message is not
|
||||
:: .current, then it's a future message and .current has not yet been
|
||||
:: acked, so we place the ack in .queued-message-acks.
|
||||
:: .current, then this ack is for a future message and .current has
|
||||
:: not yet been acked, so we place the ack in .queued-message-acks.
|
||||
::
|
||||
:: If we hear a message ack before we've sent all the
|
||||
:: fragments for that message, clear .unsent-fragments. If the
|
||||
:: message ack was positive, print it out because it indicates the
|
||||
:: peer is not behaving properly.
|
||||
:: If we hear a message ack before we've sent all the fragments for
|
||||
:: that message, clear .unsent-fragments and have |packet-pump delete
|
||||
:: all sent fragments from the message. If this early message ack was
|
||||
:: positive, print it out because it indicates the peer is not
|
||||
:: behaving properly.
|
||||
::
|
||||
:: If the ack is for the current message, emit the message ack,
|
||||
:: increment .current, and check if this next message is in
|
||||
:: .queued-message-acks. If it is, emit the message (n)ack,
|
||||
:: increment .current, and check the next message. Repeat until
|
||||
:: .current is not fully acked.
|
||||
::
|
||||
:: When we hear a message nack, we send it to |packet-pump, which
|
||||
:: deletes all packets from that message. If .current gets nacked,
|
||||
:: clear .unsent-fragments and go into the same flow as when we hear
|
||||
:: the last packet ack on a message.
|
||||
:: If the ack is for the current message, have |packet-pump delete
|
||||
:: all packets from the message, give the message ack back
|
||||
:: to the client vane, increment .current, and check if this next
|
||||
:: message is in .queued-message-acks. If it is, emit the message
|
||||
:: (n)ack, increment .current, and check the next message. Repeat
|
||||
:: until .current is not fully acked.
|
||||
::
|
||||
:: The following equation is always true:
|
||||
:: .next - .current == number of messages in flight
|
||||
::
|
||||
:: At the end of a task, |message-pump sends a %halt task to
|
||||
:: |packet-pump, which can trigger a timer to be set or cleared based
|
||||
:: on congestion control calculations. When it fires, the timer will
|
||||
:: generally cause one or more packets to be resent.
|
||||
:: on congestion control calculations. When the timer fires, it will
|
||||
:: generally cause a packet to be re-sent.
|
||||
::
|
||||
:: Message sequence numbers start at 1 so the first message will be
|
||||
:: greater than .last-acked.message-sink-state on the receiver.
|
||||
:: Message sequence numbers start at 1 so that the first message will
|
||||
:: be greater than .last-acked.message-sink-state on the receiver.
|
||||
::
|
||||
:: current: sequence number of earliest message sent or being sent
|
||||
:: next: sequence number of next message to send
|
||||
@ -618,7 +657,14 @@
|
||||
:: algorithm. The information signals and their responses are
|
||||
:: identical to those of the "NewReno" variant of Reno; the
|
||||
:: implementation differs because Ames acknowledgments differ from
|
||||
:: TCP's and because we're using functional data structures.
|
||||
:: TCP's, because this code uses functional data structures, and
|
||||
:: because TCP's sequence numbers reset when a peer becomes
|
||||
:: unresponsive, whereas Ames sequence numbers only change when a
|
||||
:: ship breaches.
|
||||
::
|
||||
:: A deviation from Reno is +fast-resend-after-ack, which re-sends
|
||||
:: timed-out packets when a peer starts responding again after a
|
||||
:: period of unresponsiveness.
|
||||
::
|
||||
:: If .skips reaches 3, we perform a fast retransmit and fast
|
||||
:: recovery. This corresponds to Reno's handling of "three duplicate
|
||||
@ -697,8 +743,6 @@
|
||||
==
|
||||
:: $note: request to other vane
|
||||
::
|
||||
:: TODO: specialize gall interface for subscription management
|
||||
::
|
||||
:: Ames passes a %plea note to another vane when it receives a
|
||||
:: message on a "forward flow" from a peer, originally passed from
|
||||
:: one of the peer's vanes to the peer's Ames.
|
||||
@ -729,13 +773,6 @@
|
||||
== == ==
|
||||
:: $sign: response from other vane
|
||||
::
|
||||
:: A vane gives a %boon sign to Ames on a duct on which it had
|
||||
:: previously received a message on a "forward flow". Ames will
|
||||
:: transmit the message to the peer that had originally sent the
|
||||
:: message on the forward flow. The peer's Ames will then give the
|
||||
:: message to the remote vane from which the forward flow message
|
||||
:: originated.
|
||||
::
|
||||
+$ sign
|
||||
$~ [%b %wake ~]
|
||||
$% $: %b
|
||||
@ -1126,11 +1163,70 @@
|
||||
--
|
||||
:: +scry: dereference namespace
|
||||
::
|
||||
:: The ones producing vases are expected to be used like this:
|
||||
::
|
||||
:: &tang [(sell .^(vase %a /=peer=/~zod)) ~]
|
||||
::
|
||||
++ scry
|
||||
|= [fur=(unit (set monk)) ren=@tas why=shop syd=desk lot=coin tyl=path]
|
||||
^- (unit (unit cage))
|
||||
?. =(lot [%$ %da now]) ~
|
||||
?. =(%$ ren) [~ ~]
|
||||
?. =([%& our] why)
|
||||
[~ ~]
|
||||
?+ syd ~
|
||||
%peer
|
||||
?. ?=([@ ~] tyl) [~ ~]
|
||||
=/ who (slaw %p i.tyl)
|
||||
?~ who [~ ~]
|
||||
=/ per (~(get by peers.ames-state) u.who)
|
||||
=/ res
|
||||
?- per
|
||||
~ %unknown
|
||||
[~ %alien *] %alien
|
||||
[~ %known *]
|
||||
=, u.per
|
||||
:* %known
|
||||
symkeymug=(mug symmetric-key)
|
||||
life=life
|
||||
pubkey=public-key
|
||||
sponsor=sponsor
|
||||
route=route
|
||||
qos=qos
|
||||
ossuary=ossuary
|
||||
snd=~(key by snd)
|
||||
rcv=~(key by rcv)
|
||||
nax=nax
|
||||
heeds=heeds
|
||||
==
|
||||
==
|
||||
``noun+!>(!>(res))
|
||||
::
|
||||
[~ ~]
|
||||
%bones
|
||||
?. ?=([@ ~] tyl) [~ ~]
|
||||
=/ who (slaw %p i.tyl)
|
||||
?~ who [~ ~]
|
||||
=/ per (~(get by peers.ames-state) u.who)
|
||||
?. ?=([~ %known *] per) [~ ~]
|
||||
=/ res
|
||||
=, u.per
|
||||
[snd=~(key by snd) rcv=~(key by rcv)]
|
||||
``noun+!>(res)
|
||||
::
|
||||
%snd-bone
|
||||
?. ?=([@ @ ~] tyl) [~ ~]
|
||||
=/ who (slaw %p i.tyl)
|
||||
?~ who [~ ~]
|
||||
=/ ost (slaw %ud i.t.tyl)
|
||||
?~ ost [~ ~]
|
||||
=/ per (~(get by peers.ames-state) u.who)
|
||||
?. ?=([~ %known *] per) [~ ~]
|
||||
=/ mps (~(get by snd.u.per) u.ost)
|
||||
?~ mps [~ ~]
|
||||
=/ res
|
||||
u.mps
|
||||
``noun+!>(!>(res))
|
||||
==
|
||||
--
|
||||
:: helpers
|
||||
::
|
||||
@ -1381,10 +1477,15 @@
|
||||
?> =(rcvr-life.shut-packet our-life.channel)
|
||||
:: non-galaxy: update route with heard lane or forwarded lane
|
||||
::
|
||||
=? route.peer-state
|
||||
?& !=(%czar (clan:title her.channel))
|
||||
!=([~ %& *] route.peer-state)
|
||||
==
|
||||
=? route.peer-state
|
||||
?: =(%czar (clan:title her.channel))
|
||||
%.n
|
||||
=/ is-old-direct=? ?=([~ %& *] route.peer-state)
|
||||
=/ is-new-direct=? ?=(~ origin.packet)
|
||||
:: old direct takes precedence over new indirect
|
||||
::
|
||||
|(is-new-direct !is-old-direct)
|
||||
::
|
||||
?~ origin.packet
|
||||
`[direct=%.y lane]
|
||||
`[direct=%.n u.origin.packet]
|
||||
@ -1512,6 +1613,7 @@
|
||||
::
|
||||
:: Abandon all pretense of continuity and delete all messaging state
|
||||
:: associated with .ship, including sent and unsent messages.
|
||||
:: Also cancel all timers related to .ship.
|
||||
::
|
||||
++ on-publ-breach
|
||||
|= =ship
|
||||
@ -2053,7 +2155,11 @@
|
||||
++ send-shut-packet
|
||||
|= =shut-packet
|
||||
^+ peer-core
|
||||
:: swizzle bone just before sending; TODO document
|
||||
:: swizzle last bone bit before sending
|
||||
::
|
||||
:: The peer has the opposite perspective from ours about what
|
||||
:: kind of flow this is (forward/backward), so flip the bit
|
||||
:: here.
|
||||
::
|
||||
=. bone.shut-packet (mix 1 bone.shut-packet)
|
||||
::
|
||||
@ -2201,7 +2307,7 @@
|
||||
:: +on-sink-boon: handle response message received by |message-sink
|
||||
::
|
||||
:: .bone must be mapped in .ossuary.peer-state, or we crash.
|
||||
:: This means a malformed message will kill a channel. We
|
||||
:: This means a malformed message will kill a flow. We
|
||||
:: could change this to a no-op if we had some sort of security
|
||||
:: reporting.
|
||||
::
|
||||
@ -2491,7 +2597,7 @@
|
||||
^+ message-pump
|
||||
=/ top-live
|
||||
(peek:packet-queue:*make-packet-pump live.packet-pump-state.state)
|
||||
?. |(?=(~ top-live) (gte current.state message-num.key.u.top-live))
|
||||
?. |(?=(~ top-live) (lte current.state message-num.key.u.top-live))
|
||||
~| [%strange-current current=current.state key.u.top-live]
|
||||
!!
|
||||
message-pump
|
||||
@ -2654,7 +2760,7 @@
|
||||
:: +on-hear: handle ack on a live packet
|
||||
::
|
||||
:: If the packet was in our queue, delete it and update our
|
||||
:: metrics. Otherwise, no-op.
|
||||
:: metrics, possibly re-sending skipped packets. Otherwise, no-op.
|
||||
::
|
||||
++ on-hear
|
||||
|= [=message-num =fragment-num]
|
||||
|
@ -44,12 +44,13 @@
|
||||
::
|
||||
:: Type of request.
|
||||
::
|
||||
:: %d produces a set of desks, %p gets file permissions, %u checks for
|
||||
:: existence, %v produces a ++dome of all desk data, %w gets @ud and @da
|
||||
:: variants for the given case, %x gets file contents, %y gets a directory
|
||||
:: listing, and %z gets a recursive hash of the file contents and children.
|
||||
:: %d produces a set of desks, %p gets file permissions, %t gets all paths
|
||||
:: with the specified prefix, %u checks for existence, %v produces a ++dome
|
||||
:: of all desk data, %w gets @ud and @da variants for the given case, %x
|
||||
:: gets file contents, %y gets a directory listing, and %z gets a recursive
|
||||
:: hash of the file contents and children.
|
||||
::
|
||||
:: ++ care ?($d $p $u $v $w $x $y $z)
|
||||
:: ++ care ?($d $p $t $u $v $w $x $y $z)
|
||||
::
|
||||
:: Keeps track of subscribers.
|
||||
::
|
||||
|
@ -637,7 +637,7 @@
|
||||
this.outstandingSubscriptions.set(
|
||||
id,
|
||||
{
|
||||
err: connectionErrFunc,
|
||||
err: connectionErrFunc,
|
||||
event: eventFunc,
|
||||
quit: quitFunc
|
||||
}
|
||||
|
@ -54,7 +54,7 @@
|
||||
++ state
|
||||
$: :: state version
|
||||
::
|
||||
%2
|
||||
%3
|
||||
:: agents by ship
|
||||
::
|
||||
=agents
|
||||
@ -904,7 +904,7 @@
|
||||
%give
|
||||
=/ =gift:agent p.card
|
||||
?: ?=(%kick -.gift)
|
||||
=/ ducts=(list duct) (ap-ducts-from-path path.gift ship.gift)
|
||||
=/ ducts=(list duct) (ap-ducts-from-paths paths.gift ship.gift)
|
||||
%+ turn ducts
|
||||
|= =duct
|
||||
~? &(=(duct system-duct.agents.state) !=(agent-name %hood))
|
||||
@ -914,7 +914,7 @@
|
||||
?. ?=(%fact -.gift)
|
||||
[agent-duct %give %unto gift]~
|
||||
::
|
||||
=/ ducts=(list duct) (ap-ducts-from-path path.gift ~)
|
||||
=/ ducts=(list duct) (ap-ducts-from-paths paths.gift ~)
|
||||
=/ =cage cage.gift
|
||||
%+ turn ducts
|
||||
|= =duct
|
||||
@ -1010,6 +1010,17 @@
|
||||
::
|
||||
++ ap-agent-core
|
||||
~(. agent.current-agent ap-construct-bowl)
|
||||
:: +ap-ducts-from-paths: get ducts subscribed to paths
|
||||
::
|
||||
++ ap-ducts-from-paths
|
||||
|= [target-paths=(list path) target-ship=(unit ship)]
|
||||
^- (list duct)
|
||||
?: &(?=(~ target-paths) ?=(~ target-ship))
|
||||
~[agent-duct]
|
||||
%- zing
|
||||
%+ turn target-paths
|
||||
|= =path
|
||||
(ap-ducts-from-path `path target-ship)
|
||||
:: +ap-ducts-from-path: get ducts subscribed to path
|
||||
::
|
||||
++ ap-ducts-from-path
|
||||
@ -1567,16 +1578,177 @@
|
||||
=? all-state ?=(%1 -.all-state)
|
||||
(state-1-to-2 all-state)
|
||||
::
|
||||
?> ?=(%2 -.all-state)
|
||||
=? all-state ?=(%2 -.all-state)
|
||||
(state-2-to-3 all-state)
|
||||
::
|
||||
?> ?=(%3 -.all-state)
|
||||
gall-payload(state all-state)
|
||||
::
|
||||
:: +all-state: upgrade path
|
||||
::
|
||||
++ all-state $%(state-0 state-1 ^state)
|
||||
++ all-state $%(state-0 state-1 state-2 ^state)
|
||||
::
|
||||
++ state-2-to-3
|
||||
|= =state-2
|
||||
^- ^state
|
||||
%= state-2
|
||||
- %3
|
||||
running.agents-2
|
||||
%- ~(run by running.agents-2.state-2)
|
||||
|= =running-agent-2
|
||||
^- running-agent
|
||||
%= running-agent-2
|
||||
agent-2 (agent-2-to-3 agent-2.running-agent-2)
|
||||
==
|
||||
==
|
||||
::
|
||||
++ agent-2-to-3
|
||||
|= =agent-2
|
||||
^- agent
|
||||
=> |%
|
||||
++ cards-2-to-3
|
||||
|= cards=(list card:^agent-2)
|
||||
^- (list card:agent)
|
||||
%+ turn cards
|
||||
|= =card:^agent-2
|
||||
^- card:agent
|
||||
?. ?=([%give ?(%fact %kick) *] card) card
|
||||
%=(card path.p (drop path.p.card))
|
||||
--
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
pass ~(. agent-2 bowl)
|
||||
++ on-init
|
||||
=^ cards agent-2 on-init:pass
|
||||
[(cards-2-to-3 cards) this]
|
||||
::
|
||||
++ on-save
|
||||
on-save:pass
|
||||
::
|
||||
++ on-load
|
||||
|= old-state=vase
|
||||
=^ cards agent-2 (on-load:pass old-state)
|
||||
[(cards-2-to-3 cards) this]
|
||||
::
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
=^ cards agent-2 (on-poke:pass mark vase)
|
||||
[(cards-2-to-3 cards) this]
|
||||
::
|
||||
++ on-watch
|
||||
|= =path
|
||||
=^ cards agent-2 (on-watch:pass path)
|
||||
[(cards-2-to-3 cards) this]
|
||||
::
|
||||
++ on-leave
|
||||
|= =path
|
||||
=^ cards agent-2 (on-leave:pass path)
|
||||
[(cards-2-to-3 cards) this]
|
||||
::
|
||||
++ on-peek
|
||||
|= =path
|
||||
(on-peek:pass path)
|
||||
::
|
||||
++ on-agent
|
||||
|= [=wire =sign:agent:gall]
|
||||
=^ cards agent-2 (on-agent:pass wire sign)
|
||||
[(cards-2-to-3 cards) this]
|
||||
::
|
||||
++ on-arvo
|
||||
|= [=wire =sign-arvo]
|
||||
=^ cards agent-2 (on-arvo:pass wire sign-arvo)
|
||||
[(cards-2-to-3 cards) this]
|
||||
::
|
||||
++ on-fail
|
||||
|= [=term =tang]
|
||||
=^ cards agent-2 (on-fail:pass term tang)
|
||||
[(cards-2-to-3 cards) this]
|
||||
--
|
||||
::
|
||||
++ state-2
|
||||
$: %2
|
||||
=agents-2
|
||||
==
|
||||
::
|
||||
++ agents-2
|
||||
$: system-duct=duct
|
||||
outstanding=(map [wire duct] (qeu remote-request))
|
||||
contacts=(set ship)
|
||||
running=(map term running-agent-2)
|
||||
blocked=(map term blocked)
|
||||
==
|
||||
::
|
||||
++ running-agent-2
|
||||
$: cache=worm
|
||||
control-duct=duct
|
||||
live=?
|
||||
=stats
|
||||
=subscribers
|
||||
=agent-2
|
||||
=beak
|
||||
marks=(map duct mark)
|
||||
==
|
||||
::
|
||||
++ agent-2
|
||||
=< form
|
||||
|%
|
||||
+$ step (quip card form)
|
||||
+$ card (wind note gift)
|
||||
+$ note note:agent
|
||||
+$ task task:agent
|
||||
+$ sign sign:agent
|
||||
+$ gift
|
||||
$% [%fact path=(unit path) =cage]
|
||||
[%kick path=(unit path) ship=(unit ship)]
|
||||
[%watch-ack p=(unit tang)]
|
||||
[%poke-ack p=(unit tang)]
|
||||
==
|
||||
++ form
|
||||
$_ ^|
|
||||
|_ bowl
|
||||
++ on-init
|
||||
*(quip card _^|(..on-init))
|
||||
::
|
||||
++ on-save
|
||||
*vase
|
||||
::
|
||||
++ on-load
|
||||
|~ old-state=vase
|
||||
*(quip card _^|(..on-init))
|
||||
::
|
||||
++ on-poke
|
||||
|~ [mark vase]
|
||||
*(quip card _^|(..on-init))
|
||||
::
|
||||
++ on-watch
|
||||
|~ path
|
||||
*(quip card _^|(..on-init))
|
||||
::
|
||||
++ on-leave
|
||||
|~ path
|
||||
*(quip card _^|(..on-init))
|
||||
::
|
||||
++ on-peek
|
||||
|~ path
|
||||
*(unit (unit cage))
|
||||
::
|
||||
++ on-agent
|
||||
|~ [wire sign]
|
||||
*(quip card _^|(..on-init))
|
||||
::
|
||||
++ on-arvo
|
||||
|~ [wire sign-arvo]
|
||||
*(quip card _^|(..on-init))
|
||||
::
|
||||
++ on-fail
|
||||
|~ [term tang]
|
||||
*(quip card _^|(..on-init))
|
||||
--
|
||||
--
|
||||
::
|
||||
++ state-1-to-2
|
||||
|= =state-1
|
||||
^- ^state
|
||||
^- state-2
|
||||
%= state-1
|
||||
- %2
|
||||
+.agents-1 [~ +.agents-1.state-1]
|
||||
@ -1590,7 +1762,7 @@
|
||||
++ agents-1
|
||||
$: system-duct=duct
|
||||
contacts=(set ship)
|
||||
running=(map term running-agent)
|
||||
running=(map term running-agent-2)
|
||||
blocked=(map term blocked)
|
||||
==
|
||||
::
|
||||
@ -1602,7 +1774,7 @@
|
||||
running.agents-0
|
||||
%- ~(run by running.agents-0.state-0)
|
||||
|= =running-agent-0
|
||||
^- running-agent
|
||||
^- running-agent-2
|
||||
%= running-agent-0
|
||||
agent-0 (agent-0-to-1 agent-0.running-agent-0)
|
||||
==
|
||||
@ -1610,7 +1782,7 @@
|
||||
::
|
||||
++ agent-0-to-1
|
||||
|= =agent-0
|
||||
^- agent
|
||||
^- agent-2
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
pass ~(. agent-0 bowl)
|
||||
@ -1692,7 +1864,7 @@
|
||||
+$ card (wind note gift)
|
||||
+$ note note:agent
|
||||
+$ task task:agent
|
||||
+$ gift gift:agent
|
||||
+$ gift gift:agent-2
|
||||
+$ sign sign:agent
|
||||
++ form
|
||||
$_ ^|
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1887,8 +1887,8 @@
|
||||
[%poke-as =mark =cage]
|
||||
==
|
||||
+$ gift
|
||||
$% [%fact path=(unit path) =cage]
|
||||
[%kick path=(unit path) ship=(unit ship)]
|
||||
$% [%fact paths=(list path) =cage]
|
||||
[%kick paths=(list path) ship=(unit ship)]
|
||||
[%watch-ack p=(unit tang)]
|
||||
[%poke-ack p=(unit tang)]
|
||||
==
|
||||
|
@ -120,8 +120,8 @@
|
||||
(pure:m ~)
|
||||
=/ =path /(scot %p ship.i.udiffs)
|
||||
=/ cards
|
||||
:~ [%give %fact `/ %azimuth-udiff !>(i.udiffs)]
|
||||
[%give %fact `path %azimuth-udiff !>(i.udiffs)]
|
||||
:~ [%give %fact ~[/] %azimuth-udiff !>(i.udiffs)]
|
||||
[%give %fact ~[path] %azimuth-udiff !>(i.udiffs)]
|
||||
==
|
||||
;< ~ bind:m (send-raw-cards:strandio cards)
|
||||
loop(udiffs t.udiffs)
|
||||
|
@ -141,8 +141,8 @@
|
||||
++ test-list-murn
|
||||
%+ expect-eq
|
||||
!> ~[6 10]
|
||||
!> %+ murn `(list @)`~[2 3 4 5]
|
||||
|= [x=@]
|
||||
!> %+ murn `(list @)`~[2 3 4 5]
|
||||
|= [x=@]
|
||||
^- (unit)
|
||||
?: =((mod x 2) 0) ~
|
||||
(some (mul x 2))
|
||||
|
@ -308,7 +308,7 @@
|
||||
:~ :* duct=~[/http-blah] %give %response
|
||||
[%start [200 ['content-type' 'text/html']~] ~ %.n]
|
||||
== == ==
|
||||
|
||||
|
||||
;: weld
|
||||
results1
|
||||
results2
|
||||
|
@ -144,7 +144,7 @@ gulp.task('urbit-copy', function () {
|
||||
gulp.task('js-bundle-dev', gulp.series('jsx-transform', 'js-imports'));
|
||||
gulp.task('tile-js-bundle-dev', gulp.series('tile-jsx-transform', 'tile-js-imports'));
|
||||
gulp.task('js-bundle-prod', gulp.series('jsx-transform', 'js-imports', 'js-minify'))
|
||||
gulp.task('tile-js-bundle-prod',
|
||||
gulp.task('tile-js-bundle-prod',
|
||||
gulp.series('tile-jsx-transform', 'tile-js-imports', 'tile-js-minify'));
|
||||
|
||||
gulp.task('bundle-dev',
|
||||
|
@ -99,6 +99,21 @@ h2 {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* embeds */
|
||||
.embed-container {
|
||||
position: relative;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.embed-container iframe, .embed-container object, .embed-container embed {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* responsive */
|
||||
|
||||
@media all and (max-width: 34.375em) {
|
||||
@ -114,6 +129,9 @@ h2 {
|
||||
.h-100-minus-96-s {
|
||||
height: calc(100% - 96px);
|
||||
}
|
||||
.embed-container {
|
||||
padding-bottom: 56.25%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 34.375em) and (max-width: 46.875em) {
|
||||
@ -123,6 +141,9 @@ h2 {
|
||||
.h-100-minus-48-m {
|
||||
height: calc(100% - 48px);
|
||||
}
|
||||
.embed-container {
|
||||
padding-bottom: 56.25%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 46.875em) and (max-width: 60em) {
|
||||
@ -132,6 +153,9 @@ h2 {
|
||||
.h-100-minus-48-l {
|
||||
height: calc(100% - 48px);
|
||||
}
|
||||
.embed-container {
|
||||
padding-bottom: 37.5%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 60em) {
|
||||
@ -141,4 +165,52 @@ h2 {
|
||||
.h-100-minus-48-xl {
|
||||
height: calc(100% - 48px);
|
||||
}
|
||||
}
|
||||
.embed-container {
|
||||
padding-bottom: 28.125%;
|
||||
}
|
||||
}
|
||||
|
||||
/* dark */
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.bg-black-d {
|
||||
background-color: black;
|
||||
}
|
||||
.white-d {
|
||||
color: white;
|
||||
}
|
||||
.gray1-d {
|
||||
color: #4d4d4d;
|
||||
}
|
||||
.gray2-d {
|
||||
color: #7f7f7f;
|
||||
}
|
||||
.gray3-d {
|
||||
color: #b1b2b3;
|
||||
}
|
||||
.gray4-d {
|
||||
color: #e6e6e6;
|
||||
}
|
||||
.bg-gray0-d {
|
||||
background-color: #333;
|
||||
}
|
||||
.b--gray0-d {
|
||||
border-color: #333;
|
||||
}
|
||||
.b--gray2-d {
|
||||
border-color: #7f7f7f;
|
||||
}
|
||||
.bb-d {
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
.invert-d {
|
||||
filter: invert(1);
|
||||
}
|
||||
.o-60-d {
|
||||
opacity: .6;
|
||||
}
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ class UrbitApi {
|
||||
add: this.groupAdd.bind(this),
|
||||
remove: this.groupRemove.bind(this)
|
||||
};
|
||||
|
||||
|
||||
this.chat = {
|
||||
message: this.chatMessage.bind(this),
|
||||
read: this.chatRead.bind(this)
|
||||
@ -25,7 +25,7 @@ class UrbitApi {
|
||||
delete: this.chatViewDelete.bind(this),
|
||||
join: this.chatViewJoin.bind(this),
|
||||
};
|
||||
|
||||
|
||||
this.invite = {
|
||||
accept: this.inviteAccept.bind(this),
|
||||
decline: this.inviteDecline.bind(this),
|
||||
@ -36,7 +36,7 @@ class UrbitApi {
|
||||
bind(path, method, ship = this.authTokens.ship, app, success, fail, quit) {
|
||||
this.bindPaths = _.uniq([...this.bindPaths, path]);
|
||||
|
||||
window.subscriptionId = window.urb.subscribe(ship, app, path,
|
||||
window.subscriptionId = window.urb.subscribe(ship, app, path,
|
||||
(err) => {
|
||||
fail(err);
|
||||
},
|
||||
@ -59,7 +59,7 @@ class UrbitApi {
|
||||
window.urb.poke(ship, appl, mark, data,
|
||||
(json) => {
|
||||
resolve(json);
|
||||
},
|
||||
},
|
||||
(err) => {
|
||||
reject(err);
|
||||
});
|
||||
@ -142,7 +142,7 @@ class UrbitApi {
|
||||
}
|
||||
|
||||
chatViewJoin(ship, path, askHistory) {
|
||||
this.chatViewAction({
|
||||
this.chatViewAction({
|
||||
join: {
|
||||
ship, path,
|
||||
'ask-history': askHistory
|
||||
@ -153,9 +153,9 @@ class UrbitApi {
|
||||
inviteAction(data) {
|
||||
this.action("invite-store", "json", data);
|
||||
}
|
||||
|
||||
|
||||
inviteInvite(path, ship) {
|
||||
this.action("invite-hook", "json",
|
||||
this.action("invite-hook", "json",
|
||||
{
|
||||
invite: {
|
||||
path: '/chat',
|
||||
@ -180,7 +180,7 @@ class UrbitApi {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
inviteDecline(uid) {
|
||||
this.inviteAction({
|
||||
decline: {
|
||||
|
@ -230,14 +230,15 @@ export class ChatScreen extends Component {
|
||||
<Link to="/~chat/">{"⟵ All Chats"}</Link>
|
||||
</div>
|
||||
<div
|
||||
className="pl3 pt2 bb b--gray4 flex relative overflow-x-scroll overflow-x-auto-l overflow-x-auto-xl flex-shrink-0"
|
||||
className={`pl3 pt2 bb b--gray4 b--gray2-d bg-black-d flex relative overflow-x-scroll
|
||||
overflow-x-auto-l overflow-x-auto-xl flex-shrink-0`}
|
||||
style={{ height: 48 }}>
|
||||
<SidebarSwitcher
|
||||
sidebarShown={this.props.sidebarShown}
|
||||
popout={this.props.popout}
|
||||
/>
|
||||
<Link to={`/~chat/` + isinPopout + `room` + state.station}
|
||||
className="pt2">
|
||||
className="pt2 white-d">
|
||||
<h2
|
||||
className="mono dib f8 fw4 v-top"
|
||||
style={{ width: "max-content" }}>
|
||||
@ -253,7 +254,7 @@ export class ChatScreen extends Component {
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="overflow-y-scroll pt3 pb2 flex flex-column-reverse"
|
||||
className="overflow-y-scroll bg-black-d pt3 pb2 flex flex-column-reverse"
|
||||
style={{ height: "100%", resize: "vertical" }}
|
||||
onScroll={this.onScroll}>
|
||||
<div
|
||||
|
@ -80,9 +80,9 @@ export class JoinScreen extends Component {
|
||||
render() {
|
||||
const { props } = this;
|
||||
|
||||
let joinClasses = "db f9 green2 ba pa2 b--green2 pointer";
|
||||
let joinClasses = "db f9 green2 ba pa2 b--green2 bg-gray0-d pointer";
|
||||
if ((!this.state.station) || (this.state.station === "/")) {
|
||||
joinClasses = 'db f9 gray2 ba pa2 b--gray3 pointer';
|
||||
joinClasses = 'db f9 gray2 ba pa2 b--gray3 bg-gray0-d pointer';
|
||||
}
|
||||
|
||||
let errElem = (<span />);
|
||||
@ -95,7 +95,8 @@ export class JoinScreen extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-100 w-100 pa3 pt2 overflow-x-hidden flex flex-column">
|
||||
<div className={`h-100 w-100 pa3 pt2 overflow-x-hidden flex flex-column
|
||||
bg-black-d white-d`}>
|
||||
<div
|
||||
className="w-100 dn-m dn-l dn-xl inter pt1 pb6 f8">
|
||||
<Link to="/~chat/">{"⟵ All Chats"}</Link>
|
||||
@ -106,7 +107,7 @@ export class JoinScreen extends Component {
|
||||
<p className="f9 gray2 mb4">Chat names use lowercase, hyphens, and slashes.</p>
|
||||
<textarea
|
||||
ref={ e => { this.textarea = e; } }
|
||||
className="f7 mono ba b--gray3 pa3 mb2 db"
|
||||
className="f7 mono ba b--gray3 b--gray2-d bg-black-d white-d pa3 mb2 db"
|
||||
placeholder="~zod/chatroom"
|
||||
spellCheck="false"
|
||||
rows={1}
|
||||
|
@ -64,7 +64,7 @@ export class ChatInput extends Component {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bindShortcuts() {
|
||||
Mousetrap(this.textareaRef.current).bind('enter', e => {
|
||||
e.preventDefault();
|
||||
@ -173,9 +173,9 @@ export class ChatInput extends Component {
|
||||
const { props, state } = this;
|
||||
|
||||
this.bindShortcuts();
|
||||
|
||||
|
||||
return (
|
||||
<div className="pa3 cf flex black bt b--gray4" style={{ flexGrow: 1 }}>
|
||||
<div className="pa3 cf flex black white-d bt b--gray4 b--gray2-d bg-black-d" style={{ flexGrow: 1 }}>
|
||||
<div
|
||||
className="fl"
|
||||
style={{
|
||||
@ -185,9 +185,9 @@ export class ChatInput extends Component {
|
||||
}}>
|
||||
<Sigil ship={window.ship} size={24} color="#4330FC" />
|
||||
</div>
|
||||
<div className="fr h-100 flex" style={{ flexGrow: 1 }}>
|
||||
<div className="fr h-100 flex bg-black-d" style={{ flexGrow: 1 }}>
|
||||
<textarea
|
||||
className={"pl3 bn"}
|
||||
className={"pl3 bn bg-black-d white-d"}
|
||||
style={{ flexGrow: 1, height: 28, paddingTop: 6, resize: "none" }}
|
||||
autoCapitalize="none"
|
||||
autoFocus={(
|
||||
|
@ -14,21 +14,21 @@ export class ChatTabBar extends Component {
|
||||
|
||||
if (props.location.pathname.includes('/settings')) {
|
||||
memColor = 'gray3';
|
||||
setColor = 'black';
|
||||
setColor = 'black white-d';
|
||||
} else if (props.location.pathname.includes('/members')) {
|
||||
memColor = 'black';
|
||||
memColor = 'black white-d';
|
||||
setColor = 'gray3';
|
||||
} else {
|
||||
memColor = 'gray3';
|
||||
setColor = 'gray3';
|
||||
}
|
||||
|
||||
(props.location.pathname.includes('/popout'))
|
||||
(props.location.pathname.includes('/popout'))
|
||||
? popout = "popout/"
|
||||
: popout = "";
|
||||
|
||||
let hidePopoutIcon = (this.props.popout)
|
||||
? "dn-m dn-l dn-xl"
|
||||
let hidePopoutIcon = (this.props.popout)
|
||||
? "dn-m dn-l dn-xl"
|
||||
: "dib-m dib-l dib-xl";
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ export class ChatTabBar extends Component {
|
||||
<a href={`/~chat/popout/room` + props.station} target="_blank"
|
||||
className="dib fr">
|
||||
<img
|
||||
className={`flex-shrink-0 pr2 dn ` + hidePopoutIcon}
|
||||
className={`flex-shrink-0 pr2 dn invert-d ` + hidePopoutIcon}
|
||||
src="/~chat/img/popout.png"
|
||||
height="16"
|
||||
width="16"/>
|
||||
|
@ -17,7 +17,7 @@ export class HeaderBar extends Component {
|
||||
: "dn db-m db-l db-xl";
|
||||
|
||||
return (
|
||||
<div className={`bg-black w-100 justify-between ` + popoutHide}
|
||||
<div className={`bg-black bb-d b--gray2-d w-100 justify-between ` + popoutHide}
|
||||
style={{ height: 48, padding: 8}}>
|
||||
<a className="db"
|
||||
style={{ background: '#1A1A1A',
|
||||
|
@ -7,7 +7,7 @@ export class SidebarSwitcher extends Component {
|
||||
let popoutSwitcher = this.props.popout
|
||||
? "dn-m dn-l dn-xl"
|
||||
: "dib-m dib-l dib-xl";
|
||||
|
||||
|
||||
return (
|
||||
<div className="pt2">
|
||||
<a
|
||||
@ -16,7 +16,7 @@ export class SidebarSwitcher extends Component {
|
||||
api.sidebarToggle();
|
||||
}}>
|
||||
<img
|
||||
className={`pr3 dn ` + popoutSwitcher}
|
||||
className={`pr3 dn invert-d ` + popoutSwitcher}
|
||||
src={
|
||||
this.props.sidebarShown
|
||||
? "/~chat/img/ChatSwitcherLink.png"
|
||||
|
@ -3,7 +3,7 @@ import React, { Component } from 'react';
|
||||
export class IconSpinner extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="spinner-pending"></div>
|
||||
<div className="spinner-pending"></div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { sigil, reactRenderer } from 'urbit-sigil-js';
|
||||
|
||||
|
||||
|
||||
export class Sigil extends Component {
|
||||
render() {
|
||||
const { props } = this;
|
||||
|
@ -80,7 +80,7 @@ export class InviteElement extends Component {
|
||||
<div></div>
|
||||
);
|
||||
|
||||
let modifyButtonClasses = "db f9 ba pa2 b--black pointer";
|
||||
let modifyButtonClasses = "db f9 ba pa2 white-d bg-gray0-d b--black b--gray2-d pointer";
|
||||
if (state.error) {
|
||||
modifyButtonClasses = modifyButtonClasses + ' gray3';
|
||||
}
|
||||
@ -96,7 +96,7 @@ export class InviteElement extends Component {
|
||||
<div>
|
||||
<textarea
|
||||
ref={ e => { this.textarea = e; } }
|
||||
className="f7 mono ba b--gray3 pa3 mb4 db w-100"
|
||||
className="f7 mono ba b--gray3 bg-black-d white-d pa3 mb4 db w-100"
|
||||
style={{
|
||||
resize: 'none',
|
||||
height: 50
|
||||
|
@ -16,14 +16,14 @@ export class MemberElement extends Component {
|
||||
let actionElem;
|
||||
if (props.ship === props.owner) {
|
||||
actionElem = (
|
||||
<p className="w-20 dib list-ship black f8 c-default">
|
||||
<p className="w-20 dib list-ship black white-d f8 c-default">
|
||||
Host
|
||||
</p>
|
||||
);
|
||||
} else if (window.ship !== props.ship && window.ship === props.owner) {
|
||||
actionElem = (
|
||||
<a onClick={this.onRemove.bind(this)}
|
||||
className="w-20 dib list-ship black f8 pointer">
|
||||
className="w-20 dib list-ship black white-d f8 pointer">
|
||||
Ban
|
||||
</a>
|
||||
);
|
||||
@ -38,7 +38,7 @@ export class MemberElement extends Component {
|
||||
<Sigil ship={props.ship} size={32} />
|
||||
<p
|
||||
className={
|
||||
"w-70 mono list-ship dib v-mid black ml2 nowrap f8"
|
||||
"w-70 mono list-ship dib v-mid black white-d ml2 nowrap f8"
|
||||
}>
|
||||
~{props.ship}
|
||||
</p>
|
||||
|
@ -8,14 +8,29 @@ import _ from 'lodash';
|
||||
|
||||
|
||||
export class Message extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
unfold: false
|
||||
};
|
||||
this.unFoldEmbed = this.unFoldEmbed.bind(this);
|
||||
}
|
||||
|
||||
unFoldEmbed(id) {
|
||||
let unfoldState = this.state.unfold;
|
||||
unfoldState = !unfoldState;
|
||||
this.setState({unfold: unfoldState});
|
||||
let iframe = this.refs.iframe;
|
||||
iframe.setAttribute('src', iframe.getAttribute('data-src'));
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
const { props } = this;
|
||||
let letter = props.msg.letter;
|
||||
|
||||
if ('code' in letter) {
|
||||
let outputElement =
|
||||
(!!letter.code.output &&
|
||||
let outputElement =
|
||||
(!!letter.code.output &&
|
||||
letter.code.output.length && letter.code.output.length > 0) ?
|
||||
(
|
||||
<pre className="clamp-attachment pa1 mt0 mb0">
|
||||
@ -34,10 +49,20 @@ export class Message extends Component {
|
||||
let imgMatch =
|
||||
/(jpg|img|png|gif|tiff|jpeg|JPG|IMG|PNG|TIFF|GIF|webp|WEBP|webm|WEBM)$/
|
||||
.exec(letter.url);
|
||||
// this is jank
|
||||
// TODO do we know ID lenght?
|
||||
let youTubeRegex = new RegExp(''
|
||||
+ /(?:https?:\/\/(?:[a-z]+.)?)/.source // protocol
|
||||
+ /(?:youtu\.?be(?:\.com)?\/)(?:embed\/)?/.source // short and long-links
|
||||
+ /(?:(?:(?:(?:watch\?)?(?:time_continue=(?:[0-9]+))?.+v=)?([a-zA-Z0-9_-]+))(?:\?t\=(?:[0-9a-zA-Z]+))?)/.source // id
|
||||
)
|
||||
let ytMatch =
|
||||
youTubeRegex.exec(letter.url);
|
||||
let contents = letter.url;
|
||||
if (imgMatch) {
|
||||
contents = (
|
||||
<img
|
||||
className="o-60-d"
|
||||
src={letter.url}
|
||||
style={{
|
||||
width: "50%",
|
||||
@ -45,18 +70,58 @@ export class Message extends Component {
|
||||
}}
|
||||
></img>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<a className="f7 lh-copy v-top bb b--black word-break-all"
|
||||
return (
|
||||
<a className="f7 lh-copy v-top bb word-break-all"
|
||||
href={letter.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
{contents}
|
||||
</a>
|
||||
);
|
||||
} else if (ytMatch) {
|
||||
contents = (
|
||||
<div className={'embed-container mb2 w-100 w-75-l w-50-xl ' +
|
||||
((this.state.unfold === true)
|
||||
? "db"
|
||||
: "dn")}>
|
||||
<iframe
|
||||
ref="iframe"
|
||||
width="560"
|
||||
height="315"
|
||||
data-src={`https://www.youtube.com/embed/${ytMatch[1]}`}
|
||||
frameBorder="0" allow="picture-in-picture, fullscreen">
|
||||
</iframe>
|
||||
</div>
|
||||
)
|
||||
return (
|
||||
<div>
|
||||
<a href={letter.url}
|
||||
className="f7 lh-copy v-top bb word-break-all"
|
||||
href={letter.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
{contents}
|
||||
{letter.url}
|
||||
</a>
|
||||
);
|
||||
<a className="f7 pointer pl2 lh-copy v-top word-break-all"
|
||||
onClick={e => this.unFoldEmbed()}>
|
||||
[embed]
|
||||
</a>
|
||||
{contents}
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<a className="f7 lh-copy v-top bb b--black word-break-all"
|
||||
href={letter.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
{contents}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
} else if ('me' in letter) {
|
||||
return (
|
||||
<p className='f7 lh-copy v-top'>
|
||||
<p className='f7 i lh-copy v-top'>
|
||||
{letter.me}
|
||||
</p>
|
||||
);
|
||||
@ -70,7 +135,7 @@ export class Message extends Component {
|
||||
&& (chatroom[0] === letter.text))) { // entire message is room name?
|
||||
return (
|
||||
<Link
|
||||
className="bb b--black f7 mono lh-copy v-top"
|
||||
className="bb b--black f7 mono lh-copy v-top"
|
||||
to={"/~chat/join/" + chatroom.input}>
|
||||
{letter.text}
|
||||
</Link>
|
||||
@ -89,7 +154,7 @@ export class Message extends Component {
|
||||
render() {
|
||||
const { props } = this;
|
||||
let pending = !!props.msg.pending ? ' o-40' : '';
|
||||
let datestamp = "~" + moment.unix(props.msg.when / 1000).format('YYYY.MM.D');
|
||||
let datestamp = "~" + moment.unix(props.msg.when / 1000).format('YYYY.M.D');
|
||||
|
||||
let paddingTop = props.paddingTop ? {'paddingTop': '6px'} : '';
|
||||
|
||||
@ -108,22 +173,22 @@ export class Message extends Component {
|
||||
<Sigil
|
||||
ship={props.msg.author}
|
||||
size={24}
|
||||
color={((props.msg.author === window.ship)
|
||||
color={((props.msg.author === window.ship)
|
||||
|| (props.msg.author.substr(1) === window.ship))
|
||||
? "#4330FC"
|
||||
? "#4330FC"
|
||||
: "#000000"}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="fr clamp-message"
|
||||
className="fr clamp-message white-d"
|
||||
style={{ flexGrow: 1, marginTop: -8 }}>
|
||||
<div className="hide-child" style={paddingTop}>
|
||||
<p className="v-mid mono f9 gray dib mr3">
|
||||
<p className="v-mid mono f9 gray2 dib mr3">
|
||||
{props.msg.author.slice(0, 1) === "~" ? "" : "~"}
|
||||
{props.msg.author}
|
||||
</p>
|
||||
<p className="v-mid mono f9 gray dib">{timestamp}</p>
|
||||
<p className="v-mid mono f9 ml2 gray dib child dn-s">{datestamp}</p>
|
||||
<p className="v-mid mono f9 gray2 dib">{timestamp}</p>
|
||||
<p className="v-mid mono f9 ml2 gray2 dib child dn-s">{datestamp}</p>
|
||||
</div>
|
||||
{this.renderContent()}
|
||||
</div>
|
||||
@ -138,9 +203,9 @@ export class Message extends Component {
|
||||
style={{
|
||||
minHeight: "min-content"
|
||||
}}>
|
||||
<p className="child pt2 pl2 pr1 mono f9 gray dib">{timestamp}</p>
|
||||
<div className="fr f7 clamp-message" style={{ flexGrow: 1 }}>
|
||||
{this.renderContent()}
|
||||
<p className="child pt2 pl2 pr1 mono f9 gray2 dib">{timestamp}</p>
|
||||
<div className="fr f7 clamp-message white-d pr3" style={{ flexGrow: 1 }}>
|
||||
{this.renderContent()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -18,7 +18,7 @@ export class SidebarInvite extends Component {
|
||||
return (
|
||||
<div className='pa3'>
|
||||
<div className='w-100 v-mid'>
|
||||
<p className="dib f8 mono">
|
||||
<p className="dib f8 mono gray4-d">
|
||||
{props.invite.text}
|
||||
</p>
|
||||
</div>
|
||||
@ -28,7 +28,7 @@ export class SidebarInvite extends Component {
|
||||
Accept Invite
|
||||
</a>
|
||||
<a
|
||||
className="dib pointer ml4 pa2 f9 bg-black white mt4"
|
||||
className="dib pointer ml4 pa2 f9 bg-black bg-gray0-d white mt4"
|
||||
onClick={this.onDecline.bind(this)}>
|
||||
Decline
|
||||
</a>
|
||||
|
@ -37,7 +37,7 @@ export class SidebarItem extends Component {
|
||||
|
||||
getLetter(lett) {
|
||||
if ('text' in lett) {
|
||||
return lett.text;
|
||||
return lett.text;
|
||||
} else if ('url' in lett) {
|
||||
return lett.url;
|
||||
} else if ('code' in lett) {
|
||||
@ -50,23 +50,23 @@ export class SidebarItem extends Component {
|
||||
render() {
|
||||
const { props, state } = this;
|
||||
|
||||
let unreadElem = !!props.unread
|
||||
? "fw7 green2"
|
||||
let unreadElem = !!props.unread
|
||||
? "fw7 green2"
|
||||
: "";
|
||||
|
||||
let title = props.title.substr(1);
|
||||
|
||||
let description = this.getLetter(props.description);
|
||||
|
||||
let selectedCss = !!props.selected ? 'bg-gray5' : 'bg-white pointer';
|
||||
|
||||
let selectedCss = !!props.selected ? 'bg-gray5 bg-gray0-d gray3-d' : 'bg-white bg-black-d gray3-d pointer';
|
||||
|
||||
return (
|
||||
<div
|
||||
className={"z1 pa3 pt4 pb4 bb b--gray4 " + selectedCss}
|
||||
className={"z1 pa3 pt4 pb4 bb b--gray4 b--gray2-d " + selectedCss}
|
||||
onClick={this.onClick.bind(this)}>
|
||||
<div className="w-100 v-mid">
|
||||
<p className={"dib mono f8 " + unreadElem }>
|
||||
<span className={(unreadElem === "") ? "gray3" : ""}>
|
||||
<span className={(unreadElem === "") ? "gray3 gray2-d" : ""}>
|
||||
{title.substr(0, title.indexOf("/"))}/
|
||||
</span>
|
||||
{title.substr(title.indexOf("/") + 1)}
|
||||
|
@ -51,8 +51,8 @@ export class MemberScreen extends Component {
|
||||
|
||||
let writeListMembers = writeGroup.map((mem) => {
|
||||
return (
|
||||
<MemberElement
|
||||
key={mem}
|
||||
<MemberElement
|
||||
key={mem}
|
||||
owner={deSig(props.match.params.ship)}
|
||||
ship={mem}
|
||||
path={`/chat${state.station}/write`}
|
||||
@ -63,8 +63,8 @@ export class MemberScreen extends Component {
|
||||
|
||||
let readListMembers = readGroup.map((mem) => {
|
||||
return (
|
||||
<MemberElement
|
||||
key={mem}
|
||||
<MemberElement
|
||||
key={mem}
|
||||
owner={deSig(props.match.params.ship)}
|
||||
ship={mem}
|
||||
path={`/chat${state.station}/read`}
|
||||
@ -76,21 +76,21 @@ export class MemberScreen extends Component {
|
||||
let isinPopout = this.props.popout ? "popout/" : "";
|
||||
|
||||
return (
|
||||
<div className="h-100 w-100 overflow-x-hidden flex flex-column">
|
||||
<div className="h-100 w-100 overflow-x-hidden flex flex-column white-d">
|
||||
<div
|
||||
className="w-100 dn-m dn-l dn-xl inter pt4 pb6 pl3 f8"
|
||||
style={{ height: "1rem" }}>
|
||||
<Link to="/~chat/">{"⟵ All Chats"}</Link>
|
||||
</div>
|
||||
<div
|
||||
className="pl3 pt2 bb b--gray4 flex relative overflow-x-scroll overflow-x-auto-l overflow-x-auto-xl flex-shrink-0"
|
||||
className="pl3 pt2 bb b--gray4 b--gray2-d bg-black-d flex relative overflow-x-scroll overflow-x-auto-l overflow-x-auto-xl flex-shrink-0"
|
||||
style={{ height: 48 }}>
|
||||
<SidebarSwitcher
|
||||
sidebarShown={this.props.sidebarShown}
|
||||
popout={this.props.popout}
|
||||
/>
|
||||
<Link to={`/~chat/` + isinPopout + `room` + state.station}
|
||||
className="pt2">
|
||||
className="pt2 white-d">
|
||||
<h2
|
||||
className="mono dib f8 fw4 v-top"
|
||||
style={{ width: "max-content" }}>
|
||||
|
@ -28,7 +28,7 @@ export class NewScreen extends Component {
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { props, state } = this;
|
||||
|
||||
if (prevProps !== props) {
|
||||
if (prevProps !== props) {
|
||||
let station = `/~${window.ship}/${state.idName}`;
|
||||
if (station in props.inbox) {
|
||||
props.history.push('/~chat/room' + station);
|
||||
@ -81,7 +81,7 @@ export class NewScreen extends Component {
|
||||
let invalidChara = new RegExp(/[^a-z0-9/-]/);
|
||||
|
||||
let invalid = (
|
||||
(!state.idName) || (state.idName.startsWith("/")) ||
|
||||
(!state.idName) || (state.idName.startsWith("/")) ||
|
||||
(state.idName.includes("//")) || (invalidChara.test(state.idName))
|
||||
);
|
||||
|
||||
@ -132,7 +132,7 @@ export class NewScreen extends Component {
|
||||
|
||||
// TODO: don't do this, it's shitty
|
||||
let writeAud;
|
||||
let readAud;
|
||||
let readAud;
|
||||
|
||||
if (state.security === 'village') {
|
||||
aud.push(`~${window.ship}`);
|
||||
@ -168,9 +168,9 @@ export class NewScreen extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let createClasses = "pointer db f9 green2 ba pa2 b--green2";
|
||||
let createClasses = "pointer db f9 green2 bg-gray0-d ba pa2 b--green2";
|
||||
if (!this.state.idName) {
|
||||
createClasses = 'pointer db f9 gray2 ba pa2 b--gray3';
|
||||
createClasses = 'pointer db f9 gray2 ba bg-gray0-d pa2 b--gray3';
|
||||
}
|
||||
|
||||
let idErrElem = (<span />);
|
||||
@ -192,7 +192,8 @@ export class NewScreen extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-100 w-100 w-50-l w-50-xl pa3 pt2 overflow-x-hidden flex flex-column">
|
||||
<div className={`h-100 w-100 w-50-l w-50-xl pa3 pt2 overflow-x-hidden
|
||||
bg-black-d white-d flex flex-column`}>
|
||||
<div className="w-100 dn-m dn-l dn-xl inter pt1 pb6 f8">
|
||||
<Link to="/~chat/">{"⟵ All Chats"}</Link>
|
||||
</div>
|
||||
@ -202,8 +203,8 @@ export class NewScreen extends Component {
|
||||
<p className="f9 gray2 db mb4">
|
||||
Lowercase alphanumeric characters, dashes, and slashes only
|
||||
</p>
|
||||
<textarea
|
||||
className="f7 ba b--gray3 pa3 db w-100"
|
||||
<textarea
|
||||
className="f7 ba b--gray3 b--gray2-d bg-black-d white-d pa3 db w-100"
|
||||
placeholder="secret-chat"
|
||||
rows={1}
|
||||
style={{
|
||||
@ -216,7 +217,7 @@ export class NewScreen extends Component {
|
||||
<div className="dropdown relative">
|
||||
<select
|
||||
style={{WebkitAppearance: "none"}}
|
||||
className="pa3 f8 bg-white br0 w-100 inter"
|
||||
className="pa3 f8 bg-white bg-black-d white-d br0 w-100 inter"
|
||||
value={this.state.securityValue}
|
||||
onChange={this.securityChange}>
|
||||
<option value="village">Village</option>
|
||||
@ -232,7 +233,7 @@ export class NewScreen extends Component {
|
||||
</p>
|
||||
<textarea
|
||||
ref={e => { this.textarea = e; }}
|
||||
className="f7 mono ba b--gray3 pa3 mb4 db w-100"
|
||||
className="f7 mono ba b--gray3 b--gray2-d bg-black-d white-d pa3 mb4 db w-100"
|
||||
placeholder="~zod, ~bus"
|
||||
spellCheck="false"
|
||||
style={{
|
||||
|
@ -37,7 +37,7 @@ export class Root extends Component {
|
||||
let unreads = {};
|
||||
Object.keys(state.inbox).forEach((stat) => {
|
||||
let envelopes = state.inbox[stat].envelopes;
|
||||
|
||||
|
||||
if (envelopes.length === 0) {
|
||||
messagePreviews[stat] = false;
|
||||
} else {
|
||||
@ -47,7 +47,7 @@ export class Root extends Component {
|
||||
unreads[stat] =
|
||||
state.inbox[stat].config.length > state.inbox[stat].config.read;
|
||||
});
|
||||
|
||||
|
||||
let invites = '/chat' in state.invites ?
|
||||
state.invites['/chat'] : {};
|
||||
|
||||
|
@ -49,7 +49,7 @@ export class SettingsScreen extends Component {
|
||||
|
||||
let chatOwner = (deSig(props.match.params.ship) === window.ship);
|
||||
|
||||
let deleteButtonClasses = (chatOwner) ? 'b--red2 red2 pointer' : 'b--grey3 grey3 c-default';
|
||||
let deleteButtonClasses = (chatOwner) ? 'b--red2 red2 pointer bg-gray0-d' : 'b--grey3 grey3 bg-gray0-d c-default';
|
||||
let leaveButtonClasses = (!chatOwner) ? "pointer" : "c-default";
|
||||
|
||||
return (
|
||||
@ -58,7 +58,7 @@ export class SettingsScreen extends Component {
|
||||
<p className="f8 mt3 lh-copy db">Leave Chat</p>
|
||||
<p className="f9 gray2 db mb4">Remove this chat from your chat list. You will need to request for access again.</p>
|
||||
<a onClick={(!chatOwner) ? this.deleteChat.bind(this) : null}
|
||||
className={"dib f9 black ba pa2 b--black " + leaveButtonClasses}>Leave this chat</a>
|
||||
className={"dib f9 black gray4-d bg-gray0-d ba pa2 b--black b--gray2-d " + leaveButtonClasses}>Leave this chat</a>
|
||||
</div>
|
||||
<div className={"w-100 fl mt3 " + ((!chatOwner) ? 'o-30' : '')}>
|
||||
<p className="f8 mt3 lh-copy db">Delete Chat</p>
|
||||
@ -83,21 +83,21 @@ export class SettingsScreen extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-100 w-100 overflow-x-hidden flex flex-column">
|
||||
<div className="h-100 w-100 overflow-x-hidden flex flex-column white-d">
|
||||
<div
|
||||
className="w-100 dn-m dn-l dn-xl inter pt4 pb6 pl3 f8"
|
||||
style={{ height: "1rem" }}>
|
||||
<Link to="/~chat/">{"⟵ All Chats"}</Link>
|
||||
</div>
|
||||
<div
|
||||
className="pl3 pt2 bb b--gray4 flex relative overflow-x-scroll overflow-x-auto-l overflow-x-auto-xl flex-shrink-0"
|
||||
className="pl3 pt2 bb b--gray4 b--gray2-d bg-black-d flex relative overflow-x-scroll overflow-x-auto-l overflow-x-auto-xl flex-shrink-0"
|
||||
style={{ height: 48 }}>
|
||||
<SidebarSwitcher
|
||||
sidebarShown={this.props.sidebarShown}
|
||||
popout={this.props.popout}
|
||||
/>
|
||||
<Link to={`/~chat/` + isinPopout + `room` + state.station}
|
||||
className="pt2">
|
||||
className="pt2 white-d">
|
||||
<h2
|
||||
className="mono dib f8 fw4 v-top"
|
||||
style={{ width: "max-content" }}>
|
||||
@ -118,7 +118,7 @@ export class SettingsScreen extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-100 w-100 overflow-x-hidden flex flex-column">
|
||||
<div className="h-100 w-100 overflow-x-hidden flex flex-column white-d">
|
||||
<div
|
||||
className="w-100 dn-m dn-l dn-xl inter pt4 pb6 pl3 f8"
|
||||
style={{ height: "1rem" }}>
|
||||
|
@ -71,18 +71,19 @@ export class Sidebar extends Component {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="h-100-minus-96-s h-100 w-100 overflow-x-hidden flex flex-column relative z1">
|
||||
<div className={`h-100-minus-96-s h-100 w-100 overflow-x-hidden flex
|
||||
bg-black-d flex-column relative z1`}>
|
||||
<div className="overflow-y-auto h-100">
|
||||
{sidebarInvites}
|
||||
{sidebarItems}
|
||||
</div>
|
||||
<div className="absolute z2 tc w-100 bg-transparent"
|
||||
style={{ bottom: 10 }}>
|
||||
<a className="dib f9 pa3 bt bb bl br tc pointer bg-white"
|
||||
<a className="dib f9 pa3 bt bb bl br tc pointer bg-white bg-gray0-d gray4-d b--gray2-d"
|
||||
onClick={this.onClickNew.bind(this)}>
|
||||
Create New Chat
|
||||
</a>
|
||||
<a className="dib f9 pa3 bt bb br tl pointer bg-white"
|
||||
<a className="dib f9 pa3 bt bb br tl pointer bg-white bg-gray0-d gray4-d b--gray2-d"
|
||||
onClick={this.onClickJoin.bind(this)}>
|
||||
Join Existing Chat
|
||||
</a>
|
||||
|
@ -6,12 +6,12 @@ import { HeaderBar } from '/components/lib/header-bar.js';
|
||||
export class Skeleton extends Component {
|
||||
render() {
|
||||
|
||||
let sidebarHide = (!this.props.sidebarShown || this.props.popout)
|
||||
? "dn"
|
||||
let sidebarHide = (!this.props.sidebarShown || this.props.popout)
|
||||
? "dn"
|
||||
: "";
|
||||
|
||||
let sidebarHideOnMobile = this.props.sidebarHideOnMobile
|
||||
? "dn-s"
|
||||
let sidebarHideOnMobile = this.props.sidebarHideOnMobile
|
||||
? "dn-s"
|
||||
: "";
|
||||
|
||||
let chatHideOnMobile = this.props.chatHideonMobile
|
||||
@ -19,18 +19,18 @@ export class Skeleton extends Component {
|
||||
: "";
|
||||
|
||||
return (
|
||||
<div className="h-100 w-100 absolute">
|
||||
<div className="h-100 w-100 absolute bg-black-d">
|
||||
<HeaderBar spinner={this.props.spinner} popout={this.props.popout} />
|
||||
<div className={`cf w-100 absolute flex ` +
|
||||
((this.props.chatHideonMobile)
|
||||
<div className={`cf w-100 absolute flex ` +
|
||||
((this.props.chatHideonMobile)
|
||||
? "h-100 "
|
||||
: "h-100-minus-48-s ") +
|
||||
: "h-100-minus-48-s ") +
|
||||
((this.props.popout)
|
||||
? "h-100"
|
||||
: "h-100-minus-48-m h-100-minus-48-l h-100-minus-48-xl")}>
|
||||
<div className={
|
||||
`fl h-100 br b--gray4 overflow-x-hidden
|
||||
flex-basis-full-s flex-basis-300-m flex-basis-300-l
|
||||
`fl h-100 br b--gray4 b--gray2-d overflow-x-hidden
|
||||
flex-basis-full-s flex-basis-300-m flex-basis-300-l
|
||||
flex-basis-300-xl ` +
|
||||
sidebarHide + " " +
|
||||
sidebarHideOnMobile
|
||||
@ -43,7 +43,7 @@ export class Skeleton extends Component {
|
||||
<a className="pl3 pb6" href="/">
|
||||
{"⟵ Landscape"}
|
||||
</a>
|
||||
<div className="bb b--gray4 inter f8 pl3 pt6 pb3">All Chats</div>
|
||||
<div className="bb b--gray4 white-d inter f8 pl3 pt6 pb3">All Chats</div>
|
||||
</div>
|
||||
{this.props.sidebar}
|
||||
</div>
|
||||
|
@ -26,9 +26,9 @@ export class ChatUpdateReducer {
|
||||
messages(json, state) {
|
||||
let data = _.get(json, 'messages', false);
|
||||
if (data) {
|
||||
state.inbox[data.path].envelopes =
|
||||
state.inbox[data.path].envelopes =
|
||||
data.envelopes.concat(state.inbox[data.path].envelopes);
|
||||
state.inbox[data.path].config.length =
|
||||
state.inbox[data.path].config.length =
|
||||
state.inbox[data.path].config.length + data.envelopes.length;
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ export class ChatUpdateReducer {
|
||||
delete state.inbox[data.path];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pending(json, state) {
|
||||
let msg = _.get(json, 'message', false);
|
||||
if (!msg || !state.pendingMessages.has(msg.path)) {
|
||||
@ -76,6 +76,6 @@ export class ChatUpdateReducer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,6 @@ export class PermissionUpdateReducer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -18,12 +18,12 @@ export default class App extends Component {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<div>
|
||||
<Route exact path="/"
|
||||
<Route exact path="/"
|
||||
render={ (props) => {
|
||||
return (
|
||||
<Home
|
||||
<Home
|
||||
{...props}
|
||||
data={this.state}
|
||||
data={this.state}
|
||||
keys={new Set(Object.keys(this.state))}
|
||||
/>
|
||||
);
|
||||
|
@ -12,7 +12,7 @@ export default class Header extends Component {
|
||||
super(props);
|
||||
this.interval = null;
|
||||
this.timeout = null;
|
||||
|
||||
|
||||
this.state = {
|
||||
moment: moment()
|
||||
};
|
||||
@ -20,7 +20,7 @@ export default class Header extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
let sec = parseInt(moment().format("s"), 10);
|
||||
|
||||
|
||||
this.timeout = setTimeout(() => {
|
||||
this.setState({
|
||||
moment: moment()
|
||||
@ -32,7 +32,7 @@ export default class Header extends Component {
|
||||
}, 60000);
|
||||
}, (60 - sec) * 1000);
|
||||
}
|
||||
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.timeout);
|
||||
clearInterval(this.interval);
|
||||
|
@ -15,7 +15,7 @@ export default class Tile extends Component {
|
||||
return (
|
||||
<div className="fl ma2 bg-white overflow-hidden"
|
||||
style={{ height: '234px', width: '234px' }}>
|
||||
{ !!SpecificTile ?
|
||||
{ !!SpecificTile ?
|
||||
<SpecificTile data={this.props.data} />
|
||||
: <div></div>
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
class Api {
|
||||
bind(app, path, success, fail, ship) {
|
||||
window.urb.subscribe(ship, app, path,
|
||||
window.urb.subscribe(ship, app, path,
|
||||
(err) => {
|
||||
fail(err, app, path, ship);
|
||||
},
|
||||
@ -25,7 +25,7 @@ class Api {
|
||||
window.urb.poke(ship, appl, mark, data,
|
||||
(json) => {
|
||||
resolve(json);
|
||||
},
|
||||
},
|
||||
(err) => {
|
||||
reject(err);
|
||||
});
|
||||
|
@ -145,7 +145,7 @@ gulp.task('urbit-copy', function () {
|
||||
gulp.task('js-bundle-dev', gulp.series('jsx-transform', 'js-imports'));
|
||||
gulp.task('tile-js-bundle-dev', gulp.series('tile-jsx-transform', 'tile-js-imports'));
|
||||
gulp.task('js-bundle-prod', gulp.series('jsx-transform', 'js-imports', 'js-minify'))
|
||||
gulp.task('tile-js-bundle-prod',
|
||||
gulp.task('tile-js-bundle-prod',
|
||||
gulp.series('tile-jsx-transform', 'tile-js-imports', 'tile-js-minify'));
|
||||
|
||||
gulp.task('bundle-dev',
|
||||
|
@ -12,7 +12,7 @@ class UrbitApi {
|
||||
bind(path, method, ship = this.authTokens.ship, appl = "publish", success, fail) {
|
||||
this.bindPaths = _.uniq([...this.bindPaths, path]);
|
||||
|
||||
window.urb.subscribe(ship, appl, path,
|
||||
window.urb.subscribe(ship, appl, path,
|
||||
(err) => {
|
||||
fail(err);
|
||||
},
|
||||
|
@ -54,7 +54,7 @@ export class Blog extends Component {
|
||||
awaiting: false,
|
||||
pathData: [
|
||||
{ text: "Home", url: "/~publish/recent" },
|
||||
{ text: blog.info.title,
|
||||
{ text: blog.info.title,
|
||||
url: `/~publish/${blog.info.owner}/${blog.info.filename}` }
|
||||
],
|
||||
});
|
||||
@ -62,7 +62,7 @@ export class Blog extends Component {
|
||||
this.props.setSpinner(false);
|
||||
} else if (diff.data.remove) {
|
||||
if (diff.data.remove.post) {
|
||||
// XX TODO
|
||||
// XX TODO
|
||||
} else {
|
||||
this.props.history.push("/~publish/recent");
|
||||
}
|
||||
@ -203,7 +203,7 @@ export class Blog extends Component {
|
||||
blogHost: blog.info.owner,
|
||||
pathData: [
|
||||
{ text: "Home", url: "/~publish/recent" },
|
||||
{ text: blog.info.title,
|
||||
{ text: blog.info.title,
|
||||
url: `/~publish/${blog.info.owner}/${blog.info.filename}` }
|
||||
],
|
||||
};
|
||||
@ -279,7 +279,7 @@ export class Blog extends Component {
|
||||
let viewSettings = (this.props.ship === window.ship)
|
||||
? this.viewSettings
|
||||
: null;
|
||||
|
||||
|
||||
if (this.state.view === 'notes') {
|
||||
return (
|
||||
<div>
|
||||
|
@ -10,7 +10,7 @@ export class BlogNotes extends Component {
|
||||
|
||||
render() {
|
||||
if (!this.props.posts ||
|
||||
((this.props.posts.length === 0) &&
|
||||
((this.props.posts.length === 0) &&
|
||||
(this.props.ship === window.ship))) {
|
||||
let link = {
|
||||
pathname: "/~publish/new-post",
|
||||
|
@ -79,7 +79,7 @@ export class BlogSettings extends Component {
|
||||
|
||||
render() {
|
||||
let back = '<- Back to notes'
|
||||
let enableSave = ((this.state.title !== '') &&
|
||||
let enableSave = ((this.state.title !== '') &&
|
||||
(this.state.title !== this.props.title) &&
|
||||
!this.state.awaitingTitleChange);
|
||||
return (
|
||||
@ -93,7 +93,7 @@ export class BlogSettings extends Component {
|
||||
</p>
|
||||
<div className="flex">
|
||||
<div className="flex-col w-100">
|
||||
<p className="body-regular-400">Delete Notebook</p>
|
||||
<p className="body-regular-400">Delete Notebook</p>
|
||||
<p className="gray-50 label-small-2" style={{marginTop:12, marginBottom:8}}>
|
||||
Permanently delete this notebook
|
||||
</p>
|
||||
@ -102,7 +102,7 @@ export class BlogSettings extends Component {
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-col w-100">
|
||||
<p className="body-regular-400">Rename</p>
|
||||
<p className="body-regular-400">Rename</p>
|
||||
<p className="gray-50 label-small-2" style={{marginTop:12, marginBottom:23}}>
|
||||
Change the name of this notebook
|
||||
</p>
|
||||
|
@ -51,7 +51,7 @@ export class BlogSubs extends Component {
|
||||
.split(/[\s,]+/)
|
||||
.map(t => t.trim());
|
||||
|
||||
let valid = tokens.reduce((valid, s) =>
|
||||
let valid = tokens.reduce((valid, s) =>
|
||||
valid && ((s !== '~') && urbitOb.isValidPatp(s) && s.includes('~')), true);
|
||||
|
||||
if (valid) {
|
||||
@ -86,7 +86,7 @@ export class BlogSubs extends Component {
|
||||
|
||||
render() {
|
||||
let back = '<- Back to notes'
|
||||
|
||||
|
||||
let subscribers = this.props.subs.map((sub, i) => {
|
||||
return (
|
||||
<div className="flex w-100" key={i+1}>
|
||||
@ -113,7 +113,7 @@ export class BlogSubs extends Component {
|
||||
</p>
|
||||
<div className="flex">
|
||||
<div className="flex-col w-100">
|
||||
<p className="body-regular-400">Members</p>
|
||||
<p className="body-regular-400">Members</p>
|
||||
<p className="gray-50 label-small-2"
|
||||
style={{marginTop:12, marginBottom: 23}}>
|
||||
Everyone subscribed to this notebook
|
||||
@ -121,7 +121,7 @@ export class BlogSubs extends Component {
|
||||
{subscribers}
|
||||
</div>
|
||||
<div className="flex-col w-100">
|
||||
<p className="body-regular-400">Invite</p>
|
||||
<p className="body-regular-400">Invite</p>
|
||||
<p className="gray-50 label-small-2"
|
||||
style={{marginTop:12, marginBottom: 23}}>
|
||||
Invite people to subscribe to this notebook
|
||||
|
@ -52,7 +52,7 @@ export class CommentBox extends Component {
|
||||
? "body-regular-400 w-100"
|
||||
: "body-regular-400 w-100 gray-30";
|
||||
return (
|
||||
<div className="cb w-100 flex"
|
||||
<div className="cb w-100 flex"
|
||||
style={{paddingBottom: 8, marginTop: 32}}>
|
||||
<div className="fl" style={{marginRight: 10}}>
|
||||
<Sigil ship={this.props.our} size={36}/>
|
||||
@ -67,10 +67,10 @@ export class CommentBox extends Component {
|
||||
onChange={this.commentChange}
|
||||
disabled={(!this.props.enabled)}>
|
||||
</textarea>
|
||||
<PostButton
|
||||
post={this.props.post}
|
||||
<PostButton
|
||||
post={this.props.post}
|
||||
enabled={(Boolean(this.props.content) && this.props.enabled)}
|
||||
/>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -12,7 +12,7 @@ export class Comments extends Component {
|
||||
commentBody: '',
|
||||
awaiting: false,
|
||||
}
|
||||
|
||||
|
||||
this.toggleDisplay = this.toggleDisplay.bind(this);
|
||||
this.commentChange = this.commentChange.bind(this);
|
||||
this.postComment = this.postComment.bind(this);
|
||||
|
@ -30,7 +30,7 @@ export class HeaderMenu extends Component {
|
||||
<div className="fl bb b-gray-30 w-16" >
|
||||
</div>
|
||||
|
||||
<NavLink exact
|
||||
<NavLink exact
|
||||
className="header-menu-item"
|
||||
to="/~publish/recent"
|
||||
activeStyle={{
|
||||
@ -44,7 +44,7 @@ export class HeaderMenu extends Component {
|
||||
<div className="fl bb b-gray-30 w-16" >
|
||||
</div>
|
||||
|
||||
<NavLink exact
|
||||
<NavLink exact
|
||||
className="header-menu-item"
|
||||
to="/~publish/subs"
|
||||
activeStyle={{
|
||||
@ -58,7 +58,7 @@ export class HeaderMenu extends Component {
|
||||
<div className="fl bb b-gray-30 w-16" >
|
||||
</div>
|
||||
|
||||
<NavLink exact
|
||||
<NavLink exact
|
||||
className="header-menu-item"
|
||||
to="/~publish/pubs"
|
||||
activeStyle={{
|
||||
|
@ -3,7 +3,7 @@ import React, { Component } from 'react';
|
||||
export class IconSpinner extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="spinner-pending"></div>
|
||||
<div className="spinner-pending"></div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { sigil, reactRenderer } from 'urbit-sigil-js';
|
||||
|
||||
|
||||
|
||||
export class Sigil extends Component {
|
||||
render() {
|
||||
const { props } = this;
|
||||
|
@ -57,7 +57,7 @@ class Preview extends Component {
|
||||
|
||||
let date = moment(previewProps.date).fromNow();
|
||||
let authorDate = `${previewProps.author} • ${date}`
|
||||
let collLink = "/~publish/" +
|
||||
let collLink = "/~publish/" +
|
||||
previewProps.blogOwner + "/" +
|
||||
previewProps.collectionName;
|
||||
let postLink = collLink + "/" + previewProps.postName;
|
||||
|
@ -32,7 +32,7 @@ export class PathControl extends Component {
|
||||
(last.lastMatch === '/~publish/:ship/:blog')){
|
||||
blog = (last.lastParams.ship.slice(1) == window.ship)
|
||||
? _.get(this.props, `pubs["${last.lastParams.blog}"]`, false)
|
||||
: _.get(this.props,
|
||||
: _.get(this.props,
|
||||
`subs["${last.lastParams.ship.slice(1)}"]["${last.lastParams.blog}"]`, false);
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ export class PostBody extends Component {
|
||||
let page = this.parseContent(this.props.body.c,
|
||||
this.props.body.gn,
|
||||
this.props.body.ga,
|
||||
null);
|
||||
null);
|
||||
return page;
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ export class PostPreview extends Component {
|
||||
: `${this.props.post.numComments} comments`;
|
||||
let date = moment(this.props.post.date).fromNow();
|
||||
let authorDate = `${this.props.post.author} • ${date}`
|
||||
let collLink = "/~publish/" +
|
||||
let collLink = "/~publish/" +
|
||||
this.props.post.blogOwner + "/" +
|
||||
this.props.post.collectionName;
|
||||
let postLink = collLink + "/" + this.props.post.postName;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user