Merge branch 'master' into release/next-js

This commit is contained in:
Liam Fitzgerald 2021-04-02 13:39:51 +10:00
commit 511f48d35b
No known key found for this signature in database
GPG Key ID: D390E12C61D1CFFB
178 changed files with 5279 additions and 1210 deletions

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fd9f630f51cb104cd2042ef231b78e802a8fd31bbd0a90ced75c7ebee792647a
size 9940591
oid sha256:bc1fb5cddfa4a1c67ade60d35fc985d55f4ca86ecbaa9b30901a7c257b7b06a4
size 10035009

View File

@ -169,7 +169,7 @@
::
%fact
?+ p.cage.sign ~|([dap.bowl %bad-sub-mark wire p.cage.sign] !!)
%graph-update-0
%graph-update-1
%- on-graph-update:tc
!<(update:graph q.cage.sign)
==
@ -758,9 +758,9 @@
::TODO move creation into lib?
%^ act %out-message
%graph-push-hook
:- %graph-update-0
:- %graph-update-1
!> ^- update:graph
:+ %0 now.bowl
:- now.bowl
:+ %add-nodes audience
%- ~(put by *(map index:post node:graph))
:- ~[now.bowl]
@ -1185,7 +1185,15 @@
?- -.content
%text txt+(trip text.content)
%url url+url.content
%reference txt+"[reference to msg in {~(phat tr resource.uid.content)}]"
::
%reference
?- -.reference.content
%graph
txt+"[reference to msg in {~(phat tr resource.uid.reference.content)}]"
::
%group
txt+"[reference to msg in {~(phat tr group.reference.content)}]"
==
::
%mention
?. =(ship.content our-self) txt+(scow %p ship.content)

View File

@ -154,7 +154,7 @@
++ poke-graph-store
|= =update:graph-store
^- card
(poke-our %graph-store %graph-update-0 !>(update))
(poke-our %graph-store %graph-update-1 !>(update))
::
++ nobody
^- @p
@ -190,7 +190,7 @@
cards
:_ cards
%- poke-graph-store
:+ %0 now.bol
:- now.bol
archive-graph+rid
==
?: =(our.bol ship)

View File

