Merge pull request #1202 from urbit/promised-land

Modulo
This commit is contained in:
Joe Bryan 2019-06-27 16:48:55 -07:00 committed by GitHub
commit ffa4d326d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
80 changed files with 204180 additions and 1038 deletions

615
app/chat.hoon Normal file
View File

@ -0,0 +1,615 @@
/- hall
/+ *server, chat, hall-json
/= index
/^ octs
/; as-octs:mimes:html
/: /===/app/chat/index
/| /html/
/~ ~
==
/= tile-js
/^ octs
/; as-octs:mimes:html
/: /===/app/chat/js/tile
/| /js/
/~ ~
==
/= script
/^ octs
/; as-octs:mimes:html
/: /===/app/chat/js/index
/| /js/
/~ ~
==
/= style
/^ octs
/; as-octs:mimes:html
/: /===/app/chat/css/index
/| /css/
/~ ~
==
/= style
/^ octs
/; as-octs:mimes:html
/: /===/app/chat/css/index
/| /css/
/~ ~
==
/= chat-png
/^ (map knot @)
/: /===/app/chat/img /_ /png/
::
=, chat
::
|_ [bol=bowl:gall sta=state]
::
++ this .
::
:: +prep: set up the app, migrate the state once started
::
++ prep
|= old=(unit state)
^- (quip move _this)
=/ launchnoun [%noun [%chat /chattile '/~chat/js/tile.js']]
?~ old
=/ inboxpat /circle/inbox/config/group
=/ circlespat /circles/[(scot %p our.bol)]
=/ inboxwir /circle/[(scot %p our.bol)]/inbox/config/group
=/ inboxi/poke
:- %hall-action
[%source %inbox %.y (silt [[our.bol %i] ~]~)]
:_ this
:~ [ost.bol %peer inboxwir [our.bol %hall] inboxpat]
[ost.bol %peer circlespat [our.bol %hall] circlespat]
[ost.bol %connect / [~ /'~chat'] %chat]
[ost.bol %poke /chat [our.bol %hall] inboxi]
[ost.bol %poke /chat [our.bol %launch] launchnoun]
==
:- [ost.bol %poke /chat [our.bol %launch] launchnoun]~
this(sta u.old)
::
::
::
++ construct-tile-json
|= str=streams
^- json
=/ numbers/(list [circle:hall @ud])
%+ turn ~(tap by messages.str)
|= [cir=circle:hall lis=(list envelope:hall)]
^- [circle:hall @ud]
?~ lis
[cir 0]
=/ last (snag (dec (lent lis)) `(list envelope:hall)`lis)
[cir (add num.last 1)]
=/ maptjson=(map @t json)
%- my
:~ ['config' (config-to-json str)]
['numbers' (numbers-to-json numbers)]
==
[%o maptjson]
::
++ peer-chattile
|= wir=wire
^- (quip move _this)
:_ this
[ost.bol %diff %json (construct-tile-json str.sta)]~
::
:: +peer-messages: subscribe to subset of messages and updates
::
::
++ peer-primary
|= wir=wire
^- (quip move _this)
~& (lent (prey:pubsub:userlib /primary bol))
=* messages messages.str.sta
=/ lismov/(list move)
%+ murn ~(tap by messages)
|= [cir=circle:hall lis=(list envelope:hall)]
^- (unit move)
=/ envs/(unit (list envelope:hall)) (~(get by messages) cir)
?~ envs
~
=/ length/@ (lent u.envs)
=/ start/@
?: (gte length 100)
(sub length 100)
0
=/ end/@ length
=/ offset/@ (sub end start)
:- ~
:* ost.bol
%diff
%chat-update
[%messages cir start end (swag [start offset] u.envs)]
==
:_ this
[[ost.bol %diff %chat-config str.sta] lismov]
::
:: +poke-chat: send us an action
::
++ poke-chat-action
|= act=action:chat
^- (quip move _this)
:_ this
%+ turn lis.act
|= hac=action:hall
^- move
:* ost.bol
%poke
/p/[(scot %da now.bol)]
[our.bol %hall]
[%hall-action hac]
==
::
:: +send-chat-update: utility func for sending updates to all our subscribers
::
++ send-chat-update
|= [upd=update str=streams]
^- (list move)
=/ updates/(list move)
%+ turn (prey:pubsub:userlib /primary bol)
|= [=bone *]
[bone %diff %chat-update upd]
::
=/ tile-updates/(list move)
%+ turn (prey:pubsub:userlib /chattile bol)
|= [=bone *]
[bone %diff %json (construct-tile-json str)]
::
%+ weld
updates
tile-updates
::
::
:: +hall arms
::
::
:: +diff-hall-prize: handle full state initially handed to us by hall
::
++ diff-hall-prize
|= [wir=wire piz=prize:hall]
^- (quip move _this)
?~ wir
(mean [leaf+"invalid wire for diff: {(spud wir)}"]~)
?+ i.wir
(mean [leaf+"invalid wire for diff: {(spud wir)}"]~)
::
:: %circles wire
::
%circles
?> ?=(%circles -.piz)
=/ str %= str.sta
circles cis.piz
==
:- (send-chat-update [[%circles cis.piz] str])
this(str.sta str)
::
:: %circle wire
::
%circle
:: ::
:: :: %circle prize
:: ::
:: %circle
?> ?=(%circle -.piz)
=/ circle/circle:hall [our.bol &3:wir]
?: =(circle [our.bol %inbox])
::
:: fill inbox config and remote configs with prize data
::
=/ configs
%- ~(uni in configs.str.sta)
^- (map circle:hall (unit config:hall))
(~(run by rem.cos.piz) |=(a=config:hall `a))
::
=/ circles/(list circle:hall)
%+ turn ~(tap in src.loc.cos.piz)
|= src=source:hall
^- circle:hall
cir.src
::
=/ meslis/(list [circle:hall (list envelope:hall)])
%+ turn circles
|= cir=circle:hall
^- [circle:hall (list envelope:hall)]
[cir ~]
::
=/ localpeers/(set @p)
%- silt %+ turn ~(tap by loc.pes.piz)
|= [shp=@p stat=status:hall]
shp
::
=/ peers/(map circle:hall (set @p))
%- ~(rep by rem.pes.piz)
|= [[cir=circle:hall grp=group:hall] acc=(map circle:hall (set @p))]
^- (map circle:hall (set @p))
=/ newset
%- silt %+ turn ~(tap by grp)
|= [shp=@p stat=status:hall]
shp
(~(put by acc) cir newset)
::
:-
%+ turn ~(tap in (~(del in (silt circles)) [our.bol %inbox]))
|= cir=circle:hall
^- move
=/ wir/wire /circle/[(scot %p our.bol)]/[nom.cir]/config/group
=/ pat/path /circle/[nom.cir]/config/group
[ost.bol %peer wir [our.bol %hall] pat]
::
%= this
inbox.str.sta loc.cos.piz
configs.str.sta configs
messages.str.sta (molt meslis)
peers.str.sta (~(put by peers) [our.bol %inbox] localpeers)
==
::
:: fill remote configs with message data
::
=* messages messages.str.sta
=/ circle/circle:hall [`@p`(slav %p &2:wir) &3:wir]
=/ localpeers/(set @p)
%- silt %+ turn ~(tap by loc.pes.piz)
|= [shp=@p stat=status:hall]
shp
::
=/ peers/(map circle:hall (set @p))
%- ~(rep by rem.pes.piz)
|= [[cir=circle:hall grp=group:hall] acc=(map circle:hall (set @p))]
^- (map circle:hall (set @p))
=/ newset
%- silt %+ turn ~(tap by grp)
|= [shp=@p stat=status:hall]
shp
(~(put by acc) cir newset)
~& nes.piz
=/ str
%= str.sta
messages (~(put by messages) circle nes.piz)
peers (~(uni by peers.str.sta) (~(put by peers) circle localpeers))
==
=/ messageupdate/update
:* %messages
circle
0
(lent messages)
nes.piz
==
:- (send-chat-update [messageupdate str])
this(str.sta str)
==
::
:: +diff-hall-rumor: handle updates to hall state
::
++ diff-hall-rumor
|= [wir=wire rum=rumor:hall]
^- (quip move _this)
?~ wir
(mean [leaf+"invalid wire for diff: {(spud wir)}"]~)
?+ i.wir
(mean [leaf+"invalid wire for diff: {(spud wir)}"]~)
::
:: %circles
%circles
?> ?=(%circles -.rum)
=/ cis
?: add.rum
(~(put in circles.str.sta) cir.rum)
(~(del in circles.str.sta) cir.rum)
=/ str
%= str.sta
circles cis
peers
?: add.rum
(~(put by peers.str.sta) [our.bol cir.rum] ~)
(~(del by peers.str.sta) [our.bol cir.rum])
==
:- (send-chat-update [[%circles cis] str])
this(str.sta str)
::
::
:: %circle: fill remote configs with message data
::
%circle
?> ?=(%circle -.rum)
=* sto rum.rum
?+ -.sto
[~ this]
::
:: %gram:
::
%gram
?> ?=(%gram -.sto)
=* messages messages.str.sta
=/ circle/circle:hall [`@p`(slav %p &2:wir) &3:wir]
=/ unes/(unit (list envelope:hall)) (~(get by messages) circle)
?~ unes
[~ this]
=/ nes u.unes
=/ str
%= str.sta
messages (~(put by messages) circle (snoc nes nev.sto))
==
:- (send-chat-update [[%message circle nev.sto] str])
this(str.sta str)
::
:: %status:
::
%status
?> ?=(%status -.sto)
=/ upeers/(unit (set @p)) (~(get by peers.str.sta) cir.sto)
?~ upeers
[~ this]
=/ peers/(set @p)
?: =(%remove -.dif.sto)
(~(del in u.upeers) who.sto)
(~(put in u.upeers) who.sto)
=/ str
%= str.sta
peers (~(put by peers.str.sta) cir.sto peers)
==
:- (send-chat-update [[%peers cir.sto peers] str])
this(str.sta str)
::
:: %config: config has changed
::
%config
=* circ cir.sto
::
?+ -.dif.sto
[~ this]
::
:: %full: set all of config without side effects
::
%full
=* conf cof.dif.sto
=/ str
%= str.sta
configs (~(put by configs.str.sta) circ `conf)
==
:- (send-chat-update [[%config circ conf] str])
this(str.sta str)
::
:: %read: the read count of one of our configs has changed
::
%read
?: =(circ [our.bol %inbox])
:: ignore when circ is inbox
[~ this]
=/ uconf/(unit config:hall) (~(got by configs.str.sta) circ)
?~ uconf
:: should we crash?
[~ this]
=/ conf/config:hall
%= u.uconf
red red.dif.sto
==
=/ str
%= str.sta
configs (~(put by configs.str.sta) circ `conf)
==
:- (send-chat-update [[%config circ conf] str])
this(str.sta str)
::
:: %source: the sources of our inbox have changed
::
%source
?. =(circ [our.bol %inbox])
:: ignore when circ is not inbox
[~ this]
=* affectedcir cir.src.dif.sto
=/ newwir/wire
/circle/[(scot %p hos.affectedcir)]/[nom.affectedcir]/grams/0/config/group
=/ pat/path /circle/[nom.affectedcir]/grams/0/config/group
:: we've added a source to our inbox
::
?: add.dif.sto
=/ newinbox %= inbox.str.sta
src (~(put in src.inbox.str.sta) src.dif.sto)
==
=/ str
%= str.sta
inbox newinbox
::
configs
?: (~(has by configs.str.sta) affectedcir)
configs.str.sta
(~(put by configs.str.sta) affectedcir ~)
==
::
:_ this(str.sta str)
%+ weld
[ost.bol %peer newwir [hos.affectedcir %hall] pat]~
(send-chat-update [[%inbox newinbox] str])
::
=/ newinbox %= inbox.str.sta
src (~(del in src.inbox.str.sta) src.dif.sto)
==
:: we've removed a source from our inbox
::
=/ str
%= str.sta
inbox newinbox
::
configs (~(del by configs.str.sta) affectedcir)
messages (~(del by messages.str.sta) affectedcir)
peers (~(del by peers.str.sta) affectedcir)
==
=/ fakecir/circle:hall
:- our.bol
%- crip
%+ weld (trip 'hall-internal-') (trip nom.affectedcir)
::
?~ (~(get by configs.str) fakecir)
:: just forward the delete to our clients
::
:_ this(str.sta str)
%+ weld
[ost.bol %pull newwir [hos.affectedcir %hall] ~]~
%+ weld
(send-chat-update [[%inbox newinbox] str])
(send-chat-update [[%delete affectedcir] str])
:: if we get a delete from another ship, delete our fake circle copy
::
~& %deletefake
=/ deletefake/poke
:- %hall-action
[%delete nom.fakecir ~]
:_ this(str.sta str)
%+ weld
[ost.bol %pull newwir [hos.affectedcir %hall] ~]~
%+ weld
[ost.bol %poke /fake [our.bol %hall] deletefake]~
%+ weld
(send-chat-update [[%inbox newinbox] str])
(send-chat-update [[%delete affectedcir] str])
::
==
:: end of branching on dif.sto type
==
:: end of branching on sto type
==
:: end of i.wir branching
::
:: +lient arms
::
::
:: +bound: lient tells us we successfully bound our server to the ~chat url
::
++ bound
|= [wir=wire success=? binding=binding:http-server]
^- (quip move _this)
[~ this]
::
:: +poke-handle-http-request: serve pages from file system based on URl path
::
++ poke-handle-http-request
%- (require-authorization:app ost.bol move this)
|= =inbound-request:http-server
^- (quip move _this)
::
=+ request-line=(parse-request-line url.request.inbound-request)
=/ name=@t
=+ back-path=(flop site.request-line)
?~ back-path
''
i.back-path
?: =(name 'tile')
[[ost.bol %http-response (js-response:app tile-js)]~ this]
?+ site.request-line
:_ this
[ost.bol %http-response not-found:app]~
::
:: styling
::
[%'~chat' %css %index ~]
:_ this
[ost.bol %http-response (css-response:app style)]~
::
:: javascript
::
[%'~chat' %js %index ~]
:_ this
[ost.bol %http-response (js-response:app script)]~
::
:: images
::
[%'~chat' %img *]
=/ img (as-octs:mimes:html (~(got by chat-png) `@ta`name))
:_ this
[ost.bol %http-response (png-response:app img)]~
::
:: paginated message data
::
[%'~chat' %scroll @t @t @t @t ~]
=/ cir/circle:hall [(slav %p &3:site.request-line) &4:site.request-line]
=/ start/@ud (need (rush &5:site.request-line dem))
=/ parsedend/@ud (need (rush &6:site.request-line dem))
=* messages messages.str.sta
=/ envs/(unit (list envelope:hall)) (~(get by messages) cir)
?~ envs
[~ this]
?: (gte start (lent u.envs))
[~ this]
=/ end/@
?: (gte parsedend (lent u.envs))
(dec (lent u.envs))
parsedend
=/ offset (sub end start)
=/ jon/json %- msg-to-json
:* %messages
cir
start
end
(swag [start offset] u.envs)
==
:_ this
[ost.bol %http-response (json-response:app (json-to-octs jon))]~
::
::
:: inbox page
::
[%'~chat' *]
:_ this
[ost.bol %http-response (html-response:app index)]~
==
::
::
:: +subscription-retry arms
::
::
:: +reap: recieve acknowledgement for peer, retry on failure
::
++ reap
|= [wir=wire err=(unit tang)]
^- (quip move _this)
?~ err
[~ this]
?~ wir
(mean [leaf+"invalid wire for diff: {(spud wir)}"]~)
?+ i.wir
(mean [leaf+"invalid wire for diff: {(spud wir)}"]~)
::
%circle
=/ shp/@p (slav %p &2:wir)
=/ pat /circle/[&3:wir]/config/group
?: =(&3:wir 'inbox')
:_ this
[ost.bol %peer wir [shp %hall] pat]~
?: (~(has in src.inbox.str.sta) [[shp &3:wir] ~])
:_ this
[ost.bol %peer wir [shp %hall] pat]~
[~ this]
::
%circles
:_ this
[ost.bol %peer wir [our.bol %hall] wir]~
==
::
:: +quit: subscription failed/quit at some point, retry
::
++ quit
|= wir=wire
^- (quip move _this)
?~ wir
(mean [leaf+"invalid wire for diff: {(spud wir)}"]~)
?+ i.wir
(mean [leaf+"invalid wire for diff: {(spud wir)}"]~)
::
%circle
=/ shp/@p (slav %p &2:wir)
=/ pat /circle/[&3:wir]/config/group
?: =(&3:wir 'inbox')
:_ this
[ost.bol %peer wir [shp %hall] pat]~
?: (~(has in src.inbox.str.sta) [[shp &3:wir] ~])
:_ this
[ost.bol %peer wir [shp %hall] pat]~
[~ this]
::
%circles
:_ this
[ost.bol %peer wir [our.bol %hall] wir]~
==
::
--

2
app/chat/css/index.css Normal file

File diff suppressed because one or more lines are too long

BIN
app/chat/img/Home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

BIN
app/chat/img/Icon-Home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

BIN
app/chat/img/Send.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

BIN
app/chat/img/Tile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

16
app/chat/index.html Normal file
View File

@ -0,0 +1,16 @@
<!doctype html>
<html>
<head>
<title>Chat</title>
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<link rel="stylesheet" href="/~chat/css/index.css" />
</head>
<body>
<div id="root" />
<script src="/~/channel/channel.js"></script>
<script src="/~modulo/session.js"></script>
<script src="/~chat/js/index.js"></script>
</body>
</html>

58098
app/chat/js/index.js Normal file

File diff suppressed because one or more lines are too long

19399
app/chat/js/tile.js Normal file

File diff suppressed because it is too large Load Diff

79
app/clock.hoon Normal file
View File

@ -0,0 +1,79 @@
/+ *server
/= tile-js
/^ octs
/; as-octs:mimes:html
/: /===/app/clock/js/tile
/| /js/
/~ ~
==
=, format
::
|%
:: +move: output effect
::
+$ move [bone card]
:: +card: output effect payload
::
+$ poke
$% [%noun [@tas path @t]]
==
::
+$ card
$% [%poke wire dock poke]
[%http-response =http-event:http]
[%connect wire binding:http-server term]
[%diff %json json]
==
::
--
::
|_ [bol=bowl:gall ~]
::
++ this .
::
++ bound
|= [wir=wire success=? binding=binding:http-server]
^- (quip move _this)
[~ this]
::
++ prep
|= old=(unit ~)
^- (quip move _this)
=/ launchnoun [%noun [%clock /tile '/~clock/js/tile.js']]
:_ this
:~
[ost.bol %connect / [~ /'~clock'] %clock]
[ost.bol %poke /clock [our.bol %launch] launchnoun]
==
::
++ peer-tile
|= pax=path
^- (quip move _this)
[[ost.bol %diff %json *json]~ this]
::
++ send-tile-diff
|= jon=json
^- (list move)
%+ turn (prey:pubsub:userlib /tile bol)
|= [=bone ^]
[bone %diff %json jon]
::
++ poke-handle-http-request
%- (require-authorization:app ost.bol move this)
|= =inbound-request:http-server
^- (quip move _this)
=/ request-line (parse-request-line url.request.inbound-request)
=/ back-path (flop site.request-line)
=/ name=@t
=/ back-path (flop site.request-line)
?~ back-path
''
i.back-path
::
?~ back-path
[[ost.bol %http-response not-found:app]~ this]
?: =(name 'tile')
[[ost.bol %http-response (js-response:app tile-js)]~ this]
[[ost.bol %http-response not-found:app]~ this]
::
--

2379
app/clock/js/tile.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2535,14 +2535,16 @@
%+ murn ~(tap by stories)
|= {n/name s/story}
^- (unit (pair name burden))
:: don't federate channels
~
:: only auto-federate channels for now.
?. ?=($channel sec.con.shape.s) ~
:+ ~ n
:: share no more than the last 100, for performance reasons.
:+ ?: (lte count.s 100) grams.s
(slag (sub count.s 100) grams.s)
[shape.s mirrors.s]
[locals.s remotes.s]
::?. ?=($channel sec.con.shape.s) ~
:::+ ~ n
:::: share no more than the last 100, for performance reasons.
:::+ ?: (lte count.s 100) grams.s
:: (slag (sub count.s 100) grams.s)
:: [shape.s mirrors.s]
::[locals.s remotes.s]
::
$report
::TODO gall note: need to be able to subscirbe to just changes... or just
@ -2769,6 +2771,7 @@
==
==
::
::
++ affection
:: rumors to interested
::
@ -2780,19 +2783,35 @@
^- (list move)
:: cache results for paths.
=| res/(map path (list move))
%- zing
%+ turn ~(tap by sup.bol)
|= {b/bone s/ship p/path}
^- (list move)
=+ mur=(~(get by res) p)
?^ mur u.mur
=- =. res (~(put by res) p -)
-
=+ qer=(path-to-query p)
%+ welp
=+ rum=(feel qer det)
?~ rum ~
[b %diff %hall-rumor u.rum]~
%- zing
%+ turn ~(tap by sup.bol)
|= {b/bone s/ship p/path}
^- (list move)
=+ mur=(~(get by res) p)
?^ mur u.mur
=- =. res (~(put by res) p -)
-
=+ qer=(path-to-query p)
%+ welp
=+ rum=(feel qer det)
?~ rum ~
?: ?&
?=(%burden -.u.rum)
?=(%config -.rum.u.rum)
?=(%read -.dif.rum.u.rum)
==
:: don't send read burdens
~
?: ?&
?!(=(s our.bol))
?=(%circle -.u.rum)
?=(%config -.rum.u.rum)
?=(%read -.dif.rum.u.rum)
==
:: don't send read circle events to other ships
~
[b %diff %hall-rumor u.rum]~
?. ?=($circle -.qer) ~
:: kill the subscription if we forgot the story.
?. (~(has by stories) nom.qer) (gentle-quit b s qer)

View File

@ -1,260 +0,0 @@
/+ *server, collections
/= index
/: /===/app/landscape/index /!noun/
/= script
/^ octs
/; as-octs:mimes:html
/: /===/app/landscape/js/index-min
/| /js/
/~ ~
==
/= style
/^ octs
/; as-octs:mimes:html
/: /===/app/landscape/css/index
/| /css/
/~ ~
==
/= profile
/: /===/app/landscape/profile /!noun/
/= inbox
/: /===/app/landscape/inbox /!noun/
/= stream
/: /===/app/landscape/stream /!noun/
/= coll-elem
/: /===/app/landscape/collections/elem /!noun/
/= coll-new
/: /===/app/landscape/collections/new /!noun/
::
|%
::
+$ move [bone card]
::
+$ card
$% [%http-response =http-event:http]
[%connect wire binding:http-server term]
[%peer wire dock path]
[%diff diff]
[%quit ~]
==
+$ diff
$% [%hymn manx]
[%json json]
==
::
--
::
|_ [bol=bowl:gall ~]
::
++ this .
::
++ prep
|= old=(unit ~)
^- (quip move _this)
?~ old
:_ this
[ost.bol %connect / [~ /'~landscape'] %landscape]~
[~ this]
::
++ bound
|= [wir=wire success=? binding=binding:http-server]
^- (quip move _this)
[~ this]
::
++ peer-xship
|= wir=wire
^- (quip move _this)
?+ wir
!! :: XX should we really crash on data sent from another ship?
::
[%top @t *]
=/ jon=? =(t.t.wir [%json ~])
=/ dif=diff (coll-elem our.bol (slav %da i.t.wir) ~ jon)
:_ this
:~ [ost.bol %diff dif]
[ost.bol %quit ~]
==
::
[%new @t *]
=/ jon=? =(t.t.wir [%json ~])
=/ pos [*@da %new]
=/ dif=diff (coll-elem our.bol (slav %da i.t.wir) `pos jon)
:_ this
:~ [ost.bol %diff dif]
[ost.bol %quit ~]
==
::
[%view @t @t *]
=/ jon=? =(t.t.t.wir [%json ~])
=/ pos [(slav %da i.t.t.wir) %default]
=/ dif=diff (coll-elem our.bol (slav %da i.t.wir) `pos jon)
:_ this
:~ [ost.bol %diff dif]
[ost.bol %quit ~]
==
::
[%edit @t @t *]
=/ jon=? =(t.t.t.wir [%json ~])
=/ pos [(slav %da i.t.t.wir) %edit]
=/ dif=diff (coll-elem our.bol (slav %da i.t.wir) `pos jon)
:_ this
:~ [ost.bol %diff dif]
[ost.bol %quit ~]
==
==
::
++ diff-hymn
|= [wir=wire hym=manx]
^- (quip move _this)
:_ this
[ost.bol %http-response (html-response:app (manx-to-octs (index hym)))]~
::
++ poke-handle-http-request
%- (require-authorization:app ost.bol move this)
|= =inbound-request:http-server
^- (quip move _this)
::
=+ request-line=(parse-request-line url.request.inbound-request)
?+ site.request-line
:_ this
[ost.bol %http-response not-found:app]~
::
:: inbox page
::
[%'~landscape' ~]
=/ index-html=octs (manx-to-octs (index inbox))
:_ this
[ost.bol %http-response (html-response:app index-html)]~
::
:: styling
::
[%'~landscape' %css ~]
:_ this
[ost.bol %http-response (css-response:app style)]~
::
:: javascript
::
[%'~landscape' %js ~]
:_ this
[ost.bol %http-response (js-response:app script)]~
::
:: profile page
::
[%'~landscape' %profile @t ~]
=/ profile-html=octs
(manx-to-octs (index (profile i.t.t.site.request-line)))
:_ this
[ost.bol %http-response (html-response:app profile-html)]~
::
:: chat page
::
[%'~landscape' %stream ~]
=/ stream-html=octs (manx-to-octs (index stream))
:_ this
[ost.bol %http-response (html-response:app stream-html)]~
::
:: collections top level page
::
[%'~landscape' %collections @t @t ~]
=/ shp=@p (slav %p i.t.t.site.request-line)
=/ col=@da (slav %da i.t.t.t.site.request-line)
?: =(shp our.bol)
:: local request
::
=/ jon=? =(ext.request-line [~ ~.json])
=/ dif=diff (coll-elem shp col ~ jon)
?- -.dif
%hymn
=/ oct=octs (manx-to-octs (index +.dif))
:_ this
[ost.bol %http-response (html-response:app oct)]~
::
%json
=/ oct=octs (json-to-octs +.dif)
:_ this
[ost.bol %http-response (json-response:app oct)]~
==
:: foreign request
::
?: =(ext.request-line [~ ~.json])
:: json format
::
=/ pax=path /xship/top/(scot %da col)/json
:_ this
[ost.bol %peer pax [shp %landscape] pax]~
::
:: html format
=/ pax=path /xship/top/(scot %da col)
:_ this
[ost.bol %peer pax [shp %landscape] pax]~
::
:: collections new post page
::
[%'~landscape' %collections @t @t %new ~]
=/ shp=@p (slav %p i.t.t.site.request-line)
=/ col=@da (slav %da i.t.t.t.site.request-line)
?: =(shp our.bol)
=/ dif=diff (coll-elem shp col `[*@da %new] |)
?> ?=(%hymn -.dif)
=/ new-html=octs
(manx-to-octs (index +.dif))
:_ this
[ost.bol %http-response (html-response:app new-html)]~
=/ pax=path /xship/new/(scot %da col)
:_ this
[ost.bol %peer pax [shp %landscape] pax]~
::
:: collections view post page
::
[%'~landscape' %collections @t @t @t ~]
=/ shp=@p (slav %p i.t.t.site.request-line)
=/ col=@da (slav %da i.t.t.t.site.request-line)
=/ pos=@da (slav %da i.t.t.t.t.site.request-line)
?: =(shp our.bol)
=/ jon=? =(ext.request-line [~ ~.json])
=/ dif=diff (coll-elem shp col `[pos %default] jon)
?- -.dif
%hymn
=/ oct=octs (manx-to-octs (index +.dif))
:_ this
[ost.bol %http-response (html-response:app oct)]~
::
%json
=/ oct=octs (json-to-octs +.dif)
:_ this
[ost.bol %http-response (json-response:app oct)]~
==
:: foreign request
::
?: =(ext.request-line [~ ~.json])
:: json format
::
=/ pax=path /xship/view/(scot %da col)/(scot %da pos)/json
:_ this
[ost.bol %peer pax [shp %landscape] pax]~
::
:: html format
=/ pax=path /xship/view/(scot %da col)/(scot %da pos)
:_ this
[ost.bol %peer pax [shp %landscape] pax]~
::
:: collections edit post page
::
[%'~landscape' %collections @t @t @t %edit ~]
=/ shp=@p (slav %p i.t.t.site.request-line)
=/ col=@da (slav %da i.t.t.t.site.request-line)
=/ pos=@da (slav %da i.t.t.t.t.site.request-line)
?: =(shp our.bol)
=/ dif=diff (coll-elem shp col `[pos %edit] |)
?> ?=(%hymn -.dif)
=/ edit-html=octs
(manx-to-octs (index +.dif))
:_ this
[ost.bol %http-response (html-response:app edit-html)]~
=/ pax=path /xship/edit/(scot %da col)/(scot %da pos)
:_ this
[ost.bol %peer pax [shp %landscape] pax]~
::
==
::
--

View File

@ -1,14 +0,0 @@
::
::::
::
|= [shp=@p col=@da pos=@da dat=@t]
^- manx
;div.container
;div
=urb-component "TopicCreatePage"
=urb-ship "{<shp>}"
=urb-claypath "{<col>}"
=urb-content (trip dat)
;input(type "hidden", name "urb-header", value "collection-write", station "query");
==
==

View File

@ -1,344 +0,0 @@
::
::::
::
/? 309
/+ collections, cram
/= coll-new
/: /===/app/landscape/collections/new /!noun/
/= coll-edit
/: /===/app/landscape/collections/edit /!noun/
/= cols
/^ collection:collections
/; |= a=(map knot item:collections)
[*config:collections a]
/: /===/web/collections /_ /collections-item/
::
::
|%
+$ post-page [p=@da q=?(%default %edit %new)]
--
|= [shp=@p col=@da pos=(unit post-page) json=?]
^- $% [%hymn manx]
[%json ^json]
==
=/ itm=(unit item:collections) (~(get by data.cols) (scot %da col))
?: json
?~ itm [%json ~]
[%json (item-to-json:collections u.itm)]
?~ itm
[%hymn ;div:(Invalid collection)]
=< [%hymn (item-to-elem u.itm)]
|%
++ item-to-elem
!:
|= itm=item:collections
?~ pos
?> ?=(%collection -.itm)
^- manx
;div.container
;div.row
;div.flex-col-2;
;div.flex-col-x
;div.collection-index
;+ (meta-to-elem itm)
;+ (collection-to-elem col.itm)
==
==
;+ ?: =(type.meta.col.itm %blog)
;div.flex-col-5;
?: =(type.meta.col.itm %fora)
;div.flex-col-4;
;div.flex-col-4;
==
==
::
::
?> ?=(%collection -.itm)
=/ posttt=(unit item:collections) (~(get by data.col.itm) (scot %da p.u.pos))
?: ?&(?=(~ posttt) !=(q.u.pos %new))
;div: Invalid collection
^- manx
?- q.u.pos
%default
?< ?=(~ posttt)
?> ?=(%both -.u.posttt)
;div.container
;div.row
;div.flex-col-2;
;div.flex-col-x
;div.collection-index
;+ (meta-to-elem u.posttt)
;+ (both-to-elem col.u.posttt raw.u.posttt)
==
==
;div.flex-col-2;
==
==
::
%edit
?< ?=(~ posttt)
?> ?=(%both -.u.posttt)
=/ dat data.raw.u.posttt
;div.row
;div.flex-col-2;
;div.flex-col-x
;div.collection-index
;+ (meta-to-elem u.posttt)
;+ (coll-edit shp col p.u.pos dat)
==
==
;div.flex-col-2;
==
::
%new
;div.row
;div.flex-col-2;
;div.flex-col-x
;div.collection-index
;+ (meta-to-elem itm)
;+ (coll-new shp col)
==
==
;div.flex-col-2;
==
==
::
++ collection-to-elem
|= col=collection:collections
^- manx
;ul.vanilla
;* %+ roll
%+ sort ~(tap by data.col)
|= [[knot a=item:collections] [knot b=item:collections]]
=/ a-dat (extract-date-created a)
=/ b-dat (extract-date-created b)
(lth a-dat b-dat)
|= [[nom=knot ite=item:collections] out=marl]
^- marl
?: ?=(%error -.ite)
out
:_ out
^- manx
;li.collection-post.mt-6
;+ (item-to-snip nom ite)
==
==
::
++ raw-to-elem
|= raw=raw-item:collections
^- manx
=/ elm elm:(static:cram (ream data.raw))
=/ ht (hedtal:collections +.elm)
=/ title (fall (~(get by meta.raw) %name) /spur)
=/ date (fall (~(get by meta.raw) %date-created) 'missing date')
=/ author (fall (~(get by meta.raw) %author) 'anonymous')
::
;div.mb-18.mt-4
;+ elm
==
::
++ both-to-elem
|= [col=collection:collections raw=raw-item:collections]
^- manx
;div
;+ (raw-to-elem raw)
::
;div
;div.flex.align-center.mb-5
;div(urb-component "IconComment");
;div.ml-2.text-small.text-mono.text-600: {<~(wyt by data.col)>}
==
::
;ul.vanilla
;* %+ turn
%+ sort ~(tap by data.col)
|= [[knot a=item:collections] [knot b=item:collections]]
=/ a-dat (extract-date-created a)
=/ b-dat (extract-date-created b)
(lte a-dat b-dat)
|= [nom=knot ite=item:collections]
^- manx
?> ?=(%raw -.ite)
=/ author (fall (~(get by meta.raw.ite) %author) 'anonymous')
=/ host (fall (~(get by meta.raw.ite) %host) 'anonymous')
=/ date (fall (~(get by meta.raw.ite) %date-created) 'missing date')
;li.mb-6
;div.flex.align-center
;div.mr-2
=urb-component "Sigil"
=urb-ship "{(trip author)}"
=urb-size "18"
=urb-suffix "true";
;div
;a.vanilla.text-mono.text-small.text-700.mr-4
=href "/~~/{(trip host)}/==/web/landscape/profile"
; {(trip author)}
==
==
;div.text-host-breadcrumb
=urb-component "Elapsed"
=urb-timestring "{(trip date)}";
==
;div.collection-comment-content
;+ elm:(static:cram (ream data.raw.ite))
==
==
==
::
;div
=urb-component "CommentCreate"
=urb-pax "{<(flop /spur)>}"
=urb-ship "{<shp>}";
==
==
::
++ extract-date-created
|= i=item:collections
^- @da
?- -.i
%error *@da
%collection date-created.meta.col.i
%both date-created.meta.col.i
%raw (slav %da (~(got by meta.raw.i) %date-created))
==
::
::
::
++ item-to-snip
|= [nom=knot itm=item:collections]
^- manx
?- -.itm
%error
;div: Invalid collection
%collection
(collection-to-snip nom col.itm)
%raw
(raw-to-snip nom raw.itm)
%both
(both-to-snip nom col.itm raw.itm)
==
::
++ collection-to-snip
|= [nom=knot col=collection:collections]
^- manx
=/ lnk=tape
"/~landscape/collections/{<shp>}/{(scow %p p.full-path.meta.col)}/{(spud (flop (slag 1 s.full-path.meta.col)))}"
;div
;div.collection-date: {<date-created.meta.col>}
;h2.mt-0.mb-0
;a(href lnk): {(trip name.meta.col)}
==
;div.who.text-mono.text-600: {<author.meta.col>}
;div.meta-cont
;div.com-count.ml-12
; {(trip (scot %ud ~(wyt by data.col)))} comments
==
==
==
::
++ raw-to-snip
|= [nom=knot raw=raw-item:collections]
^- manx
=/ elm=manx elm:(static:cram (ream data.raw))
=/ ht (hedtal:collections +.elm)
=? tal.ht ?=(~ hed.ht)
(scag 5 c.elm)
=/ title (fall (~(get by meta.raw) %name) nom)
=/ date (fall (~(get by meta.raw) %date-created) 'missing date')
=/ author (fall (~(get by meta.raw) %author) 'anonymous')
=/ lnk=tape
"/~landscape/collections/{<shp>}/{(scow %da col)}/{(trip nom)}"
::
;div
;div.collection-date: {(trip date)}
;h2
;+ ?~ hed.ht
;a(href lnk): {(trip title)}
;a(href lnk): *{hed.ht}
==
;div.who.text-mono.text-600: {(trip author)}
;div.snippet
;* tal.ht
==
==
::
++ both-to-snip
|= [nom=knot col=collection:collections raw=raw-item:collections]
^- manx
=/ elm=manx elm:(static:cram (ream data.raw))
=/ ht (hedtal:collections +.elm)
=? tal.ht ?=(~ hed.ht)
(scag 5 c.elm)
=/ title (fall (~(get by meta.raw) %name) nom)
=/ lnk=tape
"/~landscape/collections/{<shp>}/{(scow %da ^col)}/{(trip nom)}"
::
;div
;div.collection-date: {<date-created.meta.col>}
;h2.mt-0.mb-0.text-500
;+ ?~ hed.ht
;a(href lnk): {(trip title)}
;a(href lnk): *{hed.ht}
==
;div.text-mono.text-small.text-300.mt-1.mb-1: {<author.meta.col>}
;div
;div.icon-label.justify-start
;div(urb-component "IconComment");
;div.ml-2
; {(trip (scot %ud ~(wyt by data.col)))}
==
==
==
==
::
++ meta-to-elem
|= itm=item:collections
^- manx
=/ mat=mart
:~ [%type "hidden"]
[%name "urb-metadata"]
==
:_ ~
:- %input
%+ weld mat
^- mart
?- -.itm
%error ~
%collection
=* met meta.col.itm
:~ [%urb-name (trip name.met)]
[%urb-author (scow %p author.met)]
[%urb-host (scow %p p.full-path.met)]
[%urb-date-created (scow %da date-created.met)]
[%urb-last-modified (scow %da last-modified.met)]
[%urb-content-type (trip type.met)]
[%urb-structure-type "collection-index"]
[%urb-path (spud /web/collections/(scot %da date-created.meta.col.itm))]
[%urb-show "default"]
==
%raw
=/ met ~(got by meta.raw.itm)
:~ [%urb-name (trip (met %name))]
[%urb-author (trip (met %author))]
[%urb-host (trip (met %host))]
[%urb-date-created (trip (met %date-created))]
[%urb-last-modified (trip (met %last-modified))]
[%urb-content-type (trip (met %type))]
[%urb-structure-type "collection-post"]
[%urb-path (spud (flop /web/collections/raw))]
[%urb-show "default"]
==
%both
=/ met ~(got by meta.raw.itm)
:~ [%urb-name (trip (met %name))]
[%urb-author (trip (met %author))]
[%urb-host (trip (met %host))]
[%urb-date-created (trip (met %date-created))]
[%urb-last-modified (trip (met %last-modified))]
[%urb-content-type (trip (met %type))]
[%urb-structure-type "collection-post"]
[%urb-path (spud (flop /web/collections/both))]
[%urb-show "default"]
==
==
--

View File

@ -1,18 +0,0 @@
::
::::
::
|= [shp=@p col=@da]
^- manx
;div.container
;div
=urb-component "TopicCreatePage"
=urb-ship "{<shp>}"
=urb-claypath "{<col>}"
=urb-content "";
;input
=type "hidden"
=name "urb-header"
=value "collection-post-default"
=station "query"
=urb-structure-type "collection-index";
==

File diff suppressed because one or more lines are too long

View File

@ -1,5 +0,0 @@
^- manx
;div
;div(urb-component "InboxPage");
;input(type "hidden", name "urb-metadata", urb-structure-type "header-inbox");
==

File diff suppressed because one or more lines are too long

View File

@ -1,26 +0,0 @@
|= who=@t
^- manx
;div
;input(type "hidden", name "urb-metadata", urb-structure-type "header-profile", urb-author "{(trip who)}");
;div.container
;div.row
;div.flex-col-2;
;div.flex-col-x
;div.profile-avatar
;div(urb-component "Sigil", urb-size "320", urb-ship "{(trip who)}", urb-suffix "false");
;div(urb-component "ProfileMsgBtn", urb-ship "{(trip who)}");
==
==
==
;div.row.mt-9
;div.flex-offset-2.flex-col-x
;h2.text-500: Meta
==
==
;div.row.mt-4.align-center
;div.flex-col-2;
;h3.text-500.flex-col-1.mt-0: Started:
;div.flex-col-x.text-mono: ~2018.4.12..6.45.12
==
==
==

View File

@ -1,6 +0,0 @@
^- manx
;div.chat-container
;div.chat-container-inner(urb-component "ChatPage");
;input(type "hidden", name "urb-metadata", urb-structure-type "stream-chat");
==

View File

@ -1,6 +0,0 @@
^- manx
;div
;div(urb-component "WelcomePage");
;input(type "hidden", name "urb-metadata", urb-structure-type "welcome");
==

151
app/launch.hoon Normal file
View File

@ -0,0 +1,151 @@
/+ *server, collections
/= index
/^ $-(marl manx)
/: /===/app/launch/index /!noun/
/= script
/^ octs
/; as-octs:mimes:html
/: /===/app/launch/js/index
/| /js/
/~ ~
==
/= style
/^ octs
/; as-octs:mimes:html
/: /===/app/launch/css/index
/| /css/
/~ ~
==
/= launch-png
/^ (map knot @)
/: /===/app/launch/img /_ /png/
::
|%
::
+$ move [bone card]
::
+$ card
$% [%http-response =http-event:http]
[%connect wire binding:http-server term]
[%peer wire dock path]
[%diff %json json]
==
+$ tile [name=@tas subscribe=path]
+$ tile-data (map @tas [jon=json url=@t])
+$ state
$% [%0 tiles=(set tile) data=tile-data path-to-tile=(map path @tas)]
==
::
--
::
|_ [bol=bowl:gall sta=state]
::
++ this .
::
++ prep
|= old=(unit state)
^- (quip move _this)
~& 'launch prep'
?~ old
:_ this
[ost.bol %connect / [~ /] %launch]~
[~ this(sta u.old)]
::
++ bound
|= [wir=wire success=? binding=binding:http-server]
^- (quip move _this)
[~ this]
::
++ poke-noun
|= [name=@tas subscribe=path url=@t]
^- (quip move _this)
=/ beforedata (~(get by data.sta) name)
=/ newdata
?~ beforedata
(~(put by data.sta) name [*json url])
(~(put by data.sta) name [jon.u.beforedata url])
:- [ost.bol %peer subscribe [our.bol name] subscribe]~
%= this
tiles.sta (~(put in tiles.sta) [name subscribe])
data.sta newdata
path-to-tile.sta (~(put by path-to-tile.sta) subscribe name)
==
::
++ diff-json
|= [pax=path jon=json]
^- (quip move _this)
=/ name/@tas (~(got by path-to-tile.sta) pax)
=/ data/(unit [json url=@t]) (~(get by data.sta) name)
?~ data
[~ this]
::
:-
%+ turn (prey:pubsub:userlib /main bol)
|= [=bone *]
[bone %diff %json (frond:enjs:format name jon)]
::
%= this
data.sta (~(put by data.sta) name [jon url.u.data])
==
::
++ peer-main
|= [pax=path]
^- (quip move _this)
=/ data/json
%- pairs:enjs:format
%+ turn ~(tap by data.sta)
|= [key=@tas [jon=json url=@t]]
[key jon]
:_ this
[ost.bol %diff %json data]~
::
++ generate-script-marl
|= data=tile-data
^- marl
%+ turn ~(tap by data)
|= [key=@tas [jon=json url=@t]]
^- manx
;script@"{(trip url)}";
::
++ poke-handle-http-request
%- (require-authorization:app ost.bol move this)
|= =inbound-request:http-server
^- (quip move _this)
::
=+ request-line=(parse-request-line url.request.inbound-request)
=/ name=@t
=+ back-path=(flop site.request-line)
?~ back-path
''
i.back-path
=/ site (flop site.request-line)
?~ site
=/ hym=manx (index (generate-script-marl data.sta))
:_ this
[ost.bol %http-response (manx-response:app hym)]~
?+ site.request-line
:_ this
[ost.bol %http-response not-found:app]~
::
:: styling
::
[%'~launch' %css %index ~]
:_ this
[ost.bol %http-response (css-response:app style)]~
::
:: javascript
::
[%'~launch' %js %index ~]
:_ this
[ost.bol %http-response (js-response:app script)]~
::
:: images
::
[%'~launch' %img *]
=/ img (as-octs:mimes:html (~(got by launch-png) `@ta`name))
:_ this
[ost.bol %http-response (png-response:app img)]~
==
::
--

2
app/launch/css/index.css Normal file

File diff suppressed because one or more lines are too long

BIN
app/launch/img/Home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

View File

@ -1,22 +1,18 @@
|= inner=manx
^- manx
|= scripts=marl
;html
::
;head
;title: Landscape
;title: Home
;meta(charset "utf-8");
;meta
=name "viewport"
=content "width=device-width, initial-scale=1, shrink-to-fit=no";
;link(rel "stylesheet", href "/~landscape/css.css");
;script@"/~/channel/channel.js";
;script@"/session.js";
;link(rel "stylesheet", href "/~launch/css/index.css");
==
::
;body
;div#root
;+ inner
==
;script@"/~landscape/js.js";
;div#root;
;script@"/~/channel/channel.js";
;script@"/~modulo/session.js";
;* scripts
;script@"/~launch/js/index.js";
==
==

18
app/launch/index.html Normal file
View File

@ -0,0 +1,18 @@
|= scripts=marl
<!doctype html>
<html>
<head>
<title>Home</title>
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<link rel="stylesheet" href="/~launch/css/index.css" />
</head>
<body>
<div id="root" />
<script src="/~/channel/channel.js"></script>
<script src="/~modulo/session.js"></script>
<script src="/~launch/js/tiles.js"></script>
<script src="/~launch/js/index.js"></script>
</body>
</html>

49172
app/launch/js/index.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,4 @@
/- *modulo
/+ *server
/= index
/^ octs
/; as-octs:mimes:html
/: /===/app/modulo/index
/| /html/
/~ ~
==
/= modulo-js
/^ octs
/; as-octs:mimes:html
/: /===/app/modulo/script
/| /js/
/~ ~
==
=, format
|%
:: +move: output effect
::
@ -23,44 +7,13 @@
::
+$ card
$% [%connect wire binding:http-server term]
[%serve wire binding:http-server generator:http-server]
[%disconnect wire binding:http-server]
[%http-response =http-event:http]
[%poke wire dock poke]
[%diff %json json]
==
+$ poke
$% [%modulo-bind app=term]
[%modulo-unbind app=term]
==
::
+$ state
$% $: %0
session=(map term @t)
order=(list term)
cur=(unit [term @])
==
==
::
++ session-as-json
|= [cur=(unit [term @]) session=(map term @t) order=(list term)]
^- json
?~ cur
*json
%- pairs:enjs
:~ [%app %s -.u.cur]
[%url %s (~(got by session) -.u.cur)]
:- %list
:- %a
%+ turn order
|= [a=term]
[%s a]
==
::
--
::
|_ [bow=bowl:gall sta=state]
|_ [bow=bowl:gall ~]
::
++ this .
::
@ -69,7 +22,7 @@
^- (quip move _this)
?~ old
:_ this
[ost.bow %connect / [~ /] %modulo]~
[ost.bow %connect / [~ /'~modulo'] %modulo]~
[~ this]
::
:: alerts us that we were bound. we need this because the vane calls back.
@ -79,34 +32,13 @@
^- (quip move _this)
[~ this]
::
++ peer-applist
|= [pax=path]
^- (quip move _this)
:_ this
[ost.bow %diff %json (session-as-json cur.sta session.sta order.sta)]~
::
++ session-js
^- octs
:: ?~ cur.sta
:: *octs
%- as-octt:mimes:html
;: weld
:: (trip 'window.onload = function() {')
"window.ship = '{+:(scow %p our.bow)}';"
"window.urb = new Channel();"
==
:: (trip '};')
:: ==
:: " window.state = "
:: (en-json:html (session-as-json cur.sta session.sta order.sta))
:: (trip '}();')
:: %- trip
:: '''
:: document.onkeydown = (event) => {
:: if (!event.metaKey || event.keyCode !== 75) { return; }
:: window.parent.postMessage("commandPalette", "*");
:: };
:: '''
::
:: +poke-handle-http-request: received on a new connection established
::
@ -114,99 +46,6 @@
%- (require-authorization:app ost.bow move this)
|= =inbound-request:http-server
^- (quip move _this)
::
=/ request-line (parse-request-line url.request.inbound-request)
=/ site (flop site.request-line)
?~ site
[[ost.bow %http-response (redirect:app '~landscape')]~ this]
?+ site
[[ost.bow %http-response (html-response:app index)]~ this]
[%session *]
[[ost.bow %http-response (js-response:app session-js)]~ this]
[%script *]
[[ost.bow %http-response (js-response:app modulo-js)]~ this]
==
:: +poke-handle-http-cancel: received when a connection was killed
::
++ poke-handle-http-cancel
|= =inbound-request:http-server
^- (quip move _this)
:: the only long lived connections we keep state about are the stream ones.
::
[~ this]
::
++ poke-modulo-bind
|= bin=term
^- (quip move _this)
=/ url (crip "~{(scow %tas bin)}")
?: (~(has by session.sta) bin)
[~ this]
:- [`move`[ost.bow %connect / [~ /[url]] bin] ~]
%= this
session.sta
(~(put by session.sta) bin url)
::
order.sta
(weld order.sta ~[bin])
::
cur.sta
?~ cur.sta `[bin 0]
cur.sta
==
::
++ poke-modulo-unbind
|= bin=term
^- (quip move _this)
=/ url (crip "~{(scow %tas bin)}")
?. (~(has by session.sta) bin)
[~ this]
=/ ind (need (find ~[bin] order.sta))
=/ neworder (oust [ind 1] order.sta)
:- [`move`[ost.bow %disconnect / [~ /(crip "~{(scow %tas bin)}")]] ~]
%= this
session.sta (~(del by session.sta) bin)
order.sta neworder
cur.sta
::
?: =(1 (lent order.sta))
~
?: (lth ind +:(need cur.sta))
`[-:(need cur.sta) (dec +:(need cur.sta))]
?: =(ind +:(need cur.sta))
`[(snag 0 neworder) 0]
cur.sta
==
::
++ poke-modulo-command
|= com=command
^- (quip move _this)
=/ length (lent order.sta)
?~ cur.sta
[~ this]
?: =(length 1)
[~ this]
=/ new-cur=(unit [term @])
?- -.com
%forward
?: =((dec length) +.u.cur.sta)
`[(snag 0 order.sta) 0]
=/ ind +(+.u.cur.sta)
`[(snag ind order.sta) ind]
%back
?: =(0 +.u.cur.sta)
=/ ind (dec length)
`[(snag ind order.sta) ind]
=/ ind (dec +.u.cur.sta)
`[(snag ind order.sta) ind]
%go
=/ ind (find [app.com]~ order.sta)
?~ ind
cur.sta
`[app.com u.ind]
==
:_ this(cur.sta new-cur)
%+ turn (prey:pubsub:userlib /applist bow)
|= [=bone ^]
[bone %diff %json (session-as-json new-cur session.sta order.sta)]
[[ost.bow %http-response (js-response:app session-js)]~ this]
::
--

View File

@ -1,28 +0,0 @@
<!doctype html>
<html>
<head>
<script type="application/javascript" src="~/channel/channel.js"></script>
<script type="application/javascript" src="/session.js"></script>
<style type="text/css">
.command-palette {
position: relative;
background-color: #f6f6f6;
top:10%;
left:10%;
width: 80%;
border: none;
outline: none;
height: 48px;
font-size: 20px;
line-height: 48px;
}
</style>
</head>
<body>
<div id="frame"></div>
<div id="popup" style="display:hidden;">
<input id="input" class="command-palette" type="text" style="visibility:hidden !important;" />
</div>
<script type="application/javascript" src="/script.js"></script>
</body>
</html>

View File

@ -1,69 +0,0 @@
function setFrame() {
let iframe = document.createElement('iframe');
iframe.setAttribute('src', window.state.url);
iframe.setAttribute('width', '100%;');
iframe.setAttribute('height', '100%;');
iframe.setAttribute('style', 'border-style: none !important;');
let inner = document.getElementById("frame");
inner.innerHTML = "";
inner.appendChild(iframe);
iframe.focus();
}
function doSub() {
window.urb.subscribe(window.ship, "modulo", "/applist",
(err) => {
console.log(err);
},
(event) => {
console.log(event);
window.state = event;
setFrame();
},
() => {
doSub();
}
);
}
var palette = false;
window.addEventListener("message", (event) => {
let popup = document.getElementById("popup");
let input = document.getElementById("input");
if (palette) {
palette = false;
popup.style = "display:hidden;";
input.style = "visibility:hidden !important;";
input.value = "";
} else {
palette = true;
popup.style = "position:absolute; left: 0; top: 0; display:block; width: 100%; height: 100%; margin: 0 0; background-color:white;";
input.style = "";
input.focus();
input.addEventListener("keyup", (e) => {
if (e.keyCode !== 13) { return; }
popup.style = "display:hidden;";
popup.style = "visibility:hidden !important;";
window.urb.poke(window.ship, "modulo", "modulo-command",
{
go: input.value
},
(json) => {
console.log(json);
},
(err) => {
console.log(err);
}
);
});
}
});
setFrame();
doSub();

View File

@ -1933,7 +1933,7 @@
"cap: {(trip cap.dif)}"
::
$read
"red: {(scow %ud red.dif)}"
""
::
$filter
;: weld

122
app/timer.hoon Normal file
View File

@ -0,0 +1,122 @@
/+ *server
/= tile-js
/^ octs
/; as-octs:mimes:html
/: /===/app/timer/js/tile
/| /js/
/~ ~
==
/= timer-png
/^ (map knot @)
/: /===/app/timer/img /_ /png/
=, format
::
|%
:: +move: output effect
::
+$ move [bone card]
:: +card: output effect payload
::
+$ poke
$% [%noun [@tas path @t]]
==
::
+$ card
$% [%poke wire dock poke]
[%http-response =http-event:http]
[%connect wire binding:http-server term]
[%diff %json json]
[%wait wire @da]
[%rest wire @da]
==
::
--
::
|_ [bol=bowl:gall tim=@da]
::
++ this .
::
++ bound
|= [wir=wire success=? binding=binding:http-server]
^- (quip move _this)
[~ this]
::
++ prep
|= old=(unit tim=@da)
^- (quip move _this)
=/ launchnoun [%noun [%timer /tile '/~timer/js/tile.js']]
:-
:~
[ost.bol %connect / [~ /'~timer'] %timer]
[ost.bol %poke /timer [our.bol %launch] launchnoun]
==
?~ old
this
%= this
tim tim.u.old
==
::
++ peer-tile
|= pax=path
^- (quip move _this)
?: =(tim *@da)
[[ost.bol %diff %json [%s '']]~ this]
[[ost.bol %diff %json [%s (scot %da tim)]]~ this]
::
++ send-tile-diff
|= jon=json
^- (list move)
%+ turn (prey:pubsub:userlib /tile bol)
|= [=bone ^]
[bone %diff %json jon]
::
++ poke-json
|= jon=json
^- (quip move _this)
?. ?=(%s -.jon)
[~ this]
=/ str/@t +.jon
?: =(str 'start')
=/ data/@da (add now.bol ~s10)
:_ this(tim data)
[[ost.bol %wait /timer data] (send-tile-diff [%s (scot %da data)])]
?: =(str 'stop')
:_ this(tim *@da)
[[ost.bol %rest /timer tim] (send-tile-diff [%s ''])]
[~ this]
::
++ poke-handle-http-request
%- (require-authorization:app ost.bol move this)
|= =inbound-request:http-server
^- (quip move _this)
=/ request-line (parse-request-line url.request.inbound-request)
=/ back-path (flop site.request-line)
=/ name=@t
=/ back-path (flop site.request-line)
?~ back-path
''
i.back-path
::
?+ site.request-line
[[ost.bol %http-response not-found:app]~ this]
::
:: tile
::
[%'~timer' %js %tile ~]
[[ost.bol %http-response (js-response:app tile-js)]~ this]
::
:: images
::
[%'~timer' %img *]
=/ img (as-octs:mimes:html (~(got by timer-png) `@ta`name))
:_ this
[ost.bol %http-response (png-response:app img)]~
==
::
++ wake
|= [wir=wire err=(unit tang)]
^- (quip move _this)
:- (send-tile-diff [%s 'alarm'])
this(tim *@da)
::
--

BIN
app/timer/img/example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

2592
app/timer/js/tile.js Normal file

File diff suppressed because it is too large Load Diff

161
app/weather.hoon Normal file
View File

@ -0,0 +1,161 @@
/+ *server
/= tile-js
/^ octs
/; as-octs:mimes:html
/: /===/app/weather/js/tile
/| /js/
/~ ~
==
/= weather-png
/^ (map knot @)
/: /===/app/weather/img /_ /png/
=, format
::
|%
:: +move: output effect
::
+$ move [bone card]
:: +card: output effect payload
::
+$ card
$% [%poke wire dock poke]
[%http-response =http-event:http]
[%diff %json json]
[%connect wire binding:http-server term]
[%request wire request:http outbound-config:http-client]
[%wait wire @da]
==
+$ poke
$% [%noun [@tas path @t]]
==
+$ state
$% [%0 data=json time=@da location=@t timer=(unit @da)]
==
--
::
|_ [bol=bowl:gall state]
::
++ this .
::
++ bound
|= [wir=wire success=? binding=binding:http-server]
^- (quip move _this)
[~ this]
::
++ prep
|= old=(unit state)
^- (quip move _this)
:-
:~
[ost.bol %connect / [~ /'~weather'] %weather]
[ost.bol %poke /weather [our.bol %launch] [%noun [%weather /weathertile '/~weather/js/tile.js']]]
==
?~ old
this
%= this
data data.u.old
time time.u.old
==
::
++ peer-weathertile
|= pax=path
^- (quip move _this)
[[ost.bol %diff %json data]~ this]
::
++ poke-json
|= jon=json
^- (quip move _this)
?. ?=(%s -.jon)
[~ this]
=/ str/@t +.jon
=/ req/request:http (request-darksky str)
=/ out *outbound-config:http-client
?~ timer
:- %+ weld
`(list move)`[ost.bol %wait /timer (add now.bol ~d1)]~
`(list move)`[ost.bol %request /[(scot %da now.bol)] req out]~
%= this
location str
timer `(add now.bol ~d1)
==
:- [ost.bol %request /[(scot %da now.bol)] req out]~
%= this
location str
==
::
++ request-darksky
|= location=@t
^- request:http
=/ url/@t
%- crip %+ weld
(trip 'https://api.darksky.net/forecast/634639c10670c7376dc66b6692fe57ca/')
(trip location)
=/ hed [['Accept' 'application/json']]~
[%'GET' url hed *(unit octs)]
::
++ send-tile-diff
|= jon=json
^- (list move)
%+ turn (prey:pubsub:userlib /weathertile bol)
|= [=bone ^]
[bone %diff %json jon]
::
++ http-response
|= [=wire response=client-response:http-client]
^- (quip move _this)
:: ignore all but %finished
?. ?=(%finished -.response)
[~ this]
=/ data/(unit mime-data:http-client) full-file.response
?~ data
:: data is null
[~ this]
=/ jon/(unit json) (de-json:html q.data.u.data)
?~ jon
[~ this]
?> ?=(%o -.u.jon)
=/ ayyy/json %- pairs:enjs:format :~
currently+(~(got by p.u.jon) 'currently')
daily+(~(got by p.u.jon) 'daily')
==
:- (send-tile-diff ayyy)
%= this
data ayyy
time now.bol
==
::
++ poke-handle-http-request
%- (require-authorization:app ost.bol move this)
|= =inbound-request:http-server
^- (quip move _this)
=+ request-line=(parse-request-line url.request.inbound-request)
=+ back-path=(flop site.request-line)
=/ name=@t
=+ back-path=(flop site.request-line)
?~ back-path
''
i.back-path
::
?~ back-path
:_ this ~
?: =(name 'tile')
[[ost.bol %http-response (js-response:app tile-js)]~ this]
?: (lte (lent back-path) 1)
[[ost.bol %http-response not-found:app]~ this]
?: =(&2:site.request-line 'img')
=/ img (as-octs:mimes:html (~(got by weather-png) `@ta`name))
[[ost.bol %http-response (png-response:app img)]~ this]
[~ this]
::
++ wake
|= [wir=wire err=(unit tang)]
^- (quip move _this)
=/ req/request:http (request-darksky location)
=/ lismov/(list move)
`(list move)`[ost.bol %request /[(scot %da now.bol)] req *outbound-config:http-client]~
?~ timer
:- (weld lismov `(list move)`[ost.bol %wait /timer (add now.bol ~h3)]~)
this(timer `(add now.bol ~h3))
[lismov this]
::
--

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
app/weather/img/cloudy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
app/weather/img/fog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

BIN
app/weather/img/high.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

BIN
app/weather/img/low.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/weather/img/rain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
app/weather/img/sleet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

BIN
app/weather/img/snow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
app/weather/img/sunset.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
app/weather/img/wind.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

6946
app/weather/js/tile.js Normal file

File diff suppressed because it is too large Load Diff

1439
app/write.hoon Normal file

File diff suppressed because it is too large Load Diff

2
app/write/css/index.css Normal file

File diff suppressed because one or more lines are too long

BIN
app/write/img/tile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

21
app/write/index.hoon Normal file
View File

@ -0,0 +1,21 @@
|= inject=json
^- manx
;html
::
;head
;title: Write
;meta(charset "utf-8");
;meta
=name "viewport"
=content "width=device-width, initial-scale=1, shrink-to-fit=no";
;link(rel "stylesheet", href "/~publish/index.css");
;script@"/~/channel/channel.js";
;script@"/~modulo/session.js";
;script: window.injectedState = {(en-json:html inject)}
==
::
;body
;div#root;
;script@"/~publish/index.js";
==
==

59494
app/write/js/index.js Normal file

File diff suppressed because one or more lines are too long

2266
app/write/js/tile.js Normal file

File diff suppressed because it is too large Load Diff

140
lib/chat.hoon Normal file
View File

@ -0,0 +1,140 @@
/- hall
/+ hall-json
|%
::
+$ move [bone card]
::
+$ card
$% [%http-response =http-event:http]
[%connect wire binding:http-server term]
[%peer wire dock path]
[%quit ~]
[%poke wire dock poke]
[%peer wire dock path]
[%pull wire dock ~]
[%diff diff]
==
::
+$ diff
$% [%hall-rumor rumor:hall]
[%chat-update update]
[%chat-config streams]
[%json json]
==
::
+$ poke
$% [%hall-action action:hall]
[%noun [@tas path @t]]
==
::
+$ state
$% [%0 str=streams]
==
::
+$ streams
$: :: inbox config
::
inbox=config:hall
:: names and configs of all circles we know about
::
configs=(map circle:hall (unit config:hall))
:: messages for all circles we know about
::
messages=(map circle:hall (list envelope:hall))
::
::
circles=(set name:hall)
::
::
peers=(map circle:hall (set @p))
==
::
+$ update
$% [%inbox con=config:hall]
[%message cir=circle:hall env=envelope:hall]
[%messages cir=circle:hall start=@ud end=@ud env=(list envelope:hall)]
[%config cir=circle:hall con=config:hall]
[%circles cir=(set name:hall)]
[%peers cir=circle:hall per=(set @p)]
[%delete cir=circle:hall]
==
::
+$ action [%actions lis=(list action:hall)]
::
::
:: +utilities
::
++ msg-to-json
=, enjs:format
|= upd=update
^- json
?> ?=(%messages -.upd)
%+ frond %update
%- pairs
:~
:- %messages
%- pairs
:~
[%circle (circ:enjs:hall-json cir.upd)]
[%start (numb start.upd)]
[%end (numb end.upd)]
[%envelopes [%a (turn env.upd enve:enjs:hall-json)]]
==
==
::
++ config-to-json
|= str=streams
=, enjs:format
^- json
%+ frond %chat
%- pairs
:~
::
[%inbox (conf:enjs:hall-json inbox.str)]
::
:- %configs
%- pairs
%+ turn ~(tap by configs.str)
|= [cir=circle:hall con=(unit config:hall)]
^- [@t json]
:- (crip (circ:en-tape:hall-json cir))
?~(con ~ (conf:enjs:hall-json u.con))
::
:- %circles :- %a
%+ turn ~(tap in circles.str)
|= nom=name:hall
[%s nom]
::
:- %peers
%- pairs
%+ turn ~(tap by peers.str)
|= [cir=circle:hall per=(set @p)]
^- [@t json]
:- (crip (circ:en-tape:hall-json cir))
[%a (turn ~(tap in per) ship)]
::
==
::
++ numbers-to-json
|= num=(list [circle:hall @ud])
^- json
=, enjs:format
%+ frond %chat
%- pairs
:~
::
:: %config
:- %numbers
:- %a
%+ turn num
|= [cir=circle:hall len=@ud]
^- json
%- pairs
:~
[%circle (circ:enjs:hall-json cir)]
[%length (numb len)]
==
==
::
--
::

View File

@ -79,23 +79,25 @@
=+ myr=(clan:title our)
::
?: ?=($pawn myr)
:~ [%base %collections]
[%home %lens]
:~ [%home %lens]
[%base %hall]
[%base %talk]
[%base %dojo]
[%base %landscape]
[%base %modulo]
==
:~ [%home %collections]
[%home %lens]
:~ [%home %lens]
[%home %acme]
[%home %dns]
[%home %dojo]
[%home %hall]
[%home %talk]
[%home %landscape]
[%home %modulo]
[%home %launch]
[%home %chat]
[%home %write]
[%home %timer]
[%home %clock]
[%home %weather]
==
::
++ deft-fish :: default connects

View File

@ -59,6 +59,11 @@
^- http-event:http
[%start [200 ['content-type' 'text/css']~] [~ oct-css] %.y]
::
++ manx-response
|= man=manx
^- http-event:http
[%start [200 ['content-type' 'text/html']~] [~ (manx-to-octs man)] %.y]
::
++ png-response
|= oct-png=octs
^- http-event:http

232
lib/write.hoon Normal file
View File

@ -0,0 +1,232 @@
/- *write
/+ elem-to-react-json
|%
::
++ front-to-post-info
|= fro=(map knot cord)
^- post-info
=/ got ~(got by fro)
~| %invalid-frontmatter
:* (slav %p (got %creator))
(got %title)
(got %collection)
(got %filename)
(comment-config (got %comments))
(slav %da (got %date-created))
(slav %da (got %last-modified))
(rash (got %pinned) (fuss %true %false))
==
::
++ front-to-comment-info
|= fro=(map knot cord)
^- comment-info
=/ got ~(got by fro)
~| %invalid-frontmatter
:* (slav %p (got %creator))
(got %collection)
(got %post)
(slav %da (got %date-created))
(slav %da (got %last-modified))
==
::
++ collection-info-to-json
|= con=collection-info
^- json
%- pairs:enjs:format
:~ :- %owner [%s (scot %p owner.con)]
:- %title [%s title.con]
:- %comments [%s comments.con]
:- %allow-edit [%s allow-edit.con]
:- %date-created (time:enjs:format date-created.con)
:- %last-modified (time:enjs:format last-modified.con)
:- %filename [%s filename.con]
==
::
++ post-info-to-json
|= info=post-info
^- json
%- pairs:enjs:format
:~ :- %creator [%s (scot %p creator.info)]
:- %title [%s title.info]
:- %comments [%s comments.info]
:- %date-created (time:enjs:format date-created.info)
:- %last-modified (time:enjs:format last-modified.info)
:- %pinned [%b pinned.info]
:- %filename [%s filename.info]
:- %collection [%s collection.info]
==
::
++ comment-info-to-json
|= info=comment-info
^- json
%- pairs:enjs:format
:~ :- %creator [%s (scot %p creator.info)]
:- %date-created (time:enjs:format date-created.info)
:- %last-modified (time:enjs:format last-modified.info)
:- %post [%s post.info]
:- %collection [%s collection.info]
==
::
++ tang-to-json
|= tan=tang
%- wall:enjs:format
%- zing
%+ turn tan
|= a=tank
(wash [0 80] a)
::
++ string-to-symbol
|= tap=tape
^- @tas
%- crip
%+ turn tap
|= a=@
?: ?| &((gte a 'a') (lte a 'z'))
&((gte a '0') (lte a '9'))
==
a
?: &((gte a 'A') (lte a 'Z'))
(add 32 a)
'-'
::
++ collection-build-to-json
|= bud=(each collection-info tang)
^- json
?: ?=(%.y -.bud)
(collection-info-to-json +.bud)
(tang-to-json +.bud)
::
++ post-build-to-json
|= bud=(each [post-info manx @t] tang)
^- json
?: ?=(%.y -.bud)
%- pairs:enjs:format
:~ info+(post-info-to-json +<.bud)
body+(elem-to-react-json +>-.bud)
raw+[%s +>+.bud]
==
(tang-to-json +.bud)
::
++ comment-build-to-json
|= bud=(each (list [comment-info @t]) tang)
^- json
?: ?=(%.y -.bud)
:- %a
%+ turn p.bud
|= [com=comment-info bod=@t]
^- json
%- pairs:enjs:format
:~ info+(comment-info-to-json com)
body+s+bod
==
(tang-to-json +.bud)
::
++ total-build-to-json
|= col=collection
^- json
%- pairs:enjs:format
:~ info+(collection-build-to-json dat.col.col)
::
:+ %posts
%o
%+ roll ~(tap in ~(key by pos.col))
|= [post=@tas out=(map @t json)]
=/ post-build (~(got by pos.col) post)
=/ comm-build (~(got by com.col) post)
%+ ~(put by out)
post
%- pairs:enjs:format
:~ post+(post-build-to-json dat.post-build)
comments+(comment-build-to-json dat.comm-build)
==
::
:- %order
%- pairs:enjs:format
:~ pin+a+(turn pin.order.col |=(s=@tas [%s s]))
unpin+a+(turn unpin.order.col |=(s=@tas [%s s]))
==
::
:- %contributors
%- pairs:enjs:format
:~ mod+s+mod.contributors.col
:+ %who
%a
%+ turn ~(tap in who.contributors.col)
|= who=@p
(ship:enjs:format who)
==
::
:+ %subscribers
%a
%+ turn ~(tap in subscribers.col)
|= who=@p
^- json
(ship:enjs:format who)
::
[%last-update (time:enjs:format last-update.col)]
==
::
++ state-to-json
|= sat=state
^- json
%- pairs:enjs:format
:~ :+ %pubs
%o
%+ roll ~(tap by pubs.sat)
|= [[nom=@tas col=collection] out=(map @t json)]
%+ ~(put by out)
nom
(total-build-to-json col)
::
:+ %subs
%o
%- ~(rep by subs.sat)
|= $: [[who=@p nom=@tas] col=collection]
out=(map @t [%o (map @t json)])
==
=/ shp=@t (rsh 3 1 (scot %p who))
?: (~(has by out) shp)
%+ ~(put by out)
shp
:- %o
%+ ~(put by +:(~(got by out) shp))
nom
(total-build-to-json col)
%+ ~(put by out)
shp
:- %o
(my [nom (total-build-to-json col)] ~)
::
:+ %latest
%a
%+ turn latest.sat
|= [who=@p coll=@tas post=@tas]
%- pairs:enjs:format
:~ who+(ship:enjs:format who)
coll+s+coll
post+s+post
==
::
:+ %unread
%a
%+ turn ~(tap in unread.sat)
|= [who=@p coll=@tas post=@tas]
%- pairs:enjs:format
:~ who+(ship:enjs:format who)
coll+s+coll
post+s+post
==
::
:+ %invites
%a
%+ turn ~(tap in invites.sat)
|= [[who=@p coll=@tas] title=@t]
%- pairs:enjs:format
:~ who+(ship:enjs:format who)
coll+s+coll
title+s+title
==
==
::
--

58
mar/chat/action.hoon Normal file
View File

@ -0,0 +1,58 @@
::
::
/- hall
/+ chat, hall-json
::
|_ act=action:chat
++ grow
|%
++ tank !!
--
::
++ grab
|%
++ noun action:chat
++ json
|= jon=^json
=< (parse-chat-action jon)
|%
::
++ hall-action
=, dejs:hall-json
=, dejs-soft:format
|= a=^json
^- action:hall
=- (need ((of -) a))
:~ create+(ot nom+so des+so sec+secu ~)
design+(ot nom+so cof+conf ~)
delete+(ot nom+so why+(mu so) ~)
depict+(ot nom+so des+so ~)
filter+(ot nom+so fit+filt ~)
permit+(ot nom+so inv+bo sis+(as (su fed:ag)) ~)
source+(ot nom+so sub+bo srs+(as sorc) ~)
read+(ot nom+so red+ni ~)
usage+(ot nom+so add+bo tas+(as so) ~)
newdm+(ot sis+(as (su fed:ag)) ~)
::
convey+(ar thot)
phrase+(ot aud+audi ses+(ar spec:dejs:hall-json) ~)
::
notify+(ot aud+audi pes+(mu pres) ~)
naming+(ot aud+audi man+huma ~)
::
glyph+(ot gyf+so aud+audi bin+bo ~)
nick+(ot who+(su fed:ag) nic+so ~)
::
public+(ot add+bo cir+circ ~)
==
::
++ parse-chat-action
=, dejs:format
%- of
:~
[%actions (ot lis+(ar hall-action) ~)]
==
::
--
--
--

48
mar/chat/config.hoon Normal file
View File

@ -0,0 +1,48 @@
::
::
/? 309
::
/- hall
/+ chat, hall-json
::
|_ str=streams:chat
++ grow
|%
++ json
=, enjs:format
^- ^json
%+ frond %chat
%- pairs
:~
::
[%inbox (conf:enjs:hall-json inbox.str)]
::
:- %configs
%- pairs
%+ turn ~(tap by configs.str)
|= [cir=circle:hall con=(unit config:hall)]
^- [@t ^json]
:- (crip (circ:en-tape:hall-json cir))
?~(con ~ (conf:enjs:hall-json u.con))
::
:- %circles :- %a
%+ turn ~(tap in circles.str)
|= nom=name:hall
[%s nom]
::
:- %peers
%- pairs
%+ turn ~(tap by peers.str)
|= [cir=circle:hall per=(set @p)]
^- [@t ^json]
:- (crip (circ:en-tape:hall-json cir))
[%a (turn ~(tap in per) ship)]
::
==
--
::
++ grab
|%
++ noun streams:chat
--
--

96
mar/chat/update.hoon Normal file
View File

@ -0,0 +1,96 @@
::
::
/? 309
::
/- hall
/+ chat, hall-json
::
|_ upd=update:chat
++ grow
|%
++ json
=, enjs:format
^- ^json
%+ frond %update
%- pairs
:~
::
:: %inbox
?: =(%inbox -.upd)
?> ?=(%inbox -.upd)
[%inbox (conf:enjs:hall-json con.upd)]
::
:: %message
?: =(%message -.upd)
?> ?=(%message -.upd)
:- %message
%- pairs
:~
[%circle (circ:enjs:hall-json cir.upd)]
[%envelope (enve:enjs:hall-json env.upd)]
==
::
:: %messages
?: =(%messages -.upd)
?> ?=(%messages -.upd)
:- %messages
%- pairs
:~
[%circle (circ:enjs:hall-json cir.upd)]
[%start (numb start.upd)]
[%end (numb end.upd)]
[%envelopes [%a (turn env.upd enve:enjs:hall-json)]]
==
::
:: %config
?: =(%config -.upd)
?> ?=(%config -.upd)
:- %config
%- pairs
:~
[%circle (circ:enjs:hall-json cir.upd)]
[%config (conf:enjs:hall-json con.upd)]
==
::
:: %circles
?: =(%circles -.upd)
?> ?=(%circles -.upd)
:- %circles
%- pairs
:~
:- %circles
:- %a
%+ turn ~(tap in cir.upd)
|= nom=name:hall
[%s nom]
==
::
:: %peers
?: =(%peers -.upd)
?> ?=(%peers -.upd)
:- %peers
%- pairs
:~
[%circle (circ:enjs:hall-json cir.upd)]
[%peers [%a (turn ~(tap in per.upd) ship:enjs:format)]]
==
::
:: %delete
?: =(%delete -.upd)
?> ?=(%delete -.upd)
:- %delete
%- pairs
:~
[%circle (circ:enjs:hall-json cir.upd)]
==
::
:: %noop
[*@t *^json]
==
--
::
++ grab
|%
++ noun update:chat
--
--

View File

@ -1,6 +0,0 @@
|_ ter=term
++ grab
|%
++ noun term
--
--

View File

@ -1,14 +0,0 @@
/- *modulo
=, format
|_ com=command
++ grab
|%
++ noun command
++ json
%- of:dejs
:~ forward+ul:dejs
back+ul:dejs
go+(su:dejs sym)
==
--
--

View File

@ -1,6 +0,0 @@
|_ ter=term
++ grab
|%
++ noun term
--
--

192
mar/write/action.hoon Normal file
View File

@ -0,0 +1,192 @@
::
:::: /hoon/action/write/mar
::
/? 309
/- write
=, format
::
|_ act=action:write
::
++ grow
|%
++ tank >act<
--
::
++ grab
|%
++ noun action:write
++ json
|= jon=^json
%- action:write
=< (action jon)
|%
++ action
%- of:dejs
:~ new-collection+new-collection
new-post+new-post
new-comment+new-comment
::
delete-collection+delete-collection
delete-post+delete-post
delete-comment+delete-comment
::
edit-collection+edit-collection
edit-post+edit-post
::
invite+invite
reject-invite+reject-invite
::
serve+serve
unserve+unserve
::
subscribe+subscribe
unsubscribe+unsubscribe
::
read+read
==
::
++ new-collection
%- ot:dejs
:~ name+(su:dejs sym)
title+so:dejs
comments+comment-config
allow-edit+edit-config
perm+perm-config
==
::
++ new-post
%- ot:dejs
:~ who+(su:dejs fed:ag)
coll+(su:dejs sym)
name+(su:dejs sym)
title+so:dejs
comments+comment-config
perm+perm-config
content+so:dejs
==
::
++ new-comment
%- ot:dejs
:~ who+(su:dejs fed:ag)
coll+(su:dejs sym)
name+(su:dejs sym)
content+so:dejs
==
::
++ delete-collection (of:dejs coll+(su:dejs sym) ~)
::
++ delete-post
%- ot:dejs
:~ coll+(su:dejs sym)
post+(su:dejs sym)
==
::
++ delete-comment
%- ot:dejs
:~ coll+(su:dejs sym)
post+(su:dejs sym)
comment+(su:dejs sym)
==
::
++ edit-collection
%- ot:dejs
:~ name+(su:dejs sym)
title+so:dejs
comments+comment-config
allow-edit+edit-config
perm+perm-config
==
::
++ edit-post
%- ot:dejs
:~ who+(su:dejs fed:ag)
coll+(su:dejs sym)
name+(su:dejs sym)
title+so:dejs
comments+comment-config
perm+perm-config
content+so:dejs
==
::
++ edit-comment
%- ot:dejs
:~ coll+(su:dejs sym)
name+(su:dejs sym)
id+(su:dejs sym)
content+so:dejs
==
::
++ comment-config
%- su:dejs
;~(pose (jest %open) (jest %closed) (jest %none))
::
++ edit-config
%- su:dejs
;~(pose (jest %post) (jest %comment) (jest %all) (jest %none))
::
++ perm-config
%- ot:dejs
:~ :- %read
%- ot:dejs
:~ mod+(su:dejs ;~(pose (jest %black) (jest %white)))
who+whoms
==
:- %write
%- ot:dejs
:~ mod+(su:dejs ;~(pose (jest %black) (jest %white)))
who+whoms
== ==
::
++ whoms
|= jon=^json
^- (set whom:clay)
=/ x ((ar:dejs (su:dejs fed:ag)) jon)
%- (set whom:clay)
%- ~(run in (sy x))
|=(w=@ [& w])
::
++ invite
%- ot:dejs
:~ coll+(su:dejs sym)
title+so:dejs
who+(ar:dejs (su:dejs fed:ag))
==
::
++ reject-invite
%- ot:dejs
:~ who+(su:dejs fed:ag)
coll+(su:dejs sym)
==
::
++ serve
%- ot:dejs
:~ coll+(su:dejs sym)
==
::
++ unserve
%- ot:dejs
:~ coll+(su:dejs sym)
==
::
++ subscribe
%- ot:dejs
:~ who+(su:dejs fed:ag)
coll+(su:dejs sym)
==
::
++ unsubscribe
%- ot:dejs
:~ who+(su:dejs fed:ag)
coll+(su:dejs sym)
==
::
++ read
%- ot:dejs
:~ who+(su:dejs fed:ag)
coll+(su:dejs sym)
post+(su:dejs sym)
==
::
--
--
--

84
mar/write/info.hoon Normal file
View File

@ -0,0 +1,84 @@
::
:::: /hoon/info/write/mar
::
/- write
!:
|_ con=collection-info:write
::
::
++ grow
|%
++ mime
:- /text/x-write-info
(as-octs:mimes:html (of-wain:format txt))
++ txt
^- wain
:~ (cat 3 'owner: ' (scot %p owner.con))
(cat 3 'title: ' title.con)
(cat 3 'filename: ' filename.con)
(cat 3 'comments: ' comments.con)
(cat 3 'allow-edit: ' allow-edit.con)
(cat 3 'date-created: ' (scot %da date-created.con))
(cat 3 'last-modified: ' (scot %da last-modified.con))
==
--
++ grab
|%
++ mime
|= [mite:eyre p=octs:eyre]
(txt (to-wain:format q.p))
++ txt
|= txs=(pole @t)
^- collection-info:write
:: TODO: putting ~ instead of * breaks this but shouldn't
::
?> ?= $: owner=@t
title=@t
filename=@t
comments=@t
allow-edit=@t
date-created=@t
last-modified=@t
*
==
txs
::
:* %+ rash owner.txs
;~(pfix (jest 'owner: ~') fed:ag)
::
%+ rash title.txs
;~(pfix (jest 'title: ') (cook crip (star next)))
::
%+ rash filename.txs
;~(pfix (jest 'filename: ') (cook crip (star next)))
::
%+ rash comments.txs
;~ pfix
(jest 'comments: ')
%+ cook comment-config:write
;~(pose (jest %open) (jest %closed) (jest %none))
==
::
%+ rash allow-edit.txs
;~ pfix
(jest 'allow-edit: ')
%+ cook edit-config:write
;~(pose (jest %post) (jest %comment) (jest %all) (jest %none))
==
::
%+ rash date-created.txs
;~ pfix
(jest 'date-created: ~')
(cook year when:so)
==
::
%+ rash last-modified.txs
;~ pfix
(jest 'last-modified: ~')
(cook year when:so)
==
==
++ noun collection-info:write
--
++ grad %mime
--

55
mar/write/rumor.hoon Normal file
View File

@ -0,0 +1,55 @@
/- *write
/+ *write, elem-to-react-json
|_ rum=rumor
++ grab
|%
++ noun rumor
--
++ grow
|%
++ noun rum
++ json
=, enjs:format
%+ frond -.rum
?- -.rum
%collection
%- pairs
:~ [%coll s+col.rum]
[%who (ship who.rum)]
[%data (collection-build-to-json dat.rum)]
==
::
%post
%- pairs
:~ [%coll s+col.rum]
[%post s+pos.rum]
[%who (ship who.rum)]
[%data (post-build-to-json dat.rum)]
==
::
%comments
%- pairs
:~ [%coll s+col.rum]
[%post s+pos.rum]
[%who (ship who.rum)]
[%data (comment-build-to-json dat.rum)]
==
::
%total
%- pairs
:~ [%coll s+col.rum]
[%who (ship who.rum)]
[%data (total-build-to-json dat.rum)]
==
::
%remove
%- pairs
:~ [%who (ship who.rum)]
[%coll s+col.rum]
[%post ?~(pos.rum ~ s+u.pos.rum)]
==
::
==
::
--
--

26
mar/write/update.hoon Normal file
View File

@ -0,0 +1,26 @@
/- *write
|_ upd=update
++ grab
|%
++ noun update
--
++ grow
|%
++ noun upd
++ json
=, enjs:format
%+ frond -.upd
::
?- -.upd
%invite
%- pairs
:~ [%who (ship who.upd)]
[%add b+add.upd]
[%coll s+col.upd]
[%title s+title.upd]
==
::
==
::
--
--

27
ren/write/comments.hoon Normal file
View File

@ -0,0 +1,27 @@
/- write
/+ write, cram, elem-to-react-json
/= args /$ ,[beam *]
/= result
/^ (list [comment-info:write @t])
/;
|= $= comments
%+ map knot
$: comment-front=(map knot cord)
comment-content=wain
~
==
^- (list [comment-info:write @t])
%+ sort
%+ turn ~(tap by comments)
|= [fil=knot front=(map knot cord) content=wain ~]
^- [comment-info:write @t]
:- (front-to-comment-info:write front)
(of-wain:format (slag 8 content))
|= [a=[com=comment-info:write @t] b=[com=comment-info:write @t]]
(lte date-created.com.a date-created.com.b)
::
/_
/. /&front&/udon/
/&txt&/udon/
==
result

20
ren/write/post.hoon Normal file
View File

@ -0,0 +1,20 @@
/- write
/+ write, cram, elem-to-react-json
/= args /$ ,[beam *]
/= result
/^ [post-info:write manx @t]
/;
|= $: post-front=(map knot cord)
post-content=manx
post-raw=wain
~
==
:+ (front-to-post-info:write post-front)
post-content
(of-wain:format (slag 11 post-raw))
::
/. /&front&/udon/
/&elem&/udon/
/&txt&/udon/
==
result

View File

@ -1,7 +0,0 @@
|%
+$ command
$% [%forward ~]
[%back ~]
[%go app=term]
==
--

126
sur/write.hoon Normal file
View File

@ -0,0 +1,126 @@
|%
::
+$ action
$% $: %new-collection
name=@tas
title=@t
com=comment-config
edit=edit-config
perm=perm-config
==
::
$: %new-post
who=@p
coll=@tas
name=@tas
title=@t
com=comment-config
perm=perm-config
content=@t
==
::
[%new-comment who=@p coll=@tas post=@tas content=@t]
::
[%delete-collection coll=@tas]
[%delete-post coll=@tas post=@tas]
[%delete-comment coll=@tas post=@tas comment=@tas]
::
$: %edit-collection
name=@tas
title=@t
com=comment-config
edit=edit-config
perm=perm-config
==
::
$: %edit-post
who=@p
coll=@tas
name=@tas
title=@t
com=comment-config
perm=perm-config
content=@t
==
::
[%invite coll=@tas title=@t who=(list ship)]
[%reject-invite who=@p coll=@tas]
::
[%serve coll=@tas]
[%unserve coll=@tas]
::
[%subscribe who=@p coll=@tas]
[%unsubscribe who=@p coll=@tas]
::
[%read who=@p coll=@tas post=@tas]
==
::
+$ collection-info
$: owner=@p
title=@t
filename=@tas
comments=comment-config
allow-edit=edit-config
date-created=@da
last-modified=@da
==
::
+$ post-info
$: creator=@p
title=@t
collection=@tas
filename=@tas
comments=comment-config
date-created=@da
last-modified=@da
pinned=?
==
::
+$ comment-info
$: creator=@p
collection=@tas
post=@tas
date-created=@da
last-modified=@da
==
::
+$ perm-config [read=rule:clay write=rule:clay]
::
+$ comment-config $?(%open %closed %none)
::
+$ edit-config $?(%post %comment %all %none)
::
+$ rumor delta
::
+$ collection
$: col=[=bone dat=(each collection-info tang)]
pos=(map @tas [=bone dat=(each [post-info manx @t] tang)])
com=(map @tas [=bone dat=(each (list [comment-info @t]) tang)])
order=[pin=(list @tas) unpin=(list @tas)]
contributors=[mod=?(%white %black) who=(set @p)]
subscribers=(set @p)
last-update=@da
==
::
+$ state
$: pubs=(map @tas collection)
subs=(map [ship @tas] collection)
awaiting=(map @tas [builds=(set wire) partial=(unit delta)])
latest=(list [who=ship coll=@tas post=@tas])
unread=(set [who=ship coll=@tas post=@tas])
invites=(map [who=ship coll=@tas] title=@t)
outgoing=(map path bone)
==
::
+$ delta
$% [%collection who=@p col=@tas dat=(each collection-info tang)]
[%post who=@p col=@tas pos=@tas dat=(each [post-info manx @t] tang)]
[%comments who=@p col=@tas pos=@tas dat=(each (list [comment-info @t]) tang)]
[%total who=@p col=@tas dat=collection]
[%remove who=@p col=@tas pos=(unit @tas)]
==
::
+$ update
$% [%invite add=? who=@p col=@tas title=@t]
==
--

View File

@ -60,7 +60,7 @@
$: %b
::
::
$% [%wake ~]
$% [%wake error=(unit tang)]
== ==
:: %f: from ford
::
@ -245,7 +245,7 @@
:: We maintain a list of subscriptions so if a channel times out, we
:: can cancel all the subscriptions we've made.
::
subscriptions=(map wire [ship=@p app=term =path])
subscriptions=(map wire [ship=@p app=term =path duc=duct])
==
:: channel-request: an action requested on a channel
::
@ -581,7 +581,6 @@
//
var x = JSON.stringify(
[{"action": "ack", "event-id": parseInt(this.lastEventId)}, j])
console.log(x, this.lastEventId);
req.send(x);
this.lastEventId = this.lastAcknowledgedEventId;
@ -622,20 +621,14 @@
if (obj.hasOwnProperty("err")) {
funcs["err"](obj.err);
this.outstandingSubscriptions.delete(obj.id);
} else {
console.log("Subscription establisthed");
}
} else if (obj.response == "diff") {
console.log("Diff: ", obj);
var funcs = this.outstandingSubscriptions.get(obj.id);
funcs["event"](obj.json);
} else if (obj.response == "quit") {
var funcs = this.outstandingSubscriptions.get(obj.id);
funcs["quit"](obj.err);
this.outstandingSubscriptions.delete(obj.id);
} else {
console.log("Unrecognized response: ", e);
}
@ -1303,7 +1296,7 @@
%+ ~(jab by session.channel-state.state) channel-id
|= =channel
=, i.requests
channel(subscriptions (~(put by subscriptions.channel) channel-wire [ship app path]))
channel(subscriptions (~(put by subscriptions.channel) channel-wire [ship app path duct]))
::
$(requests t.requests)
::
@ -1324,7 +1317,7 @@
=. gall-moves
:_ gall-moves
^- move
:^ duct %pass channel-wire
:^ duc.u.maybe-subscription %pass channel-wire
=, u.maybe-subscription
[%g %deal [our ship] `cush:gall`[app %pull ~]]
::
@ -1336,22 +1329,41 @@
$(requests t.requests)
::
%delete
=/ session
(~(got by session.channel-state.state) channel-id)
=/ unitsession
(~(get by session.channel-state.state) channel-id)
::
?~ unitsession
$(requests t.requests)
::
=/ session u.unitsession
=. session.channel-state.state
(~(del by session.channel-state.state) channel-id)
::
=. gall-moves
%+ weld
gall-moves
%+ weld gall-moves
::
:: produce a list of moves which cancels every gall subscription
::
%+ turn ~(tap by subscriptions.session)
|= [channel-wire=path ship=@p app=term =path duc=^duct]
^- move
::
[duc %pass channel-wire [%g %deal [our ship] app %pull ~]]
::
?: ?=([%& *] state.session)
=. gall-moves
:_ gall-moves
::
^- move
?> ?=([%& *] state.session)
:^ duct.p.state.session %pass /channel/timeout/[channel-id]
[%b %rest date.p.state.session]
::
:: produce a list of moves which cancels every gall subscription
$(requests t.requests)
::
%+ turn ~(tap by subscriptions.session)
|= [channel-wire=path ship=@p app=term =path]
^- move
::
[duct %pass channel-wire [%g %deal [our ship] app %pull ~]]
?> ?=([%| *] state.session)
=. duct-to-key.channel-state.state
(~(del by duct-to-key.channel-state.state) p.state.session)
::
$(requests t.requests)
::
@ -1487,10 +1499,10 @@
:: produce a list of moves which cancels every gall subscription
::
%+ turn ~(tap by subscriptions.session)
|= [channel-wire=path ship=@p app=term =path]
|= [channel-wire=path ship=@p app=term =path duc=^duct]
^- move
::
[duct %pass channel-wire [%g %deal [our ship] app %pull ~]]
[duc %pass channel-wire [%g %deal [our ship] app %pull ~]]
--
:: +handle-ford-response: translates a ford response for the outside world
::
@ -1985,6 +1997,9 @@
~|([%bad-channel-wire wire] !!)
::
%timeout
?> ?=([%b %wake *] sign)
?^ error.sign
[[duct %slip %d %flog %crud %wake u.error.sign]~ http-server-gate]
=/ on-channel-timeout
on-channel-timeout:by-channel:(per-server-event event-args)
=^ moves server-state.ax