@ -247,7 +247,7 @@
++ add-graph
|= [rid=resource =mailbox:store]
%- poke-graph-store
:+ %0 now.bol
:- now.bol
:+ %add-graph rid
:- (mailbox-to-graph mailbox)
[`%graph-validator-chat %.y]
@ -255,7 +255,7 @@
++ archive-graph
|= rid=resource
%- poke-graph-store
[%0 now.bol %archive-graph rid]
[now.bol %archive-graph rid]
::
++ nobody
^- @p
@ -298,7 +298,7 @@
++ poke-graph-store
|= =update:graph-store
^- card
[%pass / %agent [our.bol %graph-store] %poke %graph-update-0 !>(update)]
[%pass / %agent [our.bol %graph-store] %poke %graph-update-1 !>(update)]
::
++ letter-to-contents
|= =letter:store

View File

@ -1077,7 +1077,12 @@
::
%thread-done
?> ?=(^ poy)
(~(dy-hand dy u.poy(pux ~)) %noun q.cage.sign)
:: print the vase as a tang if it nests in tang
=/ =mark
?: (~(nest ut -:!>(*tang)) | p.q.cage.sign)
%tang
%noun
(~(dy-hand dy u.poy(pux ~)) mark q.cage.sign)
==
::
%kick +>.$

View File

@ -5,7 +5,7 @@
/- glob
/+ default-agent, verb, dbug
|%
++ hash 0v6.8mn05.16g61.46lkc.lgddc.3ifug
++ hash 0v6.i86m5.f4rs9.l09fu.a7d86.v00sl
+$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))]
+$ all-states
$% state-0

View File

@ -9,7 +9,7 @@
update:store
%graph-update
%graph-push-hook
0 0
1 1
%.n
==
--
@ -41,9 +41,9 @@
%- (slog leaf+"nacked {<resource>}" tang)
:_ this
?. (~(has in get-keys:gra) resource) ~
=- [%pass /pull-nack %agent [our.bowl %graph-store] %poke %graph-update-0 -]~
=- [%pass /pull-nack %agent [our.bowl %graph-store] %poke %graph-update-1 -]~
!> ^- update:store
[%0 now.bowl [%archive-graph resource]]
[now.bowl [%archive-graph resource]]
::
++ on-pull-kick
|= =resource

View File

@ -12,7 +12,7 @@
update:store
%graph-update
%graph-pull-hook
0 0
1 1
==
::
+$ agent (push-hook:push-hook config)
@ -185,7 +185,7 @@
(get-graph:gra resource)
=/ =time (slav %da i.path)
=/ =update-log:store (get-update-log-subset:gra resource time)
[%0 now.bowl [%run-updates resource update-log]]
[now.bowl [%run-updates resource update-log]]
::
++ take-update
|= =vase

View File

@ -10,18 +10,20 @@
$% state-0
state-1
state-2
state-3
==
::
+$ state-0 [%0 network:store]
+$ state-1 [%1 network:store]
+$ state-2 [%2 network:store]
+$ state-0 [%0 network:zero:store]
+$ state-1 [%1 network:zero:store]
+$ state-2 [%2 network:zero:store]
+$ state-3 [%3 network:store]
::
++ orm orm:store
++ orm-log orm-log:store
+$ debug-input [%validate-graph =resource:store]
--
::
=| state-2
=| state-3
=* state -
::
%- agent:dbug
@ -60,134 +62,149 @@
::
graphs.old
%- ~(run by graphs.old)
|= [=graph:store q=(unit mark)]
^- [graph:store (unit mark)]
:- (convert-unix-timestamped-graph graph)
|= [=graph:zero:store q=(unit mark)]
^- [graph:zero:store (unit mark)]
:- (convert-unix-timestamped-graph:zero-load graph)
?^ q q
`%graph-validator-link
::
update-logs.old
%- ~(run by update-logs.old)
|=(a=* *update-log:store)
|=(a=* *update-log:zero:store)
==
::
%1
%_ $
-.old %2
graphs.old (~(run by graphs.old) change-revision-graph)
graphs.old (~(run by graphs.old) change-revision-graph:zero-load)
::
update-logs.old
%- ~(run by update-logs.old)
|=(a=* *update-log:store)
|=(a=* *update-log:zero:store)
==
::
%2 [cards this(state old)]
%2
%_ $
-.old %3
update-logs.old (~(run by update-logs.old) update-log-to-one:store)
graphs.old (~(run by graphs.old) marked-graph-to-one:store)
archive.old (~(run by archive.old) marked-graph-to-one:store)
==
::
%3 [cards this(state old)]
==
::
++ change-revision-graph
|= [=graph:store q=(unit mark)]
^- [graph:store (unit mark)]
|^
:_ q
?+ q graph
[~ %graph-validator-link] convert-links
[~ %graph-validator-publish] convert-publish
==
::
++ convert-links
%+ gas:orm *graph:store
%+ turn (tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:: top-level
++ zero-load
:: =* infinitely recurses
=, store=zero:store
=, orm=orm:zero:store
=, orm-log=orm-log:zero:store
|%
++ change-revision-graph
|= [=graph:store q=(unit mark)]
^- [graph:store (unit mark)]
|^
:_ q
?+ q graph
[~ %graph-validator-link] convert-links
[~ %graph-validator-publish] convert-publish
==
::
:+ atom post.node
?: ?=(%empty -.children.node)
[%empty ~]
:- %graph
%+ gas:orm *graph:store
%+ turn (tap:orm p.children.node)
|= [=^atom =node:store]
^- [^^atom node:store]
:: existing comments get turned into containers for revisions
::
:^ atom
post.node(contents ~, hash ~)
%graph
%+ gas:orm *graph:store
:_ ~ :- %1
:_ [%empty ~]
post.node(index (snoc index.post.node atom), hash ~)
::
++ convert-publish
%+ gas:orm *graph:store
%+ turn (tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:: top-level
::
:+ atom post.node
?: ?=(%empty -.children.node)
[%empty ~]
:- %graph
%+ gas:orm *graph:store
%+ turn (tap:orm p.children.node)
|= [=^atom =node:store]
^- [^^atom node:store]
:: existing container for publish note revisions
::
?+ atom !!
%1 [atom node]
%2
++ convert-links
%+ gas:orm *graph:store
%+ turn (tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:: top-level
::
:+ atom post.node
?: ?=(%empty -.children.node)
[%empty ~]
:- %graph
%+ gas:orm *graph:store
%+ turn (tap:orm p.children.node)
|= [=^^atom =node:store]
^- [^^^atom node:store]
:+ atom post.node(contents ~, hash ~)
:- %graph
|= [=^atom =node:store]
^- [^^atom node:store]
:: existing comments get turned into containers for revisions
::
:^ atom
post.node(contents ~, hash ~)
%graph
%+ gas:orm *graph:store
:_ ~ :- %1
:_ ~ :- %0
:_ [%empty ~]
post.node(index (snoc index.post.node atom), hash ~)
==
::
++ convert-publish
%+ gas:orm *graph:store
%+ turn (tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:: top-level
::
:+ atom post.node
?: ?=(%empty -.children.node)
[%empty ~]
:- %graph
%+ gas:orm *graph:store
%+ turn (tap:orm p.children.node)
|= [=^atom =node:store]
^- [^^atom node:store]
:: existing container for publish note revisions
::
?+ atom !!
%1 [atom node]
%2
:+ atom post.node
?: ?=(%empty -.children.node)
[%empty ~]
:- %graph
%+ gas:orm *graph:store
%+ turn (tap:orm p.children.node)
|= [=^^atom =node:store]
^- [^^^atom node:store]
:+ atom post.node(contents ~, hash ~)
:- %graph
%+ gas:orm *graph:store
:_ ~ :- %1
:_ [%empty ~]
post.node(index (snoc index.post.node atom), hash ~)
==
--
::
++ maybe-unix-to-da
|= =atom
^- @
:: (bex 127) is roughly 226AD
?. (lte atom (bex 127))
atom
(add ~1970.1.1 (div (mul ~s1 atom) 1.000))
::
++ convert-unix-timestamped-node
|= =node:store
^- node:store
=. index.post.node
(convert-unix-timestamped-index index.post.node)
?. ?=(%graph -.children.node)
node
:+ post.node
%graph
(convert-unix-timestamped-graph p.children.node)
::
++ convert-unix-timestamped-index
|= =index:store
(turn index maybe-unix-to-da)
::
++ convert-unix-timestamped-graph
|= =graph:store
%+ gas:orm *graph:store
%+ turn
(tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:- (maybe-unix-to-da atom)
(convert-unix-timestamped-node node)
--
::
++ maybe-unix-to-da
|= =atom
^- @
:: (bex 127) is roughly 226AD
?. (lte atom (bex 127))
atom
(add ~1970.1.1 (div (mul ~s1 atom) 1.000))
::
++ convert-unix-timestamped-node
|= =node:store
^- node:store
=. index.post.node
(convert-unix-timestamped-index index.post.node)
?. ?=(%graph -.children.node)
node
:+ post.node
%graph
(convert-unix-timestamped-graph p.children.node)
::
++ convert-unix-timestamped-index
|= =index:store
(turn index maybe-unix-to-da)
::
++ convert-unix-timestamped-graph
|= =graph:store
%+ gas:orm *graph:store
%+ turn
(tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:- (maybe-unix-to-da atom)
(convert-unix-timestamped-node node)
--
::
++ on-watch
@ -205,9 +222,9 @@
[cards this]
::
++ give
|= =update-0:store
|= =action:store
^- (list card)
[%give %fact ~ [%graph-update-0 !>([%0 now.bowl update-0])]]~
[%give %fact ~ [%graph-update-1 !>([now.bowl action])]]~
--
::
++ on-poke
@ -217,10 +234,10 @@
|^
?> (team:title our.bowl src.bowl)
=^ cards state
?+ mark (on-poke:def mark vase)
%graph-update-0 (graph-update !<(update:store vase))
%noun (debug !<(debug-input vase))
%import (poke-import q.vase)
?+ mark (on-poke:def mark vase)
%graph-update-1 (graph-update !<(update:store vase))
%noun (debug !<(debug-input vase))
%import (poke-import q.vase)
==
[cards this]
::
@ -228,7 +245,6 @@
|= =update:store
^- (quip card _state)
|^
?> ?=(%0 -.update)
=? p.update =(p.update *time) now.bowl
?- -.q.update
%add-graph (add-graph p.update +.q.update)
@ -262,7 +278,7 @@
~| "validation of graph {<resource>} failed using mark {<mark>}"
?> (validate-graph graph mark)
=/ =logged-update:store
[%0 time %add-graph resource graph mark overwrite]
[time %add-graph resource graph mark overwrite]
=/ =update-log:store
(gas:orm-log ~ [time logged-update] ~)
:_ %_ state
@ -308,7 +324,7 @@
?< (check-for-duplicates graph ~(key by nodes))
=/ =update-log:store (~(got by update-logs) resource)
=. update-log
(put:orm-log update-log time [%0 time [%add-nodes resource nodes]])
(put:orm-log update-log time [time [%add-nodes resource nodes]])
::
:- (give [/updates]~ [%add-nodes resource nodes])
%_ state
@ -424,7 +440,7 @@
(~(got by graphs) resource)
=/ =update-log:store (~(got by update-logs) resource)
=. update-log
(put:orm-log update-log time [%0 time [%remove-nodes resource indices]])
(put:orm-log update-log time [time [%remove-nodes resource indices]])
=/ [affected-indices=(set index:store) new-graph=graph:store]
(remove-indices resource graph (sort ~(tap in indices) by-lent))
::
@ -511,7 +527,7 @@
(~(got by graphs) resource)
=/ =update-log:store (~(got by update-logs) resource)
=. update-log
(put:orm-log update-log time [%0 time [%add-signatures uid signatures]])
(put:orm-log update-log time [time [%add-signatures uid signatures]])
::
:- (give [/updates]~ [%add-signatures uid signatures])
%_ state
@ -556,7 +572,7 @@
=. update-log
%^ put:orm-log update-log
time
[%0 time [%remove-signatures uid signatures]]
[time [%remove-signatures uid signatures]]
::
:- (give [/updates]~ [%remove-signatures uid signatures])
%_ state
@ -659,9 +675,9 @@
$(cards (weld cards crds), updates t.updates)
::
++ give
|= [paths=(list path) update=update-0:store]
|= [paths=(list path) update=action:store]
^- (list card)
[%give %fact paths [%graph-update-0 !>([%0 now.bowl update])]]~
[%give %fact paths [%graph-update-1 !>([now.bowl update])]]~
--
::
++ debug
@ -696,7 +712,7 @@
|= arc=*
^- (quip card _state)
|^
=/ sty=state-2 [%2 (remake-network ;;(tree-network +.arc))]
=/ sty=state-3 [%3 (remake-network ;;(tree-network +.arc))]
:_ sty
%+ turn ~(tap by graphs.sty)
|= [rid=resource:store =marked-graph:store]
@ -725,8 +741,7 @@
+$ tree-update-logs (tree [resource:store tree-update-log])
+$ tree-update-log (tree [time tree-logged-update])
+$ tree-logged-update
$: %0
p=time
$: p=time
$= q
$% [%add-graph =resource:store =tree-graph mark=(unit ^mark) ow=?]
[%add-nodes =resource:store nodes=(tree [index:store tree-node])]
@ -807,7 +822,7 @@
++ remake-logged-update
|= t=tree-logged-update
^- logged-update:store
:+ %0 p.t
:- p.t
?- -.q.t
%add-graph
:* %add-graph
@ -863,16 +878,16 @@
``noun+!>(q.u.result)
::
[%x %keys ~]
:- ~ :- ~ :- %graph-update-0
!>(`update:store`[%0 now.bowl [%keys ~(key by graphs)]])
:- ~ :- ~ :- %graph-update-1
!>(`update:store`[now.bowl [%keys ~(key by graphs)]])
::
[%x %tags ~]
:- ~ :- ~ :- %graph-update-0
!>(`update:store`[%0 now.bowl [%tags ~(key by tag-queries)]])
:- ~ :- ~ :- %graph-update-1
!>(`update:store`[now.bowl [%tags ~(key by tag-queries)]])
::
[%x %tag-queries ~]
:- ~ :- ~ :- %graph-update-0
!>(`update:store`[%0 now.bowl [%tag-queries tag-queries]])
:- ~ :- ~ :- %graph-update-1
!>(`update:store`[now.bowl [%tag-queries tag-queries]])
::
[%x %graph @ @ ~]
=/ =ship (slav %p i.t.t.path)
@ -880,10 +895,9 @@
=/ result=(unit marked-graph:store)
(~(get by graphs) [ship term])
?~ result [~ ~]
:- ~ :- ~ :- %graph-update-0
:- ~ :- ~ :- %graph-update-1
!> ^- update:store
:+ %0
now.bowl
:- now.bowl
[%add-graph [ship term] `graph:store`p.u.result q.u.result %.y]
::
:: note: near-duplicate of /x/graph
@ -896,10 +910,9 @@
?~ result
~& no-archived-graph+[ship term]
[~ ~]
:- ~ :- ~ :- %graph-update-0
:- ~ :- ~ :- %graph-update-1
!> ^- update:store
:+ %0
now.bowl
:- now.bowl
[%add-graph [ship term] `graph:store`p.u.result q.u.result %.y]
::
[%x %export ~]
@ -913,9 +926,9 @@
=/ graph=(unit marked-graph:store)
(~(get by graphs) [ship term])
?~ graph [~ ~]
:- ~ :- ~ :- %graph-update-0
:- ~ :- ~ :- %graph-update-1
!> ^- update:store
:+ %0 now.bowl
:- now.bowl
:+ %add-nodes
[ship term]
%- ~(gas by *(map index:store node:store))
@ -940,10 +953,9 @@
(turn t.t.t.t.path (cury slav %ud))
=/ node=(unit node:store) (get-node ship term index)
?~ node [~ ~]
:- ~ :- ~ :- %graph-update-0
:- ~ :- ~ :- %graph-update-1
!> ^- update:store
:+ %0
now.bowl
:- now.bowl
:+ %add-nodes
[ship term]
(~(gas by *(map index:store node:store)) [index u.node] ~)
@ -960,10 +972,9 @@
=/ graph
(get-node-children ship term parent)
?~ graph [~ ~]
:- ~ :- ~ :- %graph-update-0
:- ~ :- ~ :- %graph-update-1
!> ^- update:store
:+ %0
now.bowl
:- now.bowl
:+ %add-nodes
[ship term]
%- ~(gas by *(map index:store node:store))
@ -991,10 +1002,9 @@
=/ children
(get-node-children ship term index)
?~ children [~ ~]
:- ~ :- ~ :- %graph-update-0
:- ~ :- ~ :- %graph-update-1
!> ^- update:store
:+ %0
now.bowl
:- now.bowl
:+ %add-nodes
[ship term]
%- ~(gas by *(map index:store node:store))
@ -1018,10 +1028,9 @@
?- -.children.u.node
%empty [~ ~]
%graph
:- ~ :- ~ :- %graph-update-0
:- ~ :- ~ :- %graph-update-1
!> ^- update:store
:+ %0
now.bowl
:- now.bowl
:+ %add-nodes
[ship term]
%- ~(gas by *(map index:store node:store))

View File

@ -4,23 +4,30 @@
|%
++ card card:agent:gall
::
+$ base-state
+$ base-state-0
joining=(map rid=resource [=ship =progress:view])
::
+$ base-state-1
joining=(map rid=resource request:view)
::
+$ state-zero
[%0 base-state]
[%0 base-state-0]
::
+$ state-one
[%1 base-state]
[%1 base-state-0]
::
+$ state-two
[%2 base-state-1]
::
+$ versioned-state
$% state-zero
state-one
state-two
==
::
++ view view-sur
--
=| state-one
=| state-two
=* state -
::
%- agent:dbug
@ -41,10 +48,29 @@
|= =vase
=+ !<(old=versioned-state vase)
=| cards=(list card)
|-
?: ?=(%1 -.old)
`this(state old)
$(-.old %1, cards :_(cards (poke-self:pass:io noun+!>(%cleanup))))
|^
?- -.old
%2 [cards this(state old)]
%1 $(-.old %2, +.old (base-state-to-1 +.old))
%0 $(-.old %1, cards :_(cards (poke-self:pass:io noun+!>(%cleanup))))
==
::
++ base-state-to-1
|= base-state-0
%- ~(gas by *(map resource request:view))
(turn ~(tap by joining) request-to-1)
::
++ request-to-1
|= [rid=resource =ship =progress:view]
^- [resource request:view]
:- rid
%* . *request:view
started now.bowl
hidden %.n
ship ship
progress progress
==
--
::
++ on-poke
|= [=mark =vase]
@ -56,9 +82,11 @@
?. ?=(%group-view-action mark)
(on-poke:def mark vase)
=+ !<(=action:view vase)
?> ?=(%join -.action)
=^ cards state
jn-abet:(jn-start:join:gc +.action)
?+ -.action !!
%join jn-abet:(jn-start:join:gc +.action)
%hide (hide:gc +.action)
==
[cards this]
::
++ on-watch
@ -69,8 +97,7 @@
:_ ~
%+ fact:io
:- %group-view-update
!> ^- update:view
[%initial (~(run by joining) |=([=ship =progress:view] progress))]
!>(`update:view`[%initial joining])
~
==
::
@ -97,6 +124,11 @@
++ grp ~(. grpl bowl)
++ io ~(. agentio bowl)
++ con ~(. conl bowl)
++ hide
|= rid=resource
^- (quip card _state)
:- (fact:io group-view-update+!>([%hide rid]) /all ~)^~
state(joining (~(jab by joining) rid |=(request:view +<(hidden %.y))))
::
++ has-joined
|= rid=resource
@ -107,10 +139,10 @@
::
++ poke-noun
^- (quip card _state)
=; new-joining=(map resource [ship progress:view])
=; new-joining=(map resource request:view)
`state(joining new-joining)
%+ roll ~(tap by joining)
|= [[rid=resource =ship =progress:view] out=_joining]
|= [[rid=resource =request:view] out=_joining]
?. (has-joined rid) out
(~(del by out) rid)
::
@ -128,7 +160,7 @@
++ tx-progress
|= =progress:view
=. joining
(~(put by joining) rid [ship progress])
(~(jab by joining) rid |=(request:view +<(progress progress)))
=; =cage
(emit (fact:io cage /all tx+(en-path:resource rid) ~))
group-view-update+!>([%progress rid progress])
@ -145,9 +177,9 @@
::
++ jn-abed
|= r=resource
=/ [s=^ship =progress:view]
=/ =request:view
(~(got by joining) r)
jn-core(rid r, ship s)
jn-core(rid r, ship ship.request)
::
++ jn-abet
^- (quip card _state)
@ -158,9 +190,14 @@
^+ jn-core
?< (~(has by joining) rid)
=. joining
(~(put by joining) rid [ship %start])
(~(put by joining) rid [%.n now.bowl ship %start])
=. jn-core
(jn-abed rid)
=. jn-core
%- emit
%+ fact:io
group-view-update+!>([%started rid (~(got by joining) rid)])
~[/all]
?< ~|("already joined {<rid>}" (has-joined rid))
=. jn-core
%- emit
@ -246,12 +283,27 @@
::
++ md-fact
|= [=mark =vase]
?. ?=(%metadata-update-0 mark) jn-core
?. ?=(%metadata-update-1 mark) jn-core
=+ !<(=update:metadata vase)
?. ?=(%initial-group -.update) jn-core
?. =(group.update rid) jn-core
=. jn-core (cleanup %done)
?. hidden:(need (scry-group:grp rid)) jn-core
?. hidden:(need (scry-group:grp rid))
=/ list-md=(list [=md-resource:metadata =association:metadata])
%+ skim ~(tap by associations.update)
|= [=md-resource:metadata =association:metadata]
=(app-name.md-resource %groups)
?> ?=(^ list-md)
=* metadatum metadatum.association.i.list-md
?. ?& ?=(%group -.config.metadatum)
?=(^ feed.config.metadatum)
?=(^ u.feed.config.metadatum)
==
jn-core
=* feed resource.u.u.feed.config.metadatum
%- emit
%+ poke-our:(jn-pass-io /pull-feed) %graph-pull-hook
pull-hook-action+!>([%add [entity .]:feed])
%- emit-many
%+ murn ~(tap by associations.update)
|= [=md-resource:metadata =association:metadata]

View File

@ -182,7 +182,7 @@
~[watch-graph:ha]
::
%fact
?. ?=(%graph-update-0 p.cage.sign)
?. ?=(%graph-update-1 p.cage.sign)
(on-agent:def wire sign)
=^ cards state
(graph-update !<(update:graph-store q.cage.sign))
@ -277,7 +277,11 @@
=/ metadatum=(unit metadatum:metadata)
(peek-metadatum:met %graph rid)
?~ metadatum `state
abet:check:(abed:handle-update:ha rid nodes u.group module.u.metadatum)
=/ module=term
?: ?=(%empty -.config.u.metadatum) %$
?: ?=(%group -.config.u.metadatum) %$
module.config.u.metadatum
abet:check:(abed:handle-update:ha rid nodes u.group module)
--
::
++ on-peek on-peek:def
@ -455,7 +459,6 @@
=notif-kind:hook
==
^+ update-core
?: ?=(%none mode.notif-kind) update-core
=/ =stats-index:store
(to-stats-index:store index)
=. update-core

View File

@ -113,7 +113,7 @@
(group-update !<(update:group-store q.cage.sign))
[cards this]
::
%metadata-update-0
%metadata-update-1
=^ cards state
(metadata-update !<(update:metadata q.cage.sign))
[cards this]

View File

@ -24,11 +24,12 @@
state-3
state-4
state-5
state-6
==
+$ unread-stats
[indices=(set index:graph-store) last=@da]
::
+$ base-state
+$ base-state
$: unreads-each=(jug stats-index:store index:graph-store)
unreads-count=(map stats-index:store @ud)
last-seen=(map stats-index:store @da)
@ -45,13 +46,16 @@
[%3 state-two:store]
::
+$ state-4
[%4 base-state]
[%4 state-three:store]
::
+$ state-5
[%5 base-state]
[%5 state-three:store]
::
+$ state-6
[%6 base-state]
::
+$ inflated-state
$: state-5
$: state-6
cache
==
:: $cache: useful to have precalculated, but can be derived from state
@ -92,9 +96,16 @@
=| cards=(list card)
|^
?- -.old
%5
%6
:- (flop cards)
this(-.state old, +.state (inflate-cache:ha old))
::
%5
%_ $
-.old %6
notifications.old (convert-notifications-4 notifications.old)
archive.old (convert-notifications-4 archive.old)
==
::
%4
%_ $
@ -149,15 +160,59 @@
==
==
::
++ convert-notifications-3
|= old=notifications:state-two:store
++ convert-notifications-4
|= old=notifications:state-three:store
%+ gas:orm *notifications:store
^- (list [@da timebox:store])
%+ murn
(tap:orm:state-two:store old)
|= [time=@da =timebox:state-two:store]
(tap:orm:state-three:store old)
|= [time=@da =timebox:state-three:store]
^- (unit [@da timebox:store])
=/ new-timebox=timebox:store
(convert-timebox-4 timebox)
?: =(0 ~(wyt by new-timebox))
~
`[time new-timebox]
::
++ convert-timebox-4
|= =timebox:state-three:store
^- timebox:store
%- ~(gas by *timebox:store)
^- (list [index:store notification:store])
%+ murn
~(tap by timebox)
|= [=index:store =notification:state-three:store]
^- (unit [index:store notification:store])
=/ new-notification=(unit notification:store)
(convert-notification-4 notification)
?~ new-notification ~
`[index u.new-notification]
::
++ convert-notification-4
|= =notification:state-three:store
^- (unit notification:store)
?: ?=(%group -.contents.notification)
`notification
=/ con=(list post:post)
(convert-graph-contents-4 list.contents.notification)
?: =(~ con) ~
=, notification
`[date read %graph con]
::
++ convert-graph-contents-4
|= con=(list post:post-zero:post)
^- (list post:post)
(turn con post-to-one:graph-store)
::
++ convert-notifications-3
|= old=notifications:state-two:store
%+ gas:orm:state-three:store *notifications:state-three:store
^- (list [@da timebox:state-three:store])
%+ murn
(tap:orm:state-two:store old)
|= [time=@da =timebox:state-two:store]
^- (unit [@da timebox:state-three:store])
=/ new-timebox=timebox:state-three:store
(convert-timebox-3 timebox)
?: =(0 ~(wyt by new-timebox))
~
@ -165,21 +220,21 @@
::
++ convert-timebox-3
|= =timebox:state-two:store
^- timebox:store
%- ~(gas by *timebox:store)
^- (list [index:store notification:store])
^- timebox:state-three:store
%- ~(gas by *timebox:state-three:store)
^- (list [index:state-three:store notification:state-three:store])
%+ murn
~(tap by timebox)
|= [=index:store =notification:state-two:store]
^- (unit [index:store notification:store])
=/ new-notification=(unit notification:store)
^- (unit [index:store notification:state-three:store])
=/ new-notification=(unit notification:state-three:store)
(convert-notification-3 notification)
?~ new-notification ~
`[index u.new-notification]
::
++ convert-notification-3
|= =notification:state-two:store
^- (unit notification:store)
^- (unit notification:state-three:store)
?: ?=(%graph -.contents.notification)
`notification
=/ con=(list group-contents:store)
@ -778,7 +833,7 @@
==
::
++ inflate-cache
|= state-5
|= state-6
^+ +.state
=. +.state
*cache

View File

@ -24,6 +24,6 @@
<div id="portal-root"></div>
<script src="/~landscape/js/channel.js"></script>
<script src="/~landscape/js/session.js"></script>
<script src="/~landscape/js/bundle/index.fbd0f73d77fc99808c22.js"></script>
<script src="/~landscape/js/bundle/index.438e593dfe16044b7120.js"></script>
</body>
</html>

View File

@ -9,20 +9,49 @@
|%
+$ card card:agent:gall
::
+$ group-preview-0
$: group=resource
channels=associations-0
members=@ud
channel-count=@ud
metadatum=metadatum-0
==
::
+$ associations-0
(map md-resource:metadata [group=resource metadatum=metadatum-0])
::
+$ metadatum-0
$: title=cord
description=cord
=color:metadata
date-created=time
creator=ship
module=term
picture=url:metadata
preview=?
vip=vip-metadata:metadata
==
::
++ config
^- config:pull-hook
:* %metadata-store
update:metadata
%metadata-update
%metadata-push-hook
0 0
1 1
%.n
==
+$ state-zero
[%0 previews=(map resource group-preview:metadata)]
[%0 previews=(map resource group-preview-0)]
::
+$ state-one
$: %1
pending=(set resource)
previews=(map resource group-preview-0)
==
::
+$ state-two
$: %2
pending=(set resource)
previews=(map resource group-preview:metadata)
==
@ -30,17 +59,16 @@
+$ versioned-state
$% state-zero
state-one
state-two
==
::
--
::
::
%- agent:dbug
%+ verb |
^- agent:gall
%- (agent:pull-hook config)
^- (pull-hook:pull-hook config)
=| state-one
=| state-two
=* state -
=> |_ =bowl:gall
++ def ~(. (default-agent state %|) bowl)
@ -152,7 +180,7 @@
%kick [watch-store^~ state]
::
%fact
?> ?=(%metadata-update-0 p.cage.sign)
?> ?=(%metadata-update-1 p.cage.sign)
=+ !<(=update:metadata q.cage.sign)
?. ?=(%initial-group -.update) `state
`state(previews (~(del by previews) group.update))
@ -176,9 +204,17 @@
++ on-load
|= =vase
=+ !<(old=versioned-state vase)
|-
|^
?- -.old
%1 `this(state old)
%2 `this(state old)
::
%1
%_ $
old
%* . *state-two
previews (~(run by previews.old) preview-to-1)
==
==
::
%0
%_ $
@ -188,6 +224,39 @@
==
==
==
::
++ metadatum-to-1
|= m=metadatum-0
%* . *metadatum:metadata
title title.m
description description.m
color color.m
date-created date-created.m
creator creator.m
preview preview.m
hidden %|
::
config
?: =(module.m %$)
[%group ~]
[%graph module.m]
==
::
++ preview-to-1
|= preview=group-preview-0
^- group-preview:metadata
%= preview
metadatum (metadatum-to-1 metadatum.preview)
channels (associations-to-1 channels.preview)
==
::
++ associations-to-1
|= a=associations-0
^- associations:metadata
%- ~(run by a)
|= [g=resource m=metadatum-0]
[g (metadatum-to-1 m)]
--
::
++ on-poke
|= [=mark =vase]
@ -256,7 +325,7 @@
%+ turn ~(tap by associations)
|= [=md-resource:metadata =association:metadata]
%+ poke-our:pass:io %metadata-store
:- %metadata-update-0
:- %metadata-update-1
!> ^- update:metadata
[%remove resource md-resource]
::

View File

@ -14,7 +14,7 @@
update:store
%metadata-update
%metadata-pull-hook
0 0
1 1
==
::
+$ agent (push-hook:push-hook config)
@ -36,7 +36,7 @@
++ on-init on-init:def
++ on-save !>(~)
++ on-load on-load:def
++ on-poke
++ on-poke
|= [=mark =vase]
?. ?=(%metadata-hook-update mark)
(on-poke:def mark vase)
@ -76,7 +76,7 @@
!(is-managed:grp group.update)
==
~
?^ u.role
?^ u.role
?: ?=(?(%admin %moderator) u.u.role)
`vas
~

View File

@ -64,6 +64,21 @@
resource-indices=(jug md-resource-1 path)
==
::
+$ metadatum-2
$: title=cord
description=cord
=color:store
date-created=time
creator=ship
module=term
picture=url:store
preview=?
vip=vip-metadata:store
==
::
+$ association-2 [group=resource =metadatum-2]
+$ associations-2 (map md-resource:store association-2)
::
+$ cached-indices
$: group-indices=(jug resource md-resource:store)
app-indices=(jug app-name:store [group=resource =resource])
@ -71,6 +86,11 @@
==
::
+$ base-state-2
$: associations=associations-2
~
==
::
+$ base-state-3
$: =associations:store
~
==
@ -83,6 +103,7 @@
+$ state-5 [%5 base-state-1]
+$ state-6 [%6 base-state-1]
+$ state-7 [%7 base-state-2]
+$ state-8 [%8 base-state-3]
+$ versioned-state
$% state-0
state-1
@ -92,10 +113,11 @@
state-5
state-6
state-7
state-8
==
::
+$ inflated-state
$: state-7
$: state-8
cached-indices
==
--
@ -126,7 +148,7 @@
?> (team:title our.bowl src.bowl)
=^ cards state
?+ mark (on-poke:def mark vase)
?(%metadata-action %metadata-update-0)
?(%metadata-action %metadata-update-1)
(poke-metadata-update:mc !<(update:store vase))
::
%import
@ -144,7 +166,7 @@
=/ cards=(list card)
?+ path (on-watch:def path)
[%all ~]
(give %metadata-update-0 !>([%associations associations]))
(give %metadata-update-1 !>([%associations associations]))
::
[%updates ~]
~
@ -152,7 +174,7 @@
[%app-name @ ~]
=/ =app-name:store i.t.path
=/ app-indices (metadata-for-app:mc app-name)
(give %metadata-update-0 !>([%associations app-indices]))
(give %metadata-update-1 !>([%associations app-indices]))
==
[cards this]
::
@ -208,21 +230,16 @@
=| cards=(list card)
|^
=* loop $
?: ?=(%7 -.old)
?: ?=(%8 -.old)
:- cards
%_ state
associations
associations.old
::
resource-indices
(rebuild-resource-indices associations.old)
::
group-indices
(rebuild-group-indices associations.old)
::
app-indices
(rebuild-app-indices associations.old)
associations associations.old
resource-indices (rebuild-resource-indices associations.old)
group-indices (rebuild-group-indices associations.old)
app-indices (rebuild-app-indices associations.old)
==
?: ?=(%7 -.old)
$(old [%8 (associations-2-to-3 associations.old) ~])
?: ?=(%6 -.old)
=/ old-assoc=associations-1
(migrate-app-to-graph-store %chat associations.old)
@ -236,12 +253,37 @@
associations.old associations
==
:: pre-breach, can safely throw away
loop(old *state-7)
loop(old *state-8)
::
++ associations-2-to-3
|= assoc=associations-2
^- associations:store
%- ~(gas by *associations:store)
%+ turn ~(tap by assoc)
|= [m=md-resource:store [g=resource met=metadatum-2]]
[m [g (metadatum-2-to-3 met)]]
::
++ metadatum-2-to-3
|= m=metadatum-2
%* . *metadatum:store
title title.m
description description.m
color color.m
date-created date-created.m
creator creator.m
preview preview.m
hidden %|
::
config
?: =(module.m %$)
[%group ~]
[%graph module.m]
==
::
++ associations-1-to-2
|= assoc=associations-1
^- associations:store
%- ~(gas by *associations:store)
^- associations-2
%- ~(gas by *associations-2)
%+ murn
~(tap by assoc)
|= [[group=path m=md-resource-1] met=metadata-1]
@ -262,7 +304,7 @@
::
++ metadata-1-to-2
|= m=metadata-1
%* . *metadatum:store
%* . *metadatum-2
title title.m
description description.m
color color.m
@ -309,6 +351,8 @@
ship+path.md-resource
[[path [%graph new-path]] m(module app)]
--
::
:: TODO: refactor into a |^ inside the agent core
++ poke-metadata-update
|= upd=update:store
^- (quip card _state)
@ -319,12 +363,13 @@
%initial-group (handle-initial-group +.upd)
==
::
:: TODO: refactor into a |^ inside the agent core
++ poke-import
|= arc=*
^- (quip card _state)
|^
=^ cards state
(on-load !>([%7 (remake-metadata ;;(tree-metadata +.arc))]))
(on-load !>([%8 (remake-metadata ;;(tree-metadata +.arc))]))
:_ state
%+ weld cards
%+ turn ~(tap in ~(key by group-indices))
@ -348,7 +393,7 @@
::
++ remake-metadata
|= tm=tree-metadata
^- base-state-2
^- base-state-3
:* (remake-map associations.tm)
~
==
@ -443,6 +488,6 @@
++ update-subscribers
|= [pax=path =update:store]
^- (list card)
[%give %fact ~[pax] %metadata-update-0 !>(update)]~
[%give %fact ~[pax] %metadata-update-1 !>(update)]~
--
--

View File

@ -12,6 +12,8 @@
$% [%0 observers=(map serial observer:sur)]
[%1 observers=(map serial observer:sur)]
[%2 observers=(map serial observer:sur)]
[%3 observers=(map serial observer:sur)]
[%4 observers=(map serial observer:sur)]
==
::
+$ serial @uv
@ -25,7 +27,7 @@
--
::
%- agent:dbug
=| [%2 observers=(map serial observer:sur)]
=| [%4 observers=(map serial observer:sur)]
=* state -
::
^- agent:gall
@ -39,6 +41,7 @@
:~ (act [%watch %invite-store /invitatory/graph %invite-accepted-graph])
(act [%watch %group-store /groups %group-on-leave])
(act [%watch %group-store /groups %group-on-remove-member])
(act [%watch %metadata-store /updates %md-on-add-group-feed])
==
::
++ act
@ -50,8 +53,7 @@
[our.bowl %observe-hook]
%poke
%observe-action
!> ^- action:sur
action
!>(action)
==
--
::
@ -63,20 +65,31 @@
=/ old-state !<(versioned-state old-vase)
=| cards=(list card)
|-
?: ?=(%2 -.old-state)
=. cards
:_ cards
(act [%watch %group-store /groups %group-on-leave])
?- -.old-state
%4
[cards this(state old-state)]
?: ?=(%1 -.old-state)
::
%3
=. cards
:_ cards
(act [%watch %metadata-store /updates %md-on-add-group-feed])
$(-.old-state %4)
::
%2
=. cards
:_ cards
(act [%watch %group-store /groups %group-on-leave])
$(-.old-state %3)
::
%1
$(-.old-state %2)
=. cards
:_ cards
(act [%watch %group-store /groups %group-on-remove-member])
$(-.old-state %1)
::
%0
=. cards
:_ cards
(act [%watch %group-store /groups %group-on-remove-member])
$(-.old-state %1)
==
::
++ act
|= =action:sur
@ -87,8 +100,7 @@
[our.bowl %observe-hook]
%poke
%observe-action
!> ^- action:sur
action
!>(action)
==
--
::

View File

@ -5,6 +5,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[=resource mark=(unit mark) overwrite=? ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%add-graph resource (gas:orm ~ ~) mark overwrite]]
[now [%add-graph resource (gas:orm ~ ~) mark overwrite]]

View File

@ -12,9 +12,9 @@
contents.post contents
==
::
:- %graph-update-0
:- %graph-update-1
^- update
:+ %0 now
:- now
:+ %add-nodes [our name]
%- ~(gas by *(map index node))
~[[[now]~ [post [%empty ~]]]]

View File

@ -5,6 +5,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[[=resource =index] =signatures ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%add-signatures [resource index] signatures]]
[now [%add-signatures [resource index] signatures]]

View File

@ -5,6 +5,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[=term =resource ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%add-tag term resource]]
[now [%add-tag term resource]]

View File

@ -5,6 +5,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[=resource ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%archive-graph resource]]
[now [%archive-graph resource]]

View File

@ -4,7 +4,7 @@
|= $: [now=@da eny=@uvJ bec=beak]
[[=ship graph=term ~] ~]
==
:- %graph-update-0
:- %graph-update-1
=/ our (scot %p p.bec)
=/ wen (scot %da now)
=/ who (scot %p ship)

View File

@ -4,6 +4,6 @@
|= $: [now=@da eny=@uvJ bec=beak]
[[graph=term =path ~] ~]
==
:- %graph-update-0
:- %graph-update-1
=- ~& update=- -
.^(=update:graph-store %cx path)

View File

@ -5,6 +5,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[=resource ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%remove-graph resource]]
[now [%remove-graph resource]]

View File

@ -5,6 +5,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[=resource indices=(set index) ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%remove-nodes resource indices]]
[now [%remove-nodes resource indices]]

View File

@ -6,6 +6,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[[=resource =index] =signatures ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%remove-signatures [resource index] signatures]]
[now [%remove-signatures [resource index] signatures]]

View File

@ -5,6 +5,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[=term =resource ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%remove-tag term resource]]
[now [%remove-tag term resource]]

View File

@ -5,6 +5,6 @@
|= $: [now=@da eny=@uvJ =beak]
[[=resource ~] ~]
==
:- %graph-update-0
:- %graph-update-1
^- update
[%0 now [%unarchive-graph resource]]
[now [%unarchive-graph resource]]

View File

@ -1,13 +0,0 @@
:: Kiln: clear Gall compiler caches
::
:::: /hoon/wash-gall/hood/gen
::
/? 310
::
::::
!:
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
~ ~
==
[%kiln-wash-gall ~]

View File

@ -60,13 +60,14 @@
|= [m=md-resource:md association:md]
::NOTE we only count graphs for now
?. &(=(%graph app-name.m) =(our creator.metadatum)) ~
`[module.metadatum resource.m]
?. ?=(%graph -.config.metadatum) ~
`[module.config.metadatum resource.m]
:: for sanity checks
::
=/ real=(set resource:re)
=/ upd=update:ga
%+ scry update:ga
[%x %graph-store /keys/graph-update-0]
[%x %graph-store /keys/graph-update-1]
?> ?=(%keys -.q.upd)
resources.q.upd
:: count activity per channel

View File

@ -5,6 +5,101 @@
=, sur
=, pos
|%
::
++ update-log-to-one
|= =update-log:zero
^- ^update-log
%+ gas:orm-log *^update-log
%+ turn (tap:orm-log:zero update-log)
|= [=time =logged-update:zero]
:- time
:- p.logged-update
(logged-update-to-one q.logged-update)
::
++ logged-update-to-one
|= upd=logged-update-0:zero
?+ -.upd upd
%add-graph upd(graph (graph-to-one graph.upd))
%add-nodes upd(nodes (~(run by nodes.upd) node-to-one))
==
::
++ node-to-one
|= =node:zero
(node:(upgrade ,post:zero ,post) node post-to-one)
::
++ graph-to-one
|= =graph:zero
(graph:(upgrade ,post:zero ,post) graph post-to-one)
::
++ marked-graph-to-one
|= [=graph:zero m=(unit mark)]
[(graph-to-one graph) m]
::
++ post-to-one
|= p=post:zero
^- post
p(contents (contents-to-one contents.p))
::
++ contents-to-one
|= cs=(list content:zero)
^- (list content)
%+ murn cs
|= =content:zero
^- (unit ^content)
?: ?=(%reference -.content) ~
`content
::
++ upgrade
|* [in-pst=mold out-pst=mold]
=>
|%
++ in-orm
((ordered-map atom in-node) gth)
+$ in-node
[post=in-pst children=in-internal-graph]
+$ in-graph
((mop atom in-node) gth)
+$ in-internal-graph
$~ [%empty ~]
$% [%graph p=in-graph]
[%empty ~]
==
::
++ out-orm
((ordered-map atom out-node) gth)
+$ out-node
[post=out-pst children=out-internal-graph]
+$ out-graph
((mop atom out-node) gth)
+$ out-internal-graph
$~ [%empty ~]
$% [%graph p=out-graph]
[%empty ~]
==
--
|%
::
++ graph
|= $: gra=in-graph
fn=$-(in-pst out-pst)
==
^- out-graph
%+ gas:out-orm *out-graph
^- (list [atom out-node])
%+ turn (tap:in-orm gra)
|= [a=atom n=in-node]
^- [atom out-node]
[a (node n fn)]
::
++ node
|= [nod=in-node fn=$-(in-pst out-pst)]
^- out-node
:- (fn post.nod)
^- out-internal-graph
?: ?=(%empty -.children.nod)
[%empty ~]
[%graph (graph p.children.nod fn)]
--
:: NOTE: move these functions to zuse
++ nu :: parse number as hex
|= jon=json
@ -78,7 +173,7 @@
%mention (frond %mention (ship ship.c))
%text (frond %text s+text.c)
%url (frond %url s+url.c)
%reference (frond %reference (uid uid.c))
%reference (frond %reference (reference +.c))
%code
%+ frond %code
%- pairs
@ -95,6 +190,28 @@
==
==
::
++ reference
|= ref=^reference
|^
%+ frond -.ref
?- -.ref
%graph (graph +.ref)
%group (group +.ref)
==
::
++ graph
|= [grp=res gra=res idx=^index]
%- pairs
:~ graph+s+(enjs-path:res gra)
group+s+(enjs-path:res grp)
index+(index idx)
==
::
++ group
|= grp=res
s+(enjs-path:res grp)
--
::
++ post
|= p=^post
^- json
@ -113,7 +230,7 @@
|^ (frond %graph-update (pairs ~[(encode q.upd)]))
::
++ encode
|= upd=update-0
|= upd=action
^- [cord json]
?- -.upd
%add-graph
@ -246,9 +363,8 @@
++ update
|= jon=json
^- ^update
:- %0
:- *time
^- update-0
^- action
=< (decode jon)
|%
++ decode
@ -332,10 +448,25 @@
:~ [%mention (su ;~(pfix sig fed:ag))]
[%text so]
[%url so]
[%reference uid]
[%reference reference]
[%code eval]
==
::
++ reference
|^
%- of
:~ graph+graph
group+dejs-path:res
==
::
++ graph
%- ot
:~ group+dejs-path:res
graph+dejs-path:res
index+index
==
--
::
++ tang
|= jon=^json
^- ^tang

View File

@ -1,5 +1,5 @@
/- sur=graph-view, store=graph-store
/+ resource, group-store
/+ resource, group-store, metadata-store
^?
=< [sur .]
=, sur
@ -18,6 +18,8 @@
groupify+groupify
eval+so
pending-indices+pending-indices
create-group-feed+create-group-feed
disable-group-feed+disable-group-feed
::invite+invite
==
::
@ -62,6 +64,17 @@
:~ group+dejs:resource
policy+policy:dejs:group-store
==
::
++ create-group-feed
%- ot
:~ resource+dejs:resource
vip+vip:dejs:metadata-store
==
::
++ disable-group-feed
%- ot
:~ resource+dejs:resource
==
--
--
::

View File

@ -32,6 +32,47 @@
%run-updates ~[resource.q.update]
==
::
++ upgrade
|* [pst=mold out-pst=mold]
=>
|%
++ orm
((ordered-map atom node) gth)
+$ node
[post=pst children=internal-graph]
+$ graph
((mop atom node) gth)
+$ internal-graph
$~ [%empty ~]
$% [%graph p=graph]
[%empty ~]
==
::
++ out-orm
((ordered-map atom out-node) gth)
+$ out-node
[post=out-pst children=out-internal-graph]
+$ out-graph
((mop atom out-node) gth)
+$ out-internal-graph
$~ [%empty ~]
$% [%graph p=out-graph]
[%empty ~]
==
--
|= $: gra=graph
fn=$-(pst out-pst)
==
^- out-graph
%- gas:out-orm
%+ turn (tap:orm gra)
|= [=atom =node]
:- (fn post.node)
?: ?=(%empty -.children.node)
[%empty ~]
$(gra p.children.node)
::
++ get-graph
|= res=resource
^- update:store
@ -43,7 +84,6 @@
^- graph:store
=/ =update:store
(get-graph res)
?> ?=(%0 -.update)
?> ?=(%add-graph -.q.update)
graph.q.update
::
@ -54,7 +94,6 @@
%+ weld
/node-siblings/younger/(scot %p entity.res)/[name.res]/all
(turn index (cury scot %ud))
?> ?=(%0 -.update)
?> ?=(%add-nodes -.q.update)
nodes.q.update
::
@ -65,7 +104,6 @@
%+ weld
/node/(scot %p entity.res)/[name.res]
(turn index (cury scot %ud))
?> ?=(%0 -.update)
?> ?=(%add-nodes -.q.update)
?> ?=(^ nodes.q.update)
q.n.nodes.q.update
@ -99,7 +137,6 @@
^- resources
=+ %+ scry-for ,=update:store
/keys
?> ?=(%0 -.update)
?> ?=(%keys -.q.update)
resources.q.update
::

View File

@ -15,6 +15,7 @@
join+join
leave+leave
invite+invite
hide+dejs-path:resource
==
::
++ create
@ -53,6 +54,15 @@
?- -.upd
%initial (initial +.upd)
%progress (progress +.upd)
%started (started +.upd)
%hide s+(enjs-path:resource +.upd)
==
::
++ started
|= [rid=resource req=^request]
%- pairs
:~ resource+s+(enjs-path:resource rid)
request+(request req)
==
::
++ progress
@ -61,13 +71,21 @@
:~ resource+s+(enjs-path:resource rid)
progress+s+prog
==
++ request
|= req=^request
%- pairs
:~ hidden+b+hidden.req
started+(time started.req)
ship+(ship ship.req)
progress+s+progress.req
==
::
++ initial
|= init=(map resource ^progress)
|= init=(map resource ^request)
%- pairs
%+ turn ~(tap by init)
|= [rid=resource prog=^progress]
:_ s+prog
|= [rid=resource req=^request]
:_ (request req)
(enjs-path:resource rid)
--
++ cleanup-md

View File

@ -46,9 +46,28 @@
[%color s+(scot %ux color.met)]
[%date-created s+(scot %da date-created.met)]
[%creator s+(scot %p creator.met)]
[%module s+module.met]
::
:- %config
?+ -.config.met o+~
%graph
%+ frond %graph
s+module.config.met
::
%group
%+ frond %group
?~ feed.config.met
~
?~ u.feed.config.met
o+~
%- pairs
:~ [%app-name s+app-name.u.u.feed.config.met]
[%resource s+(enjs-path:resource resource.u.u.feed.config.met)]
==
==
::
[%picture s+picture.met]
[%preview b+preview.met]
[%hidden b+hidden.met]
[%vip s+`@t`vip.met]
==
::
@ -145,6 +164,8 @@
%- perk
:~ %reader-comments
%member-metadata
%admin-feed
%host-feed
%$
==
::
@ -156,12 +177,33 @@
[%color nu]
[%date-created (se %da)]
[%creator (su ;~(pfix sig fed:ag))]
[%module so]
[%config config]
[%picture so]
[%preview bo]
[%hidden bo]
[%vip vip]
==
::
++ config
|= jon=^json
^- md-config
?~ jon
[%group ~]
?: ?=(%s -.jon)
[%graph p.jon]
?> ?=(%o -.jon)
:+ %group ~
?. ?& (~(has by p.jon) 'app-name')
(~(has by p.jon) 'resource')
==
~
=/ app-name=^json (~(got by p.jon) 'app-name')
?> ?=(%s -.app-name)
:+ ~
p.app-name
=/ res=^json (~(got by p.jon) 'resource')
(dejs-path:resource res)
::
++ md-resource
^- $-(json ^md-resource)
%- ot

View File

@ -246,7 +246,6 @@
?: (is-root:ver mark)
:_ this
(forward-update:hc mark vase)
::
=^ cards push-hook
(on-poke:og mark vase)
[cards this]
@ -456,6 +455,47 @@
(fact:io cage ~(tap in unversioned))^~
--
::
++ forward-update
|= =cage
^- (list card:agent:gall)
=- lis
=/ vas
(convert-to:ver cage)
%+ roll (resource-for-update q.cage)
|= [rid=resource [lis=(list card:agent:gall) tf-vas=(unit vase)]]
^- [(list card:agent:gall) (unit vase)]
=/ =path
resource+(en-path:resource rid)
=/ =wire (make-wire path)
=* ship entity.rid
=. tf-vas
?. =(our.bowl ship)
:: do not transform before forwarding
::
`vas
:: use cached transform
::
?^ tf-vas tf-vas
:: transform before poking store
::
(transform-proxy-update:og vas)
~| "forwarding failed during transform. mark: {<p.cage>} resource: {<rid>}"
?> ?=(^ tf-vas)
=/ =dock
:- ship
?. =(our.bowl ship)
:: forward to host
::
dap.bowl
:: poke our store
::
store-name.config
=/ cag=^cage
:- current-version:ver
u.tf-vas
:_ tf-vas
[[%pass wire %agent dock %poke cag] lis]
::
++ ver-from-path
|= =path
=/ extra=^path
@ -463,20 +503,6 @@
?> ?=(^ extra)
(slav %ud i.extra)
::
++ forward-update
|= =cage
^- (list card:agent:gall)
=/ =vase
(need (transform-proxy-update:og (convert-to:ver cage)))
%+ roll (resource-for-update vase)
|= [rid=resource cards=(list card:agent:gall)]
=/ =wire
(make-wire resource+(en-path:resource rid))
=/ =dock:agent:gall
:- entity.rid
?:(=(our.bowl entity.rid) store-name.config dap.bowl)
:_(cards (~(poke pass wire) dock current-version:ver vase))
::
++ resource-for-update
|= =vase
^- (list resource)

View File

@ -30,7 +30,7 @@
?~ lyf %.y
=+ %: jael-scry
,deed=[a=life b=pass c=(unit @ux)]
our %deed now /(scot %p q.signature)/(scot %ud p.signature)
our %deed now /(scot %p q.signature)/(scot %ud r.signature)
==
?. =(a.deed r.signature) %.y
:: verify signature from ship at life

View File

@ -719,7 +719,7 @@
(pure:m tid)
::
+$ thread-result
(each vase [term (list tang)])
(each vase [term tang])
::
++ await-thread
|= [file=term args=vase]
@ -727,14 +727,14 @@
^- form:m
;< =bowl:spider bind:m get-bowl
=/ tid (scot %ta (cat 3 'strand_' (scot %uv (sham file eny.bowl))))
=/ tid (scot %ta (cat 3 'strand_' (scot %uv (sham file eny.bowl))))
=/ poke-vase !>([`tid.bowl `tid file args])
;< ~ bind:m (watch-our /awaiting/[tid] %spider /thread-result/[tid])
;< ~ bind:m (poke-our %spider %spider-start poke-vase)
;< ~ bind:m (sleep ~s0) :: wait for thread to start
;< =cage bind:m (take-fact /awaiting/[tid])
;< ~ bind:m (take-kick /awaiting/[tid])
?+ p.cage ~|([%strange-thread-result p.cage file tid] !!)
%thread-done (pure:m %& q.cage)
%thread-fail (pure:m %| !<([term (list tang)] q.cage))
%thread-fail (pure:m %| !<([term tang] q.cage))
==
--

View File

@ -1,20 +1,18 @@
/+ *graph-store
=* as-octs as-octs:mimes:html
::
|_ upd=update
|_ upd=update:zero
++ grad %noun
++ grow
|%
++ noun upd
++ json (update:enjs upd)
++ graph-update upd
++ mime [/application/x-urb-graph-update (as-octs (jam upd))]
--
::
++ grab
|%
++ noun update
++ json update:dejs
++ mime |=([* =octs] ;;(update (cue q.octs)))
++ noun update:zero
++ mime |=([* =octs] ;;(update:zero (cue q.octs)))
--
--

View File

@ -0,0 +1,19 @@
/+ *graph-store
=* as-octs as-octs:mimes:html
::
|_ upd=update
++ grad %noun
++ grow
|%
++ noun upd
++ json (update:enjs upd)
++ mime [/application/x-urb-graph-update (as-octs (jam upd))]
--
::
++ grab
|%
++ noun update
++ json update:dejs
++ mime |=([* =octs] ;;(update (cue q.octs)))
--
--

View File

@ -1,20 +1,18 @@
/+ *graph-store
=* as-octs as-octs:mimes:html
::
|_ upd=update
|_ upd=update:zero
++ grad %noun
++ grow
|%
++ noun upd
++ json (update:enjs upd)
++ graph-update-0 upd
++ mime [/application/x-urb-graph-update (as-octs (jam upd))]
--
::
++ grab
|%
++ noun update
++ json update:dejs
++ mime |=([* =octs] ;;(update (cue q.octs)))
++ noun update:zero
++ mime |=([* =octs] ;;(update:zero (cue q.octs)))
--
--

View File

@ -31,7 +31,6 @@
?+ index.p.i ~
[@ ~] `[%link [0 1] %each %children]
[@ @ %1 ~] `[%comment [1 2] %count %siblings]
[@ @ @ ~] `[%edit-comment [1 2] %none %none]
==
::
++ transform-add-nodes
@ -56,7 +55,7 @@
:: top-level link post; title and url
::
[@ ~]
?> ?=([[%text @] [%url @] ~] contents.p.ip)
?> ?=([[%text @] $%([%url @] [%reference *]) ~] contents.p.ip)
ip
::
:: comment on link post; container structure

View File

@ -0,0 +1,52 @@
/- *post, met=metadata-store, graph=graph-store, hark=hark-graph-hook
|_ i=indexed-post
++ grow
|%
++ noun i
++ graph-permissions-add
|= vip=vip-metadata:met
^- permissions:graph
?. ?=([@ ~] index.p.i)
[%yes %yes %yes]
?+ vip [%yes %yes %yes]
%admin-feed [%yes %no %no]
%host-feed [%no %no %no]
==
::
++ graph-permissions-remove
|= vip=vip-metadata:met
^- permissions:graph
[%yes %self %self]
:: +notification-kind: don't track unreads, notify on replies
::
++ notification-kind
^- (unit notif-kind:hark)
=/ len (lent index.p.i)
?: =(1 len) ~
`[%post [(dec len) len] %none %children]
::
++ transform-add-nodes
|= [=index =post =atom was-parent-modified=?]
^- [^index ^post]
=- [- post(index -)]
?~ index !!
?: ?=([@ ~] index)
[atom ~]
?: was-parent-modified
~|(%cannot-submit-parents-with-prepopulated-children !!)
=/ ind=^index index
(snoc (snip ind) atom)
--
++ grab
|%
:: +noun: validate post
::
++ noun
|= p=*
=/ ip ;;(indexed-post p)
?> ?=(^ contents.p.ip)
ip
--
::
++ grad %noun
--

View File

@ -29,9 +29,7 @@
^- (unit notif-kind:hark)
?+ index.p.i ~
[@ %1 %1 ~] `[%note [0 1] %each %children]
[@ %1 @ ~] `[%edit-note [0 1] %none %none]
[@ %2 @ %1 ~] `[%comment [1 3] %count %siblings]
[@ %2 @ @ ~] `[%edit-comment [1 3] %none %none]
==
::
++ transform-add-nodes
@ -57,7 +55,7 @@
--
++ grab
|%
:: +noun: validate publish post
:: +noun: validate publish note
::
++ noun
|= p=*

View File

@ -3,9 +3,8 @@
++ grad %noun
++ grow
|%
++ noun update
++ metadata-update update
++ json (update:enjs:store update)
++ noun update
++ metadata-update update
--
::
++ grab

View File

@ -0,0 +1,16 @@
/+ store=metadata-store
|_ =update:store
++ grad %noun
++ grow
|%
++ noun update
++ metadata-update update
++ json (update:enjs:store update)
--
::
++ grab
|%
++ noun update:store
++ json action:dejs:store
--
--

View File

@ -5,6 +5,7 @@
|%
++ noun update
++ metadata-update-0 update
++ metadata-update-1 update
++ json (update:enjs:store update)
--
::

View File

@ -12,6 +12,76 @@
:: %yes: May add a node or remove node
+$ permission-level
?(%no %self %yes)
::
++ zero
=< [. post-zero]
=, post-zero
|%
::
++ orm ((ordered-map atom node) gth)
++ orm-log ((ordered-map time logged-update) gth)
::
+$ graph ((mop atom node) gth)
+$ marked-graph [p=graph q=(unit mark)]
::
+$ node [=post children=internal-graph]
+$ graphs (map resource marked-graph)
::
+$ tag-queries (jug term resource)
::
+$ update-log ((mop time logged-update) gth)
+$ update-logs (map resource update-log)
::
::
+$ internal-graph
$~ [%empty ~]
$% [%graph p=graph]
[%empty ~]
==
::
+$ network
$: =graphs
=tag-queries
=update-logs
archive=graphs
validators=(set mark)
==
::
+$ update
$% [%0 p=time q=update-0]
==
::
+$ logged-update
$% [%0 p=time q=logged-update-0]
==
::
+$ logged-update-0
$% [%add-graph =resource =graph mark=(unit mark) overwrite=?]
[%add-nodes =resource nodes=(map index node)]
[%remove-nodes =resource indices=(set index)]
[%add-signatures =uid =signatures]
[%remove-signatures =uid =signatures]
==
::
+$ update-0
$% logged-update-0
[%remove-graph =resource]
::
[%add-tag =term =resource]
[%remove-tag =term =resource]
::
[%archive-graph =resource]
[%unarchive-graph =resource]
[%run-updates =resource =update-log]
::
:: NOTE: cannot be sent as pokes
::
[%keys =resources]
[%tags tags=(set term)]
[%tag-queries =tag-queries]
==
--
+$ graph ((mop atom node) gth)
+$ marked-graph [p=graph q=(unit mark)]
::
@ -38,15 +108,12 @@
validators=(set mark)
==
::
+$ update
$% [%0 p=time q=update-0]
==
+$ update [p=time q=action]
::
+$ logged-update
$% [%0 p=time q=logged-update-0]
==
+$ logged-update [p=time q=logged-action]
::
+$ logged-update-0
+$ logged-action
$% [%add-graph =resource =graph mark=(unit mark) overwrite=?]
[%add-nodes =resource nodes=(map index node)]
[%remove-nodes =resource indices=(set index)]
@ -54,8 +121,8 @@
[%remove-signatures =uid =signatures]
==
::
+$ update-0
$% logged-update-0
+$ action
$% logged-action
[%remove-graph =resource]
::
[%add-tag =term =resource]

View File

@ -1,4 +1,4 @@
/- *group, store=graph-store
/- *group, store=graph-store, met=metadata-store
/+ resource
^?
|%
@ -43,6 +43,8 @@
[%forward rid=resource =update:store]
[%eval =cord]
[%pending-indices pending=(map hash:store index:store)]
[%create-group-feed group=resource vip=vip-metadata:met]
[%disable-group-feed group=resource]
==
--

View File

@ -2,6 +2,13 @@
^?
|%
::
+$ request
$: hidden=?
started=time
=ship
=progress
==
::
+$ action
$% :: host side
[%create name=term =policy title=@t description=@t]
@ -11,6 +18,8 @@
[%leave =resource]
::
[%invite =resource ships=(set ship) description=@t]
:: pending ops
[%hide =resource]
==
::
@ -21,7 +30,9 @@
?(%no-perms %strange %done)
::
+$ update
$% [%initial initial=(map resource progress)]
$% [%initial initial=(map resource request)]
[%started =resource =request]
[%progress =resource =progress]
[%hide =resource]
==
--

View File

@ -33,7 +33,7 @@
==
::
+$ contents
$% [%graph =(list post:post)]
$% [%graph =(list post:post-zero:post)]
[%group =(list group-contents)]
[%chat =(list envelope:chat-store)]
==
@ -75,7 +75,7 @@
[date=@da read=? =contents]
::
+$ contents
$% [%graph =(list post:post)]
$% [%graph =(list post:post-zero:post)]
[%group =(list group-contents)]
==
::
@ -90,6 +90,38 @@
::
--
::
++ state-three
=< state
|%
+$ state
$: unreads-each=(jug stats-index index:graph-store)
unreads-count=(map stats-index @ud)
last-seen=(map stats-index @da)
=notifications
archive=notifications
current-timebox=@da
dnd=_|
==
::
++ orm
((ordered-map @da timebox) gth)
::
+$ notification
[date=@da read=? =contents]
::
+$ contents
$% [%graph =(list post:post-zero:post)]
[%group =(list group-contents)]
==
::
+$ timebox
(map index notification)
::
+$ notifications
((mop @da timebox) gth)
::
--
::
+$ index
$% $: %graph
group=resource

View File

@ -25,18 +25,35 @@
:: %reader-comments: Allow readers to comment, regardless
:: of whether they can write. (notebook, collections)
:: %member-metadata: Allow members to add channels (groups)
:: %host-feed: Only host can post to group feed
:: %admin-feed: Only admins and host can post to group feed
:: %$: No variation
::
+$ vip-metadata ?(%reader-comments %member-metadata %$)
+$ vip-metadata
$? %reader-comments
%member-metadata
%host-feed
%admin-feed
%$
==
::
+$ md-config
$~ [%empty ~]
$% [%group feed=(unit (unit md-resource))]
[%graph module=term]
[%empty ~]
==
::
+$ metadatum
$: title=cord
description=cord
=color
date-created=time
creator=ship
module=term
config=md-config
picture=url
preview=?
hidden=?
vip=vip-metadata
==
::

View File

@ -1,5 +1,27 @@
/- *resource
|%
::
++ post-zero
|%
::
+$ content
$% [%text text=cord]
[%mention =ship]
[%url url=cord]
[%code expression=cord output=(list tank)]
[%reference =uid]
==
::
+$ post
$: author=ship
=index
time-sent=time
contents=(list content)
hash=(unit hash)
=signatures
==
--
+$ index (list atom)
+$ uid [=resource =index]
::
@ -26,13 +48,16 @@
contents=(list content)
==
::
+$ reference
$% [%graph group=resource =uid]
[%group group=resource]
==
::
+$ content
$% [%text text=cord]
[%mention =ship]
[%url url=cord]
[%code expression=cord output=(list tank)]
[%reference =uid]
:: TODO: maybe use a cask?
::[%cage =cage]
[%reference =reference]
==
--

View File

@ -1,30 +1,299 @@
/- spider
/+ strandio
=, strand=strand:spider
=, clay
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
|^
=+ !<([~ =a=path =b=path] arg)
=/ a-mark=mark -:(flop a-path)
=/ b-mark=mark -:(flop b-path)
?. =(a-mark b-mark)
(strand-fail:strandio %files-not-same-type ~)
:: workaround to make the shallow flag optional. if it's specified we
:: do require a non-empty path - however this shouldn't be called with
:: empty paths to begin with.
=+ !<([~ =a=path b=$~([/hi &] $^([(lest @ta) flag] path))] arg)
=/ [b-path=path shallow=flag] ?:(?=([^ *] b) b [`path`b |])
=/ a-beam (need (de-beam a-path))
;< =a=cage bind:m (get-file a-path)
;< =b=cage bind:m (get-file b-path)
;< =dais:clay bind:m (build-mark:strandio -.a-beam a-mark)
(pure:m (~(diff dais q.a-cage) q.b-cage))
=/ b-beam (need (de-beam b-path))
;< a-dome=dome bind:m (get-from-clay a-beam dome %v)
;< b-dome=dome bind:m (get-from-clay b-beam dome %v)
;< diffs=(list diff-type) bind:m (diff-beams a-beam b-beam)
%- pure:m
!> ^- tang
:: our tang is built in reverse order
%- flop
?: shallow
(format-shallow diffs a-beam b-beam)
(format-deep diffs a-beam b-beam)
::
:: $diff-type: type for diffs produced.
:: 1. %txt-diff is a standard diff (i.e. for hoon and txt files)
:: 2. %directory-diff shows unique files between two directories
:: 3. %other is for files that don't use txt-diff - we just take
:: the mug of the files
+$ diff-type
:: paths of the diffed beams
$: a=path
b=path
$% [%txt-diff diff=(urge cord)]
[%directory-diff p=(list path) q=(list path)]
[%other p=@ q=@]
==
==
:: +diff-is-empty: check if a diff is empty (for two identical files)
::
++ diff-is-empty
|= d=diff-type
^- flag
?: ?=([%txt-diff *] +.+.d)
:: levy produces & on empty lists
%+ levy
diff.d
|= u=(unce cord)
^- flag
-:u
?: ?=([%directory-diff *] +.+.d)
=(p.d q.d)
=(p.d q.d)
:: +get-file: retrieve a cage of a file from clay
::
++ get-file
|= =path
|= =beam
=/ m (strand ,cage)
^- form:m
=/ beam (need (de-beam path))
;< =riot:clay bind:m
(warp:strandio p.beam q.beam ~ %sing %x r.beam s.beam)
?~ riot
(strand-fail:strandio %file-not-found >path< ~)
(strand-fail:strandio %file-not-found >s.beam< ~)
(pure:m r.u.riot)
:: +get-from-clay: retrieve other data from clay based on care
::
++ get-from-clay
|* [=beam mol=mold =care]
=/ m (strand ,mol)
^- form:m
;< =riot:clay bind:m
(warp:strandio p.beam q.beam ~ %sing care r.beam s.beam)
?~ riot
(strand-fail:strandio %file-not-found >s.beam< ~)
(pure:m !<(mol q.r.u.riot))
:: +diff-beams: recursively diff two beams. produces a vase
:: of (list diff-type)
::
++ diff-beams
=<
|= [a=beam b=beam]
=/ m (strand ,(list diff-type))
^- form:m
;< hash-a=@ bind:m (get-from-clay a @ %z)
;< hash-b=@ bind:m (get-from-clay b @ %z)
:: if the recursive hashes for each beam are the same we bail early
?: =(hash-a hash-b)
(pure:m *(list diff-type))
;< a-arch=arch bind:m (get-from-clay a arch %y)
;< b-arch=arch bind:m (get-from-clay b arch %y)
;< file-diff=(unit diff-type) bind:m (diff-file-contents a a-arch b b-arch)
:: get distinct files along with shared files
=/ a-keys=(set @t) ~(key by dir.a-arch)
=/ b-keys=(set @t) ~(key by dir.b-arch)
:: unique children
=/ a-unique-children=(set @t) (~(dif in a-keys) b-keys)
=/ b-unique-children=(set @t) (~(dif in b-keys) a-keys)
;< a-unique=(list path) bind:m (format-unique-children a a-arch a-unique-children)
;< b-unique=(list path) bind:m (format-unique-children b b-arch b-unique-children)
=/ unique-diff=diff-type [s.a s.b %directory-diff a-unique b-unique]
:: shared children
=/ find-common-diffs
|.
^- form:m
=| acc=(list diff-type)
=/ common-children=(list @t) ~(tap in (~(int in a-keys) b-keys))
|-
=* loop $
^- form:m
?~ common-children
(pure:m acc)
=/ child=@t i.common-children
=/ new-a=beam a(s (snoc s.a child))
=/ new-b=beam b(s (snoc s.b child))
;< diffs=(list diff-type) bind:m
(diff-beams new-a new-b)
:: ;< introduces another $ so we use "loop" instead.
%= loop
acc (weld diffs acc)
common-children t.common-children
==
;< common-diffs=(list diff-type) bind:m (find-common-diffs)
%- pure:m
^- (list diff-type)
%+ skip
;: weld
(drop file-diff)
[unique-diff ~]
common-diffs
==
diff-is-empty
|%
:: +format-unique-children: produce list of paths representing
:: files that are unique within a directory.
::
++ format-unique-children
|= [bem=beam ark=arch children=(set @t)]
=/ m (strand ,(list path))
^- form:m
=/ children=(list @t) ~(tap in children)
=| acc=(list path)
|-
=* loop $
^- form:m
?~ children
(pure:m acc)
:: the %t care gives all paths with the specified prefix
;< res=(list path) bind:m (get-from-clay bem(s (snoc s.bem i.children)) (list path) %t)
%= loop
acc (weld res acc)
children t.children
==
:: +diff-file-contents: diff two files at specified beams,
:: producing a vase of (unit diff-type)
++ diff-file-contents
=<
|= [a=beam a-arch=arch b=beam b-arch=arch]
=/ m (strand ,(unit diff-type))
^- form:m
?: =(fil.a-arch fil.b-arch)
(pure:m *(unit diff-type))
?~ fil.a-arch
:: only b has contents
%- pure:m
^- (unit diff-type)
%- some
:^ s.a
s.b
%txt-diff
:_ ~
^- (unce cord)
:+ %|
~
~[(format-file-content-missing s.b q.b)]
?~ fil.b-arch
:: only a has contents
%- pure:m
^- (unit diff-type)
%- some
:^ s.a
s.b
%txt-diff
:_ ~
^- (unce cord)
:+ %|
~[(format-file-content-missing s.a q.a)]
~
:: have two file contents - check that they have
:: the same mark.
=/ mar=mark -:(flop s.a)
?: !=(mar -:(flop s.b))
(strand-fail:strandio %files-not-same-type >s.a< >s.b< ~)
;< =a=cage bind:m (get-file a)
;< =b=cage bind:m (get-file b)
;< =dais:clay bind:m (build-mark:strandio -.a mar)
:: for txt-diff we produce an actual diff with type (urge cord).
:: for all other marks we just take the mug)
%- pure:m
?: =(form:dais %txt-diff)
^- (unit diff-type)
%- some
:^ s.a
s.b
%txt-diff
!<((urge cord) (~(diff dais q.a-cage) q.b-cage))
^- (unit diff-type)
%- some
:^ s.a
s.b
%other
:: For some reason, vases for identical files on different desks
:: can sometimes have different types. for this reason, we only
:: take the mug of the data.
[(mug q.q.a-cage) (mug q.q.b-cage)]
|%
++ format-file-content-missing
|= [p=path d=desk]
^- cord
%- crip
;: weld
"only "
<p>
" in desk "
<d>
" has file contents"
==
--
--
:: +format-beams: helper to combine two beams into a tank
::
++ format-beams
|= [a=beam b=beam]
^- tank
[%rose [" " ~ ~] ~[(smyt (en-beam a)) (smyt (en-beam b))]]
:: +format-directory-diff: helper for producing a tank based on
:: a %directory-diff
::
++ format-directory-diff
|= [paths=(list path) =beam]
^- tang
=/ prefix=tape (weld "only in " <(en-beam beam)>)
%+ turn
paths
|= p=path
^- tank
[%rose [": " ~ ~] [leaf+prefix (smyt p) ~]]
:: +format-shallow: converts a list of diff-type generated
:: between desks a and b into a tang in a shallow manner (just
:: listing files that differ).
::
++ format-shallow
|= [diffs=(list diff-type) a=beam b=beam]
^- tang
%+ reel
diffs
|= [d=diff-type acc=tang]
^- tang
?: ?=([%txt-diff *] +.+.d)
[(format-beams a(s a.d) b(s b.d)) acc]
?: ?=([%other *] +.+.d)
[(format-beams a(s a.d) b(s b.d)) acc]
?: ?=([%directory-diff *] +.+.d)
;: weld
(format-directory-diff p.d a)
(format-directory-diff q.d b)
acc
==
!!
:: +format-deep: converts a list of diff-type generated
:: between desks a and b into a tang in a deep manner (preserving
:: diff information for files)
++ format-deep
|= [diffs=(list diff-type) a=beam b=beam]
^- tang
%+ reel
diffs
|= [d=diff-type acc=tang]
^- tang
?: ?=([%txt-diff *] +.+.d)
:+ (format-beams a(s a.d) b(s b.d))
>diff.d<
acc
?: ?=([%directory-diff *] +.+.d)
;: weld
(format-directory-diff p.d a)
(format-directory-diff q.d b)
acc
==
?: ?=([%other *] +.+.d)
=/ a-tank=tank (smyt (en-beam a(s a.d)))
=/ b-tank=tank (smyt (en-beam b(s b.d)))
:+ [%rose [" " "files " ~] ~[a-tank b-tank]]
[%rose [" and " "have mugs: " ~] ~[leaf+<p.d> leaf+<q.d>]]
acc
!!
--

View File

@ -10,7 +10,6 @@
;< =update:store bind:m
%+ scry:strandio update:store
/gx/graph-store/graph/(scot %p entity.rid)/[name.rid]/noun
?> ?=(%0 -.update)
?> ?=(%add-graph -.q.update)
(pure:m graph.q.update)
--
@ -33,7 +32,7 @@
=/ hashes (nodes-to-pending-indices nodes.q.update)
;< ~ bind:m
%^ poke-our %graph-push-hook
%graph-update-0
%graph-update-1
!>(update)
(pure:m !>(`action:graph-view`[%pending-indices hashes]))
::
@ -88,10 +87,9 @@
%_ node
hash.post `hash
::
:: TODO: enable signing our own post as soon as we're ready
:: signatures.post
:: %- ~(gas in *signatures:store)
:: [(sign:sig our.bowl now.bowl hash)]~
signatures.post
%- ~(gas in *signatures:store)
[(sign:sig our.bowl now.bowl hash)]~
::
children
?: ?=(%empty -.children.node)

View File

@ -0,0 +1,71 @@
/- spider,
graph=graph-store,
met=metadata-store,
push-hook
/+ strandio, resource, graph-view
::
=* strand strand:spider
=* poke poke:strandio
=* poke-our poke-our:strandio
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<([~ =action:graph-view] arg)
?> ?=(%create-group-feed -.action)
;< =bowl:spider bind:m get-bowl:strandio
?. =(our.bowl entity.group.action)
(strand-fail:strandio %bad-request ~)
=/ feed-rid=resource
:- entity.group.action
%- crip
%+ weld (trip name.group.action)
%+ weld "-"
(trip (scot %ud (mod eny.bowl 10.000)))
;< association=(unit association:met) bind:m
%+ scry:strandio (unit association:met)
%- zing
:~ /gx/metadata-store/metadata/groups
(en-path:resource group.action)
/noun
==
?~ association
~|('No group exists, cannot make group feed.' !!)
=* metadatum metadatum.u.association
?> ?=(%group -.config.metadatum)
?> ?| ?=(~ feed.config.metadatum)
?=([~ ~] feed.config.metadatum)
==
;< ~ bind:m
%+ poke-our %graph-store
:- %graph-update-1
!> ^- update:graph
[now.bowl %add-graph feed-rid *graph:graph `%graph-validator-post %&]
;< ~ bind:m
(poke-our %graph-push-hook %push-hook-action !>([%add feed-rid]))
;< ~ bind:m
%+ poke-our %metadata-push-hook
:- %metadata-update-1
!> ^- action:met
:^ %add
group.action
groups+group.action
metadatum(feed.config ``[%graph feed-rid])
;< ~ bind:m
%+ poke-our %metadata-push-hook
:- %metadata-update-1
!> ^- action:met
:^ %add
group.action
graph+feed-rid
%* . *metadatum:met
title 'Group Feed'
date-created now.bowl
creator our.bowl
config [%graph %post]
preview %.n
hidden %.y
vip vip.action
==
(pure:m !>(feed-rid))

View File

@ -52,9 +52,9 @@
=/ overwrite=?
?=(%policy -.associated.action)
=/ =update:graph
[%0 now.bowl %add-graph rid.action *graph:graph mark.action overwrite]
[now.bowl %add-graph rid.action *graph:graph mark.action overwrite]
;< ~ bind:m
(poke-our %graph-store graph-update-0+!>(update))
(poke-our %graph-store graph-update-1+!>(update))
;< ~ bind:m
(poke-our %graph-push-hook %push-hook-action !>([%add rid.action]))
::
@ -71,13 +71,14 @@
description description.action
date-created now.bowl
creator our.bowl
module module.action
config [%graph module.action]
preview %.n
hidden %.n
==
=/ met-action=action:met
[%add group graph+rid.action metadatum]
;< ~ bind:m
(poke-our %metadata-push-hook metadata-update-0+!>(met-action))
(poke-our %metadata-push-hook metadata-update-1+!>(met-action))
::
:: Send invites
::

View File

@ -36,12 +36,12 @@
^- form:m
;< =bowl:spider bind:m get-bowl:strandio
;< ~ bind:m
(poke-our %graph-store %graph-update-0 !>([%0 now.bowl %remove-graph rid]))
(poke-our %graph-store %graph-update-1 !>([now.bowl %remove-graph rid]))
;< ~ bind:m
(poke-our %graph-push-hook %push-hook-action !>([%remove rid]))
;< ~ bind:m
%+ poke-our %metadata-push-hook
:- %metadata-update-0
:- %metadata-update-1
!> ^- action:metadata
[%remove group-rid [%graph rid]]
(pure:m ~)

View File

@ -0,0 +1,47 @@
/- spider,
met=metadata-store,
graph=graph-store
/+ strandio, resource, graph-view
::
=* strand strand:spider
=* poke-our poke-our:strandio
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<([~ =action:graph-view] arg)
?> ?=(%disable-group-feed -.action)
;< =bowl:spider bind:m get-bowl:strandio
?. =(our.bowl entity.group.action)
(strand-fail:strandio %bad-request ~)
;< association=(unit association:met) bind:m
%+ scry:strandio (unit association:met)
%- zing
:~ /gx/metadata-store/metadata/groups
(en-path:resource group.action)
/noun
==
?~ association
~|('No group exists, cannot make group feed.' !!)
=* metadatum metadatum.u.association
?> ?=(%group -.config.metadatum)
?> ?| ?=(~ feed.config.metadatum)
?=([~ ^] feed.config.metadatum)
==
;< ~ bind:m
%+ poke-our %metadata-push-hook
:- %metadata-update-1
!> ^- action:met
:^ %add
group.action
groups+group.action
metadatum(feed.config [~ ~])
?: ?=([~ ^] feed.config.metadatum)
;< ~ bind:m
%+ poke-our %graph-store
:- %graph-update-1
!> ^- update:graph
[now.bowl [%archive-graph resource.u.u.feed.config.metadatum]]
(pure:m !>(~))
(pure:m !>(~))

View File

@ -39,7 +39,7 @@
;< ~ bind:m
(poke-our %graph-pull-hook %pull-hook-action !>([%remove rid]))
;< ~ bind:m
(poke-our %graph-store %graph-update-0 !>([%0 now [%remove-graph rid]]))
(poke-our %graph-store %graph-update-1 !>([now [%remove-graph rid]]))
(pure:m ~)
--
::

View File

@ -17,7 +17,7 @@
;< =bowl:spider bind:m get-bowl:strandio
:: unarchive graph and share it
;< ~ bind:m
(poke-our %graph-store %graph-update-0 !>([%0 now.bowl %unarchive-graph rid]))
(poke-our %graph-store %graph-update-1 !>([now.bowl %unarchive-graph rid]))
;< ~ bind:m
(poke-our %graph-push-hook %push-hook-action !>([%add rid]))
::
@ -29,7 +29,7 @@
description description
date-created now.bowl
creator our.bowl
module module
config [%graph module]
==
;< ~ bind:m
%+ poke-our %metadata-push-hook

View File

@ -40,6 +40,7 @@
description description.action
date-created now.bowl
creator our.bowl
config [%group ~]
==
=/ met-action=action:metadata
[%add rid groups+rid metadatum]

View File

@ -70,9 +70,9 @@
;< ~ bind:m
%+ raw-poke
[our.bowl %graph-store]
:- %graph-update-0
:- %graph-update-1
!> ^- update:gra
[%0 now.bowl [%archive-graph app-resource]]
[now.bowl [%archive-graph app-resource]]
;< ~ bind:m
%+ raw-poke
[our.bowl %graph-pull-hook]

View File

@ -0,0 +1,31 @@
/- spider, graph-view, met=metadata-store
/+ strandio
::
=* strand strand:spider
=* poke-our poke-our:strandio
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<([~ =update:met] arg)
?. ?=(%add -.update)
(pure:m !>(~))
;< =bowl:spider bind:m get-bowl:strandio
?: =(our.bowl entity.group.update)
(pure:m !>(~))
?. ?=(%group -.config.metadatum.update)
(pure:m !>(~))
?~ feed.config.metadatum.update
(pure:m !>(~))
?~ u.feed.config.metadatum.update
(pure:m !>(~))
=* feed u.u.feed.config.metadatum.update
;< ~ bind:m
%+ poke-our %spider
=- spider-start+!>([`tid.bowl ~ %graph-join -])
%+ slop !>(~)
!> ^- action:graph-view
[%join resource.feed entity.resource.feed]
(pure:m !>(~))

View File

@ -13,8 +13,8 @@
=/ =index:post [id]~
=/ =post:post [our index wen [%text body]~ ~ ~]
=/ =node:graph-store [post %empty ~]
=/ act=update:graph-store [%0 wen %add-nodes rid (my [index node] ~)]
(poke-app our %graph-push-hook %graph-update-0 act)
=/ act=update:graph-store [wen %add-nodes rid (my [index node] ~)]
(poke-app our %graph-push-hook %graph-update-1 act)
--
::
^- thread:spider

View File

@ -13,8 +13,8 @@
=/ =index:post [id]~
=/ =post:post [our index wen [%text body]~ ~ ~]
=/ =node:graph-store [post %empty ~]
=/ act=update:graph-store [%0 wen %add-nodes rid (my [index node] ~)]
(poke-app our %graph-push-hook %graph-update-0 act)
=/ act=update:graph-store [wen %add-nodes rid (my [index node] ~)]
(poke-app our %graph-push-hook %graph-update-1 act)
--
::
^- thread:spider

View File

@ -67,12 +67,12 @@ if(urbitrc.URL) {
return '/index.js'
}
},
'/~landscape/js/serviceworker.js': {
target: 'http://localhost:9000',
pathRewrite: (req, path) => {
return '/serviceworker.js'
}
},
// '/~landscape/js/serviceworker.js': {
// target: 'http://localhost:9000',
// pathRewrite: (req, path) => {
// return '/serviceworker.js'
// }
// },
'**': {
changeOrigin: true,
target: urbitrc.URL,
@ -88,7 +88,7 @@ module.exports = {
mode: 'development',
entry: {
app: './src/index.js',
serviceworker: './src/serviceworker.js'
// serviceworker: './src/serviceworker.js'
},
module: {
rules: [

View File

@ -1783,36 +1783,30 @@
"dependencies": {
"@babel/runtime": {
"version": "7.12.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
"bundled": true,
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"@types/lodash": {
"version": "4.14.168",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q=="
"bundled": true
},
"@urbit/eslint-config": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@urbit/eslint-config/-/eslint-config-1.0.0.tgz",
"integrity": "sha512-Xmzb6MvM7KorlPJEq/hURZZ4BHSVy/7CoQXWogsBSTv5MOZnMqwNKw6yt24k2AO/2UpHwjGptimaNLqFfesJbw=="
"bundled": true
},
"big-integer": {
"version": "1.6.48",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
"bundled": true
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
"bundled": true
},
"regenerator-runtime": {
"version": "0.13.7",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
"bundled": true
}
}
},

View File

@ -1,6 +1,6 @@
import BaseApi from './base';
import { StoreState } from '../store/type';
import { Patp, Path } from '@urbit/api';
import { Patp, Path, Resource } from '@urbit/api';
import _ from 'lodash';
import { makeResource, resourceFromPath } from '../lib/group';
import { GroupPolicy, Enc, Post, Content } from '@urbit/api';
@ -83,7 +83,7 @@ export default class GraphApi extends BaseApi<StoreState> {
joiningGraphs = new Set<string>();
private storeAction(action: any): Promise<any> {
return this.action('graph-store', 'graph-update-0', action);
return this.action('graph-store', 'graph-update-1', action);
}
private viewAction(threadName: string, action: any) {
@ -91,7 +91,7 @@ export default class GraphApi extends BaseApi<StoreState> {
}
private hookAction(ship: Patp, action: any): Promise<any> {
return this.action('graph-push-hook', 'graph-update-0', action);
return this.action('graph-push-hook', 'graph-update-1', action);
}
createManagedGraph(
@ -227,7 +227,7 @@ export default class GraphApi extends BaseApi<StoreState> {
};
const pendingPromise = this.spider(
'graph-update-0',
'graph-update-1',
'graph-view-action',
'graph-add-nodes',
action
@ -259,6 +259,30 @@ export default class GraphApi extends BaseApi<StoreState> {
*/
}
async enableGroupFeed(group: Resource, vip: any = ''): Promise<Resource> {
const { resource } = await this.spider(
'graph-view-action',
'resource',
'graph-create-group-feed',
{
"create-group-feed": { resource: group, vip }
}
);
return resource;
}
async disableGroupFeed(group: Resource): Promise<void> {
await this.spider(
'graph-view-action',
'json',
'graph-disable-group-feed',
{
"disable-group-feed": { resource: group }
}
);
}
removeNodes(ship: Patp, name: string, indices: string[]) {
return this.hookAction(ship, {
'remove-nodes': {
@ -336,15 +360,17 @@ export default class GraphApi extends BaseApi<StoreState> {
});
}
getNode(ship: string, resource: string, index: string) {
const idx = index.split('/').map(numToUd).join('/');
return this.scry<any>(
async getNode(ship: string, resource: string, index: string) {
const idx = index.split('/').map(decToUd).join('/');
const data = await this.scry<any>(
'graph-store',
`/node/${ship}/${resource}${idx}`
).then((node) => {
this.store.handleEvent({
data: node
});
);
const node = data['graph-update'];
this.store.handleEvent({
data: {
"graph-update-loose": node
}
});
}
}

View File

@ -78,6 +78,10 @@ export default class GroupsApi extends BaseApi<StoreState> {
});
}
hide(resource: string) {
return this.viewAction({ hide: resource });
}
private proxyAction(action: GroupAction) {
return this.action('group-push-hook', 'group-update-0', action);
}

View File

@ -20,8 +20,9 @@ export default class MetadataApi extends BaseApi<StoreState> {
color,
'date-created': dateCreated,
creator,
'module': moduleName,
config: { graph: moduleName },
picture: '',
hidden: false,
preview: false,
vip: ''
}
@ -102,6 +103,6 @@ export default class MetadataApi extends BaseApi<StoreState> {
}
private metadataAction(data) {
return this.action('metadata-push-hook', 'metadata-update-0', data);
return this.action('metadata-push-hook', 'metadata-update-1', data);
}
}

View File

@ -0,0 +1,111 @@
import {
Association,
resourceFromPath,
Group,
ReferenceContent,
} from "@urbit/api";
export function getPermalinkForGraph(
group: string,
graph: string,
index = ""
) {
const groupLink = getPermalinkForAssociatedGroup(group);
const { ship, name } = resourceFromPath(graph);
return `${groupLink}/graph/${ship}/${name}${index}`;
}
function getPermalinkForAssociatedGroup(group: string) {
const { ship, name } = resourceFromPath(group);
return `web+urbitgraph://group/${ship}/${name}`;
}
type Permalink = GraphPermalink | GroupPermalink;
interface GroupPermalink {
type: "group";
group: string;
link: string;
}
interface GraphPermalink {
type: "graph";
link: string;
graph: string;
group: string;
index: string;
}
function parseGraphPermalink(
link: string,
group: string,
segments: string[]
): GraphPermalink | null {
const [kind, ship, name, ...index] = segments;
if (kind !== "graph") {
return null;
}
const graph = `/ship/${ship}/${name}`;
return {
type: "graph",
link: link.slice(16),
graph,
group,
index: `/${index.join("/")}`,
};
}
export function permalinkToReference(link: Permalink): ReferenceContent {
if(link.type === 'graph') {
const reference = {
graph: {
graph: link.graph,
group: link.group,
index: link.index
}
}
return { reference };
} else {
const reference = {
group: link.group
};
return { reference };
}
}
export function referenceToPermalink({ reference }: ReferenceContent): Permalink {
if('graph' in reference) {
const { graph, group, index } = reference.graph;
const link = `web+urbitgraph://group${group.slice(5)}/graph${graph.slice(5)}${index}`;
return {
type: 'graph',
link,
...reference.graph
};
} else {
const link = `web+urbitgraph://group${reference.group.slice(5)}`;
return {
type: 'group',
link,
...reference
}
}
}
export function parsePermalink(url: string): Permalink | null {
const [kind, ...rest] = url.slice(17).split("/");
if (kind === "group") {
const [ship, name, ...graph] = rest;
const group = `/ship/${ship}/${name}`;
if (graph.length > 0) {
return parseGraphPermalink(url, group, graph);
}
return {
type: "group",
group,
link: url.slice(11),
};
}
return null;
}

View File

@ -3,4 +3,4 @@ const ua = window.navigator.userAgent;
export const IS_IOS = ua.includes('iPhone');
console.log(IS_IOS);
export const IS_SAFARI = ua.includes('Safari') && !ua.includes('Chrome');

View File

@ -1,6 +1,7 @@
import urbitOb from 'urbit-ob';
import { parsePermalink, permalinkToReference } from "~/logic/lib/permalinks";
const URL_REGEX = new RegExp(String(/^((\w+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+\w)/.source));
const URL_REGEX = new RegExp(String(/^(([\w\-\+]+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+\w)/.source));
const isUrl = (string) => {
try {
@ -10,6 +11,10 @@ const isUrl = (string) => {
}
}
const isRef = (str) => {
return isUrl(str) && str.startsWith("web+urbitgraph://");
}
const tokenizeMessage = (text) => {
let messages = [];
let message = [];
@ -44,7 +49,20 @@ const tokenizeMessage = (text) => {
isInCodeBlock = false;
}
if (isUrl(str) && !isInCodeBlock) {
if(isRef(str) && !isInCodeBlock) {
if (message.length > 0) {
// If we're in the middle of a message, add it to the stack and reset
messages.push({ text: message.join(' ') });
}
const link = parsePermalink(str);
if(!link) {
messages.push({ url: str });
} else {
const reference = permalinkToReference(link);
messages.push(reference);
}
message = [];
} else if (isUrl(str) && !isInCodeBlock) {
if (message.length > 0) {
// If we're in the middle of a message, add it to the stack and reset
messages.push({ text: message.join(' ') });

View File

@ -0,0 +1,20 @@
import { writeText } from "./util";
import { useCallback, useState, useMemo } from "react";
export function useCopy(copied: string, display: string) {
const [didCopy, setDidCopy] = useState(false);
const doCopy = useCallback(() => {
writeText(copied);
setDidCopy(true);
setTimeout(() => {
setDidCopy(false);
}, 2000);
}, [copied]);
const copyDisplay = useMemo(() => (didCopy ? "Copied" : display), [
didCopy,
display,
]);
return { copyDisplay, doCopy };
}

View File

@ -41,10 +41,9 @@ export function useLazyScroll(
}, [count]);
useEffect(() => {
if (!ref.current) {
if (!ref.current || isDone) {
return;
}
setIsDone(false);
const scroll = ref.current;
loadUntil(scroll);

View File

@ -1,30 +1,46 @@
import { useMemo, useCallback } from 'react';
import { useLocation } from 'react-router-dom';
import _ from 'lodash';
import { useMemo, useCallback } from "react";
import { useLocation } from "react-router-dom";
import _ from "lodash";
function mergeQuery(search: URLSearchParams, added: Record<string, string>) {
_.forIn(added, (v, k) => {
if (v) {
search.append(k, v);
} else {
search.delete(k);
}
});
}
export function useQuery() {
const { search } = useLocation();
const { search, pathname } = useLocation();
const query = useMemo(() => new URLSearchParams(search), [search]);
const appendQuery = useCallback(
(q: Record<string, string>) => {
const newQuery = new URLSearchParams(search);
_.forIn(q, (value, key) => {
if (!value) {
newQuery.delete(key);
} else {
newQuery.append(key, value);
}
});
return newQuery.toString();
(added: Record<string, string>) => {
const q = new URLSearchParams(search);
mergeQuery(q, added);
return q.toString();
},
[search]
);
const toQuery = useCallback(
(params: Record<string, string>, path = pathname) => {
const q = new URLSearchParams(search);
mergeQuery(q, params);
return {
pathname: path,
search: q.toString(),
};
},
[search, pathname]
);
return {
query,
appendQuery
appendQuery,
toQuery,
};
}

View File

@ -0,0 +1,11 @@
import { useState, useCallback } from "react";
export function useToggleState(initial: boolean) {
const [state, setState] = useState(initial);
const toggle = useCallback(() => {
setState((s) => !s);
}, [setState]);
return [state, toggle] as const;
}

View File

@ -28,6 +28,11 @@ export const getModuleIcon = (mod: string) => {
if (mod === 'link') {
return 'Collection';
}
if (mod === 'post') {
return 'Spaces';
}
return _.capitalize(mod);
};
@ -37,10 +42,6 @@ export function wait(ms: number) {
});
}
export function appIsGraph(app: string) {
return app === 'publish' || app == 'link';
}
export function parentPath(path: string) {
return _.dropRight(path.split('/'), 1).join('/');
}

View File

@ -16,8 +16,27 @@ export const GraphReducer = (json) => {
removeNodes
]);
}
const loose = _.get(json, 'graph-update-loose', false);
if(loose) {
reduceState<GraphState, any>(useGraphState, loose, [addNodesLoose]);
}
};
const addNodesLoose = (json: any, state: GraphState): GraphState => {
const data = _.get(json, 'add-nodes', false);
if(data) {
const { resource: { ship, name }, nodes } = data;
const resource = `${ship}/${name}`;
const indices = _.get(state.looseNodes, [resource], {});
_.forIn(nodes, (node, index) => {
indices[index] = processNode(node);
});
_.set(state.looseNodes, [resource], indices);
}
return state;
}
const keys = (json, state: GraphState): GraphState => {
const data = _.get(json, 'keys', false);
if (data) {
@ -29,29 +48,31 @@ const keys = (json, state: GraphState): GraphState => {
return state;
};
const processNode = (node) => {
// is empty
if (!node.children) {
node.children = new BigIntOrderedMap();
return node;
}
// is graph
let converted = new BigIntOrderedMap();
for (let idx in node.children) {
let item = node.children[idx];
let index = bigInt(idx);
converted.set(
index,
processNode(item)
);
}
node.children = converted;
return node;
};
const addGraph = (json, state: GraphState): GraphState => {
const _processNode = (node) => {
// is empty
if (!node.children) {
node.children = new BigIntOrderedMap();
return node;
}
// is graph
let converted = new BigIntOrderedMap();
for (let idx in node.children) {
let item = node.children[idx];
let index = bigInt(idx);
converted.set(
index,
_processNode(item)
);
}
node.children = converted;
return node;
};
const data = _.get(json, 'add-graph', false);
if (data) {
@ -68,7 +89,7 @@ const addGraph = (json, state: GraphState): GraphState => {
let item = data.graph[idx];
let index = bigInt(idx);
let node = _processNode(item);
let node = processNode(item);
state.graphs[resource].set(
index,

View File

@ -11,12 +11,22 @@ const initial = (json: any, state: GroupState): GroupState => {
return state;
};
const started = (json: any, state: GroupState): GroupState => {
const data = json.started;
if(data) {
const { resource, request } = data;
state.pendingJoin[resource] = request;
}
return state;
}
const progress = (json: any, state: GroupState): GroupState => {
const data = json.progress;
if(data) {
const { progress, resource } = data;
state.pendingJoin = { ...state.pendingJoin, [resource]: progress };
state.pendingJoin[resource].progress = progress;
if(progress === 'done') {
setTimeout(() => {
delete state.pendingJoin[resource];
}, 10000);
@ -25,12 +35,23 @@ const progress = (json: any, state: GroupState): GroupState => {
return state;
};
const hide = (json: any, state: GroupState) => {
const data = json.hide;
if(data) {
state.pendingJoin[data].hidden = true;
}
return state;
}
export const GroupViewReducer = (json: any) => {
const data = json['group-view-update'];
if (data) {
reduceState<GroupState, GroupUpdate>(useGroupState, data, [
progress,
hide,
started,
initial
]);
}
};
};

View File

@ -1,7 +1,7 @@
import produce from "immer";
import { compose } from "lodash/fp";
import create, { State, UseStore } from "zustand";
import { persist } from "zustand/middleware";
import { persist, devtools } from "zustand/middleware";
export const stateSetter = <StateType>(

View File

@ -1,6 +1,7 @@
import { Patp, Rolodex, Scry } from "@urbit/api";
import { Patp, Rolodex, Scry, Contact } from "@urbit/api";
import { BaseState, createState } from "./base";
import {useCallback} from "react";
export interface ContactState extends BaseState<ContactState> {
contacts: Rolodex;
@ -9,6 +10,12 @@ export interface ContactState extends BaseState<ContactState> {
// fetchIsAllowed: (entity, name, ship, personal) => Promise<boolean>;
};
export function useContact(ship: string) {
return useContactState(
useCallback(s => s.contacts[ship] as Contact | null, [ship])
);
}
const useContactState = createState<ContactState>('Contact', {
contacts: {},
nackedContacts: new Set(),
@ -28,4 +35,4 @@ const useContactState = createState<ContactState>('Contact', {
// },
}, ['nackedContacts']);
export default useContactState;
export default useContactState;

View File

@ -1,10 +1,15 @@
import { Graphs, decToUd, numToUd } from "@urbit/api";
import { Graphs, decToUd, numToUd, GraphNode } from "@urbit/api";
import { BaseState, createState } from "./base";
export interface GraphState extends BaseState<GraphState> {
graphs: Graphs;
graphKeys: Set<string>;
looseNodes: {
[graph: string]: {
[index: string]: GraphNode;
}
};
pendingIndices: Record<string, any>;
graphTimesentMap: Record<string, any>;
// getKeys: () => Promise<void>;
@ -21,6 +26,7 @@ export interface GraphState extends BaseState<GraphState> {
const useGraphState = createState<GraphState>('Graph', {
graphs: {},
graphKeys: new Set(),
looseNodes: {},
pendingIndices: {},
graphTimesentMap: {},
// getKeys: async () => {
@ -122,6 +128,6 @@ const useGraphState = createState<GraphState>('Graph', {
// });
// graphReducer(node);
// },
}, ['graphs', 'graphKeys']);
}, ['graphs', 'graphKeys', 'looseNodes']);
export default useGraphState;
export default useGraphState;

View File

@ -1,9 +1,12 @@
import { Path, JoinRequests, Group } from "@urbit/api";
import { Path, JoinRequests, Association, Group } from "@urbit/api";
import { BaseState, createState } from "./base";
import {useCallback} from "react";
export interface GroupState extends BaseState<GroupState> {
groups: { [rid: string]: Group; };
groups: {
[group: string]: Group;
}
pendingJoin: JoinRequests;
};
@ -12,4 +15,14 @@ const useGroupState = createState<GroupState>('Group', {
pendingJoin: {},
}, ['groups']);
export function useGroup(group: string) {
return useGroupState(useCallback(s => s.groups[group], [group]));
}
export function useGroupForAssoc(association: Association) {
return useGroupState(
useCallback(s => s.groups[association.group] as Group | undefined, [association])
);
}
export default useGroupState;

View File

@ -3,29 +3,9 @@ import { StoreState } from '../store/type';
import { Path } from '@urbit/api';
import _ from 'lodash';
/**
* Path to subscribe on and app to subscribe to
*/
type AppSubscription = [Path, string];
const groupSubscriptions: AppSubscription[] = [
];
const graphSubscriptions: AppSubscription[] = [
['/updates', 'graph-store']
];
type AppName = 'groups' | 'graph';
const appSubscriptions: Record<AppName, AppSubscription[]> = {
groups: groupSubscriptions,
graph: graphSubscriptions
};
export default class GlobalSubscription extends BaseSubscription<StoreState> {
openSubscriptions: Record<AppName, number[]> = {
groups: [],
graph: []
};
openSubscriptions: any = {};
start() {
this.subscribe('/all', 'metadata-store');
@ -35,7 +15,6 @@ export default class GlobalSubscription extends BaseSubscription<StoreState> {
this.subscribe('/groups', 'group-store');
this.clearQueue();
// TODO: update to get /updates
this.subscribe('/all', 'contact-store');
this.subscribe('/all', 's3-store');
this.subscribe('/keys', 'graph-store');
@ -45,29 +24,37 @@ export default class GlobalSubscription extends BaseSubscription<StoreState> {
this.subscribe('/all', 'settings-store');
this.subscribe('/all', 'group-view');
this.subscribe('/nacks', 'contact-pull-hook');
this.clearQueue();
this.subscribe('/updates', 'graph-store');
}
subscribe(path: Path, app: string) {
if (`${app}${path}` in this.openSubscriptions) {
return;
}
const id = super.subscribe(path, app);
this.openSubscriptions[`${app}${path}`] = { app, path, id };
}
unsubscribe(id) {
for (let key in Object.keys(this.openSubscriptions)) {
let val = this.openSubscriptions[key];
if (id === val.id) {
delete this.openSubscriptions[`${val.app}${val.path}`];
super.unsubscribe(id);
}
}
}
restart() {
super.restart();
_.mapValues(this.openSubscriptions, (subs, app: AppName) => {
if(subs.length > 0) {
this.stopApp(app);
this.startApp(app);
}
});
}
for (let key in Object.keys(this.openSubscriptions)) {
let val = this.openSubscriptions[key];
startApp(app: AppName) {
if(this.openSubscriptions[app].length > 0) {
console.log(`${app} already started`);
return;
this.unsubscribe(val.id);
}
this.openSubscriptions[app] =
appSubscriptions[app].map(([path, agent]) => this.subscribe(path, agent));
}
stopApp(app: AppName) {
this.openSubscriptions[app].map(id => this.unsubscribe(id));
this.openSubscriptions[app] = [];
this.start();
}
}

View File

@ -1,6 +1,4 @@
if ("serviceWorker" in navigator) {
if ("serviceWorker" in navigator && process.env.NODE_ENV !== 'development') {
window.addEventListener("load", () => {
navigator.serviceWorker.register("/~landscape/js/bundle/serviceworker.js", {
scope: "/",

View File

@ -44,7 +44,7 @@ registerRoute(
// Check to see if the request's destination is style for stylesheets, script for JavaScript, or worker for web worker
({ request }) =>
request.destination === 'style' ||
request.destination === 'script' ||
// request.destination === 'script' ||
request.destination === 'worker',
// Use a Stale While Revalidate caching strategy
new StaleWhileRevalidate({

View File

@ -2,6 +2,7 @@ import React, { useRef, useCallback, useEffect, useState } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { Col } from '@tlon/indigo-react';
import _ from 'lodash';
import bigInt from 'big-integer';
import { Association } from '@urbit/api/metadata';
import { StoreState } from '~/logic/store/type';
@ -20,6 +21,8 @@ import useContactState from '~/logic/state/contact';
import useGraphState from '~/logic/state/graph';
import useGroupState from '~/logic/state/group';
import useHarkState from '~/logic/state/hark';
import {Post} from '@urbit/api';
import {getPermalinkForGraph} from '~/logic/lib/permalinks';
type ChatResourceProps = StoreState & {
association: Association;
@ -78,19 +81,20 @@ export function ChatResource(props: ChatResourceProps) {
const scrollTo = new URLSearchParams(location.search).get('msg');
useEffect(() => {
const clear = () => {
props.history.replace(location.pathname);
};
setTimeout(clear, 10000);
return clear;
}, [station]);
const [showBanner, setShowBanner] = useState(false);
const [hasLoadedAllowed, setHasLoadedAllowed] = useState(false);
const [recipients, setRecipients] = useState([]);
const res = resourceFromPath(groupPath);
const onReply = useCallback((msg: Post) => {
const url = getPermalinkForGraph(
props.association.group,
props.association.resource,
msg.index
);
const message = `${url}\n~${msg.author} : `;
setUnsent(s => ({...s, [props.association.resource]: message }));
}, [props.association, group, setUnsent]);
useEffect(() => {
(async () => {
@ -163,9 +167,10 @@ export function ChatResource(props: ChatResourceProps) {
pendingSize={Object.keys(graphTimesentMap[graphPath] || {}).length}
group={group}
ship={owner}
onReply={onReply}
station={station}
api={props.api}
scrollTo={scrollTo ? parseInt(scrollTo, 10) : undefined}
scrollTo={scrollTo ? bigInt(scrollTo) : undefined}
/>
{ canWrite && (
<ChatInput

View File

@ -165,7 +165,7 @@ class ChatInput extends Component<ChatInputProps, ChatInputState> {
flexGrow={1}
flexShrink={0}
borderTop={1}
borderTopColor='washedGray'
borderTopColor='lightGray'
backgroundColor='white'
className='cf'
zIndex={0}

View File

@ -40,6 +40,11 @@ import useSettingsState, { selectCalmState } from '~/logic/state/settings';
import Timestamp from '~/views/components/Timestamp';
import useContactState from '~/logic/state/contact';
import { useIdlingState } from '~/logic/lib/idling';
import ProfileOverlay from '~/views/components/ProfileOverlay';
import {useCopy} from '~/logic/lib/useCopy';
import {PermalinkEmbed} from '../../permalinks/embed';
import {referenceToPermalink} from '~/logic/lib/permalinks';
export const DATESTAMP_FORMAT = '[~]YYYY.M.D';
@ -48,6 +53,7 @@ interface DayBreakProps {
shimTop?: boolean;
}
export const DayBreak = ({ when, shimTop = false }: DayBreakProps) => (
<Row
px={2}
@ -134,13 +140,15 @@ const MessageActionItem = (props) => {
);
};
const MessageActions = ({ api, history, msg, group }) => {
const MessageActions = ({ api, onReply, association, history, msg, group }) => {
const isAdmin = () => group.tags.role.admin.has(window.ship);
const isOwn = () => msg.author === window.ship;
const { doCopy, copyDisplay } = useCopy(`web+urbitgraph://group${association.group.slice(5)}/graph${association.resource.slice(5)}${msg.index}`, 'Copy Message Link');
return (
<Box
borderRadius={1}
background='white'
backgroundColor='white'
border='1px solid'
borderColor='lightGray'
position='absolute'
@ -148,21 +156,11 @@ const MessageActions = ({ api, history, msg, group }) => {
right={2}
>
<Row>
{isOwn() ? (
<Box
padding={1}
size={'24px'}
cursor='pointer'
onClick={(e) => console.log(e)}
>
<Icon icon='NullIcon' size={3} />
</Box>
) : null}
<Box
padding={1}
size={'24px'}
cursor='pointer'
onClick={(e) => console.log(e)}
onClick={() => onReply(msg)}
>
<Icon icon='Chat' size={3} />
</Box>
@ -184,25 +182,22 @@ const MessageActions = ({ api, history, msg, group }) => {
borderColor='lightGray'
boxShadow='0px 0px 0px 3px'
>
{isOwn() ? (
<MessageActionItem onClick={(e) => console.log(e)}>
Edit Message
</MessageActionItem>
) : null}
<MessageActionItem onClick={(e) => console.log(e)}>
<MessageActionItem onClick={() => onReply(msg)}>
Reply
</MessageActionItem>
<MessageActionItem onClick={(e) => console.log(e)}>
Copy Message Link
<MessageActionItem onClick={doCopy}>
{copyDisplay}
</MessageActionItem>
{isAdmin() || isOwn() ? (
{false && (isAdmin() || isOwn()) ? (
<MessageActionItem onClick={(e) => console.log(e)} color='red'>
Delete Message
</MessageActionItem>
) : null}
<MessageActionItem onClick={(e) => console.log(e)}>
View Signature
</MessageActionItem>
{false && (
<MessageActionItem onClick={(e) => console.log(e)}>
View Signature
</MessageActionItem>
)}
</Col>
}
>
@ -217,17 +212,19 @@ const MessageActions = ({ api, history, msg, group }) => {
const MessageWrapper = (props) => {
const { hovering, bind } = useHovering();
const showHover = (props.transcluded === 0) && hovering && !props.hideHover;
return (
<Box
py='1'
backgroundColor={
hovering && !props.hideHover ? 'washedGray' : 'transparent'
backgroundColor={props.highlighted
? showHover ? 'lightBlue' : 'washedBlue'
: showHover ? 'washedGray' : 'transparent'
}
position='relative'
{...bind}
>
{props.children}
{/* {hovering ? <MessageActions {...props} /> : null} */}
{showHover ? <MessageActions {...props} /> : null}
</Box>
);
};
@ -239,6 +236,7 @@ interface ChatMessageProps {
isLastRead: boolean;
group: Group;
association: Association;
transcluded?: number;
className?: string;
isPending: boolean;
style?: unknown;
@ -251,6 +249,7 @@ interface ChatMessageProps {
renderSigil?: boolean;
hideHover?: boolean;
innerRef: (el: HTMLDivElement | null) => void;
onReply?: (msg: Post) => void;
}
class ChatMessage extends Component<ChatMessageProps> {
@ -285,6 +284,9 @@ class ChatMessage extends Component<ChatMessageProps> {
hideHover
} = this.props;
let onReply = this.props?.onReply;
onReply ??= () => {};
const transcluded = this.props?.transcluded ?? 0;
let { renderSigil } = this.props;
if (renderSigil === undefined) {
@ -320,7 +322,9 @@ class ChatMessage extends Component<ChatMessageProps> {
scrollWindow,
highlighted,
fontSize,
hideHover
hideHover,
transcluded,
onReply
};
const unreadContainerStyle = {
@ -331,9 +335,9 @@ class ChatMessage extends Component<ChatMessageProps> {
<Box
ref={this.props.innerRef}
pt={renderSigil ? 2 : 0}
width="100%"
pb={isLastMessage ? '20px' : 0}
className={containerClass}
backgroundColor={highlighted ? 'blue' : 'white'}
style={style}
>
{dayBreak && !isLastRead ? (
@ -477,21 +481,9 @@ export const MessageAuthor = ({
cursor='pointer'
position='relative'
>
{showOverlay && (
<OverlaySigil
cursor='auto'
ship={msg.author}
contact={contact}
color={`#${uxToHex(contact?.color ?? '0x0')}`}
group={group}
onDismiss={() => toggleOverlay()}
history={history}
className='relative'
scrollWindow={scrollWindow}
api={api}
/>
)}
{img}
<ProfileOverlay cursor='auto' ship={msg.author} api={api}>
{img}
</ProfileOverlay>
</Box>
<Box flexGrow={1} display='block' className='clamp-message' {...bind}>
<Box
@ -542,12 +534,14 @@ export const Message = ({
api,
scrollWindow,
timestampHover,
transcluded,
showOurContact,
...rest
}) => {
const { hovering, bind } = useHovering();
const contacts = useContactState((state) => state.contacts);
return (
<Box position='relative' {...rest}>
<Box width="100%" position='relative' {...rest}>
{timestampHover ? (
<Text
display={hovering ? 'block' : 'none'}
@ -564,7 +558,7 @@ export const Message = ({
) : (
<></>
)}
<Box {...bind}>
<Box width="100%" {...bind}>
{msg.contents.map((content, i) => {
switch (Object.keys(content)[0]) {
case 'text':
@ -578,40 +572,31 @@ export const Message = ({
/>
);
case 'code':
return <CodeContent key={i} content={content} />;
case 'url':
return <CodeContent key={i} content={content} />;
case 'reference':
const { link } = referenceToPermalink(content);
return (
<PermalinkEmbed
link={link}
api={api}
transcluded={transcluded}
showOurContact={showOurContact}
/>
);
case 'url':
return (
<Box
key={i}
flexShrink={0}
fontSize={1}
lineHeight='20px'
color='black'
width="fit-content"
maxWidth="500px"
>
<RemoteContent
key={content.url}
url={content.url}
imageProps={{
style: {
maxWidth: 'min(100%,18rem)',
display: 'inline-block',
marginTop: '0.5rem'
}
}}
videoProps={{
style: {
maxWidth: '18rem',
display: 'block',
marginTop: '0.5rem'
}
}}
textProps={{
style: {
fontSize: 'inherit',
borderBottom: '1px solid',
textDecoration: 'none'
}
}}
/>
</Box>
);

View File

@ -42,7 +42,8 @@ type ChatWindowProps = RouteComponentProps<{
ship: Patp;
station: any;
api: GlobalApi;
scrollTo?: number;
scrollTo?: BigInteger;
onReply: (msg: Post) => void;
};
interface ChatWindowState {
@ -89,10 +90,13 @@ class ChatWindow extends Component<
componentDidMount() {
this.calculateUnreadIndex();
setTimeout(() => {
if (this.props.scrollTo) {
this.scrollToUnread();
}
this.setState({ initialized: true });
this.setState({ initialized: true }, () => {
if(this.props.scrollTo) {
this.virtualList.scrollToIndex(this.props.scrollTo);
}
});
}, this.INITIALIZATION_MAX_TIME);
}
@ -239,7 +243,8 @@ class ChatWindow extends Component<
graph,
history,
groups,
associations
associations,
onReply
} = this.props;
const { unreadMarkerRef } = this;
const messageProps = {
@ -250,7 +255,8 @@ class ChatWindow extends Component<
history,
api,
groups,
associations
associations,
onReply
};
const msg = graph.get(index)?.post;
@ -268,7 +274,7 @@ class ChatWindow extends Component<
const isLastMessage = index.eq(
graph.peekLargest()?.[0] ?? bigInt.zero
);
const highlighted = false; // this.state.unreadIndex.eq(index);
const highlighted = index.eq(this.props.scrollTo ?? bigInt.zero);
const keys = graph.keys().reverse();
const graphIdx = keys.findIndex((idx) => idx.eq(index));
const prevIdx = keys[graphIdx + 1];
@ -306,7 +312,8 @@ class ChatWindow extends Component<
groups,
associations,
showOurContact,
pendingSize
pendingSize,
onReply,
} = this.props;
const unreadMarkerRef = this.unreadMarkerRef;

View File

@ -60,7 +60,7 @@ export const ShareProfile = (props) => {
alignItems="center"
justifyContent="space-between"
borderBottom={1}
borderColor="washedGray"
borderColor="lightGray"
>
<Row pl={3} alignItems="center">
{image}

View File

@ -8,6 +8,7 @@ import { Row, BaseTextArea, Box } from '@tlon/indigo-react';
import 'codemirror/mode/markdown/markdown';
import 'codemirror/addon/display/placeholder';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/lib/codemirror.css';
@ -142,6 +143,9 @@ export default class ChatEditor extends Component {
}
messageChange(editor, data, value) {
if(value.endsWith('/')) {
editor.showHint(['test', 'foo']);
}
if (this.state.message !== '' && value == '') {
this.setState({
message: value

View File

@ -4,10 +4,12 @@ import { Center, Text } from "@tlon/indigo-react";
import { deSig } from '~/logic/lib/util';
import useGraphState from '~/logic/state/graph';
import useMetadataState from '~/logic/state/metadata';
import useGroupState from '~/logic/state/group';
const GraphApp = (props) => {
const associations= useMetadataState(state => state.associations);
const graphKeys = useGraphState(state => state.graphKeys);
const groups = useGroupState(state => state.groups);
const history = useHistory();
const { api } = props;
@ -38,8 +40,8 @@ const GraphApp = (props) => {
if(!graphKeys.has(resource)) {
autoJoin();
} else if(!!association) {
history.push(`/~landscape/home/resource/${association.metadata.module}${path}`);
} else if(!!association && 'graph' in association.config) {
history.push(`/~landscape/home/resource/${association.metadata.config.graph}${path}`);
}
return (
<Center width="100%" height="100%">
@ -52,4 +54,4 @@ const GraphApp = (props) => {
);
}
export default GraphApp;
export default GraphApp;

View File

@ -6,7 +6,6 @@ import _ from 'lodash';
import { Col, Button, Box, Row, Icon, Text } from '@tlon/indigo-react';
import './css/custom.css';
import useContactState from '~/logic/state/contact';
import Tiles from './components/tiles';
import Tile from './components/tiles/tile';
import Groups from './components/Groups';
@ -33,6 +32,7 @@ import {
import useLaunchState from '~/logic/state/launch';
import useSettingsState, { selectCalmState } from '~/logic/state/settings';
import useMetadataState from '~/logic/state/metadata';
import {useHistory} from 'react-router-dom';
const ScrollbarLessBox = styled(Box)`
@ -52,7 +52,7 @@ export default function LaunchApp(props) {
const [exitingTut, setExitingTut] = useState(false);
const seen = useSettingsState(s => s?.tutorial?.seen) ?? true;
const associations = useMetadataState(s => s.associations);
const contacts = useContactState(state => state.contacts);
const history = useHistory();
const hasLoaded = useMemo(() => Boolean(connection === "connected"), [connection]);
const notificationsCount = useHarkState(state => state.notificationsCount);
const calmState = useSettingsState(selectCalmState);
@ -191,7 +191,13 @@ export default function LaunchApp(props) {
to="/~landscape/home"
p={0}
>
<Box p={2} height='100%' width='100%' bg='scales.black20'>
<Box
p={2}
height='100%'
width='100%'
bg='scales.black20'
border={1}
borderColor="lightGray">
<Row alignItems='center'>
<Icon
color="black"
@ -228,7 +234,7 @@ export default function LaunchApp(props) {
</Box>
<Box alignSelf="flex-start" display={["block", "none"]}>{hashBox}</Box>
</ScrollbarLessBox>
<Box display={["none", "block"]}>{hashBox}</Box>
<Box onClick={() => history.push('/~graph/graph/ship/~bitpyx-dildus/infrastructure-digests/170141184504958869914231288036524556288/2/170141184504958917566472168072435204096') } display={["none", "block"]}>{hashBox}</Box>
</>
);
}

View File

@ -12,7 +12,7 @@ export default class CustomTile extends React.PureComponent {
position='relative'
backgroundColor='white'
border='1px solid'
borderColor='washedGray'
borderColor='lightGray'
borderRadius='2'
>
<BaseImage

View File

@ -48,7 +48,7 @@ const Tile = React.forwardRef((props, ref) => {
borderRadius={2}
overflow="hidden"
bg={bg || "white"}
color={props?.color || 'washedGray'}
color={props?.color || 'lightGray'}
boxShadow={boxShadow || '0 0 0px 1px inset'}
style={{ gridColumnStart }}
>

Some files were not shown because too many files have changed in this diff Show More