mirror of
https://github.com/ilyakooo0/urbit.git
synced 2025-01-03 04:40:50 +03:00
Merge remote-tracking branch 'origin/la/push-hook-list-resource' into lf/handoff
This commit is contained in:
commit
7d69b23440
@ -9,6 +9,7 @@
|
||||
update:store
|
||||
%contact-update
|
||||
%contact-push-hook
|
||||
%.y :: necessary to enable p2p
|
||||
==
|
||||
--
|
||||
::
|
||||
@ -32,14 +33,11 @@
|
||||
++ on-agent on-agent:def
|
||||
++ on-watch on-watch:def
|
||||
++ on-leave on-leave:def
|
||||
++ resource-for-update resource-for-update:con
|
||||
++ on-pull-nack
|
||||
|= [=resource =tang]
|
||||
^- (quip card _this)
|
||||
:_ this
|
||||
?~ (get-contact:con entity.resource) ~
|
||||
=- [%pass /pl-nack %agent [our.bowl %contact-store] %poke %contact-update -]~
|
||||
!> ^- update:store
|
||||
[%remove entity.resource]
|
||||
[~ this]
|
||||
::
|
||||
++ on-pull-kick |=(=resource `/)
|
||||
--
|
||||
|
@ -1,4 +1,6 @@
|
||||
/+ store=contact-store, res=resource, contact, default-agent, dbug, push-hook
|
||||
/- pull-hook
|
||||
/+ store=contact-store, res=resource, contact, group,
|
||||
default-agent, dbug, push-hook
|
||||
~% %contact-push-hook-top ..part ~
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
@ -12,6 +14,8 @@
|
||||
==
|
||||
::
|
||||
+$ agent (push-hook:push-hook config)
|
||||
::
|
||||
+$ share [%share =ship]
|
||||
--
|
||||
::
|
||||
%- agent:dbug
|
||||
@ -22,11 +26,34 @@
|
||||
+* this .
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
con ~(. contact bowl)
|
||||
grp ~(. group bowl)
|
||||
::
|
||||
++ on-init
|
||||
^- (quip card _this)
|
||||
:_ this :_ ~
|
||||
=- [%pass /us %agent [our.bowl %contact-push-hook] %poke %push-hook-action -]
|
||||
!> ^- action:push-hook
|
||||
[%add [our.bowl %'']]
|
||||
::
|
||||
++ on-init on-init:def
|
||||
++ on-save !>(~)
|
||||
++ on-load on-load:def
|
||||
++ on-poke on-poke:def
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
^- (quip card _this)
|
||||
?. =(mark %contact-share) (on-poke:def mark vase)
|
||||
=/ =share !<(share vase)
|
||||
?> =(src.bowl ship.share)
|
||||
:_ this :_ ~
|
||||
:* %pass
|
||||
/(scot %p src.bowl)/share
|
||||
%agent
|
||||
[our.bowl %contact-pull-hook]
|
||||
%poke
|
||||
%pull-hook-action
|
||||
!> ^- action:pull-hook
|
||||
[%add ship.share [ship.share %'']]
|
||||
==
|
||||
::
|
||||
++ on-agent on-agent:def
|
||||
++ on-watch on-watch:def
|
||||
++ on-leave on-leave:def
|
||||
@ -48,16 +75,31 @@
|
||||
%set-public %.n
|
||||
==
|
||||
::
|
||||
++ resource-for-update resource-for-update:con
|
||||
::
|
||||
++ initial-watch
|
||||
|= [=path =resource:res]
|
||||
^- vase
|
||||
?> (is-allowed:con src.bowl)
|
||||
|^
|
||||
?> (is-allowed:con resource src.bowl)
|
||||
!> ^- update:store
|
||||
=/ contact=(unit contact:store) (get-contact:con our.bowl)
|
||||
:+ %add
|
||||
our.bowl
|
||||
?^ contact u.contact
|
||||
*contact:store
|
||||
[%initial rolo %.n]
|
||||
::
|
||||
++ rolo
|
||||
^- rolodex:store
|
||||
=/ ugroup (scry-group:grp resource)
|
||||
%- ~(gas by *rolodex:store)
|
||||
?~ ugroup
|
||||
=/ c=(unit contact:store) (get-contact:con our.bowl)
|
||||
?~ c
|
||||
[our.bowl *contact:store]~
|
||||
[our.bowl u.c]~
|
||||
%+ murn ~(tap in (members:grp resource))
|
||||
|= s=ship
|
||||
^- (unit [ship contact:store])
|
||||
=/ c=(unit contact:store) (get-contact:con s)
|
||||
?~(c ~ `[s u.c])
|
||||
--
|
||||
::
|
||||
++ take-update
|
||||
|= =vase
|
||||
|
@ -3,7 +3,7 @@
|
||||
:: data store that holds individual contact data
|
||||
::
|
||||
/- store=contact-store, *resource
|
||||
/+ default-agent, dbug, *migrate
|
||||
/+ default-agent, dbug, *migrate, contact
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
+$ state-4
|
||||
@ -29,6 +29,7 @@
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
con ~(. contact bowl)
|
||||
::
|
||||
++ on-init
|
||||
=. rolodex (~(put by rolodex) our.bowl *contact:store)
|
||||
@ -101,8 +102,10 @@
|
||||
++ handle-initial
|
||||
|= [rolo=rolodex:store is-public=?]
|
||||
^- (quip card _state)
|
||||
=/ our-contact (~(got by rolodex) our.bowl)
|
||||
=. rolodex (~(uni by rolodex) rolo)
|
||||
:_ state(rolodex rolodex, is-public is-public)
|
||||
=. rolodex (~(put by rolodex) our.bowl our-contact)
|
||||
:_ state(rolodex rolodex)
|
||||
(send-diff [%initial rolodex is-public] %.n)
|
||||
::
|
||||
++ handle-add
|
||||
@ -208,9 +211,22 @@
|
||||
[%x %allowed-ship @ ~]
|
||||
=/ =ship (slav %p i.t.t.path)
|
||||
``noun+!>((~(has in allowed-ships) ship))
|
||||
::
|
||||
[%x %is-public ~]
|
||||
``noun+!>(is-public)
|
||||
::
|
||||
[%x %allowed-groups ~]
|
||||
``noun+!>(allowed-groups)
|
||||
|
||||
::
|
||||
[%x %is-allowed @ @ @ @ ~]
|
||||
=/ is-personal =(i.t.t.t.t.t.path 'true')
|
||||
=/ =resource
|
||||
?: is-personal
|
||||
[our.bowl %'']
|
||||
[(slav %p i.t.t.path) i.t.t.t.path]
|
||||
=/ =ship (slav %p i.t.t.t.t.path)
|
||||
``json+!>(`json`b+(is-allowed:con resource ship))
|
||||
==
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
|
@ -9,6 +9,7 @@
|
||||
update:store
|
||||
%graph-update
|
||||
%graph-push-hook
|
||||
%.n
|
||||
==
|
||||
--
|
||||
::
|
||||
@ -48,4 +49,6 @@
|
||||
=/ maybe-time (peek-update-log:gra resource)
|
||||
?~ maybe-time `/
|
||||
`/(scot %da u.maybe-time)
|
||||
::
|
||||
++ resource-for-update resource-for-update:gra
|
||||
--
|
||||
|
@ -93,6 +93,7 @@
|
||||
%tag-queries %.n
|
||||
%run-updates %.n
|
||||
==
|
||||
++ resource-for-update resource-for-update:gra
|
||||
::
|
||||
++ initial-watch
|
||||
|= [=path =resource:res]
|
||||
|
@ -14,6 +14,7 @@
|
||||
update:store
|
||||
%group-update
|
||||
%group-push-hook
|
||||
%.n
|
||||
==
|
||||
::
|
||||
--
|
||||
@ -28,6 +29,7 @@
|
||||
+* this .
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
dep ~(. (default:pull-hook this config) bowl)
|
||||
grp ~(. grpl bowl)
|
||||
::
|
||||
++ on-init on-init:def
|
||||
++ on-save !>(~)
|
||||
@ -45,8 +47,11 @@
|
||||
:_ this
|
||||
=- [%pass / %agent [our.bowl %group-store] %poke -]~
|
||||
group-update+!>([%remove-group resource ~])
|
||||
::
|
||||
++ on-pull-kick
|
||||
|= =resource
|
||||
^- (unit path)
|
||||
`/
|
||||
::
|
||||
++ resource-for-update resource-for-update:grp
|
||||
--
|
||||
|
@ -141,6 +141,7 @@
|
||||
=(~(tap in ships.update) ~[src.bowl])
|
||||
==
|
||||
--
|
||||
++ resource-for-update resource-for-update:grp
|
||||
::
|
||||
++ take-update
|
||||
|= =vase
|
||||
|
@ -1,5 +1,6 @@
|
||||
/- view-sur=group-view, group-store, *group, metadata=metadata-store
|
||||
/+ default-agent, agentio, mdl=metadata, resource, dbug, grpl=group, verb
|
||||
/+ default-agent, agentio, mdl=metadata,
|
||||
resource, dbug, grpl=group, con=contact, verb
|
||||
|%
|
||||
++ card card:agent:gall
|
||||
+$ state-zero
|
||||
@ -69,9 +70,7 @@
|
||||
[cards this]
|
||||
::
|
||||
++ on-arvo on-arvo:def
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
::
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
|_ =bowl:gall
|
||||
@ -86,6 +85,7 @@
|
||||
++ emit-many
|
||||
|= crds=(list card)
|
||||
jn-core(cards (weld (flop crds) cards))
|
||||
::
|
||||
++ emit
|
||||
|= =card
|
||||
jn-core(cards [card cards])
|
||||
@ -152,43 +152,65 @@
|
||||
%+ poke-our:(jn-pass-io /pull-groups) %group-pull-hook
|
||||
pull-hook-action+!>([%add ship rid])
|
||||
(tx-progress %added)
|
||||
::
|
||||
::
|
||||
%pull-groups
|
||||
?> ?=(%poke-ack -.sign)
|
||||
(ack +.sign)
|
||||
::
|
||||
::
|
||||
%groups
|
||||
?+ -.sign !!
|
||||
%fact (groups-fact +.sign)
|
||||
%watch-ack (ack +.sign)
|
||||
%kick watch-groups
|
||||
==
|
||||
::
|
||||
::
|
||||
%pull-md
|
||||
?> ?=(%poke-ack -.sign)
|
||||
(ack +.sign)
|
||||
::
|
||||
::
|
||||
%pull-co
|
||||
?> ?=(%poke-ack -.sign)
|
||||
(ack +.sign)
|
||||
::
|
||||
%share-co
|
||||
?> ?=(%poke-ack -.sign)
|
||||
(ack +.sign)
|
||||
::
|
||||
%push-co
|
||||
?> ?=(%poke-ack -.sign)
|
||||
(ack +.sign)
|
||||
::
|
||||
%md
|
||||
?+ -.sign !!
|
||||
%fact (md-fact +.sign)
|
||||
%watch-ack (ack +.sign)
|
||||
%kick watch-md
|
||||
==
|
||||
::
|
||||
::
|
||||
%pull-graphs
|
||||
?> ?=(%poke-ack -.sign)
|
||||
%- cleanup
|
||||
?^(p.sign %strange %done)
|
||||
==
|
||||
::
|
||||
++ groups-fact
|
||||
|= =cage
|
||||
?. ?=(%group-update p.cage) jn-core
|
||||
=+ !<(=update:group-store q.cage)
|
||||
?. ?=(%initial-group -.update) jn-core
|
||||
?. =(rid resource.update) jn-core
|
||||
%- emit
|
||||
%+ poke-our:(jn-pass-io /pull-md) %metadata-pull-hook
|
||||
pull-hook-action+!>([%add [entity .]:rid])
|
||||
%- emit-many
|
||||
=/ cag=^cage pull-hook-action+!>([%add [entity .]:rid])
|
||||
%- zing
|
||||
:~ [(poke-our:(jn-pass-io /pull-md) %metadata-pull-hook cag)]~
|
||||
[(poke-our:(jn-pass-io /pull-co) %contact-pull-hook cag)]~
|
||||
::
|
||||
?. scry-is-public:con ~
|
||||
:_ ~
|
||||
%+ poke:(jn-pass-io /share-co)
|
||||
[entity.rid %contact-push-hook]
|
||||
[%contact-share !>([%share our.bowl])]
|
||||
==
|
||||
::
|
||||
++ md-fact
|
||||
|= [=mark =vase]
|
||||
|
@ -15,6 +15,7 @@
|
||||
update:metadata
|
||||
%metadata-update
|
||||
%metadata-push-hook
|
||||
%.n
|
||||
==
|
||||
+$ state-zero
|
||||
[%0 previews=(map resource group-preview:metadata)]
|
||||
@ -191,6 +192,7 @@
|
||||
++ on-arvo on-arvo:def
|
||||
::
|
||||
++ on-fail on-fail:def
|
||||
++ resource-for-update resource-for-update:met
|
||||
++ on-pull-nack
|
||||
|= [=resource =tang]
|
||||
^- (quip card _this)
|
||||
|
@ -92,6 +92,7 @@
|
||||
?=(%member-metadata vip.metadatum)
|
||||
==
|
||||
::
|
||||
++ resource-for-update resource-for-update:met
|
||||
++ take-update
|
||||
|= =vase
|
||||
^- [(list card) agent]
|
||||
|
@ -173,4 +173,10 @@
|
||||
==
|
||||
--
|
||||
--
|
||||
::
|
||||
++ share-dejs
|
||||
=, dejs:format
|
||||
|%
|
||||
++ share (ot [%share (su ;~(pfix sig fed:ag))]~)
|
||||
--
|
||||
--
|
||||
|
@ -1,6 +1,7 @@
|
||||
/- store=contact-store, *resource
|
||||
/+ group
|
||||
/+ group, grpl=group
|
||||
|_ =bowl:gall
|
||||
+* grp ~(. grpl bowl)
|
||||
++ scry-for
|
||||
|* [=mold =path]
|
||||
.^ mold
|
||||
@ -11,24 +12,88 @@
|
||||
(snoc `^path`path %noun)
|
||||
==
|
||||
::
|
||||
++ resource-for-update
|
||||
|= =vase
|
||||
^- (list resource)
|
||||
|^
|
||||
=/ =update:store !<(update:store vase)
|
||||
?- -.update
|
||||
%initial ~
|
||||
%add (rids-for-ship ship.update)
|
||||
%remove (rids-for-ship ship.update)
|
||||
%edit (rids-for-ship ship.update)
|
||||
%allow ~
|
||||
%disallow ~
|
||||
%set-public ~
|
||||
==
|
||||
::
|
||||
++ rids-for-ship
|
||||
|= s=ship
|
||||
^- (list resource)
|
||||
:: if the ship is in any group that I am pushing updates for, push
|
||||
:: it out to that resource.
|
||||
::
|
||||
=/ rids
|
||||
%+ skim ~(tap in scry-sharing)
|
||||
|= r=resource
|
||||
(is-member:grp s r)
|
||||
?. =(s our.bowl)
|
||||
rids
|
||||
(snoc rids [our.bowl %''])
|
||||
--
|
||||
++ scry-sharing
|
||||
.^ (set resource)
|
||||
%gx
|
||||
(scot %p our.bowl)
|
||||
%contact-push-hook
|
||||
(scot %da now.bowl)
|
||||
/sharing/noun
|
||||
==
|
||||
::
|
||||
++ get-contact
|
||||
|= =ship
|
||||
^- (unit contact:store)
|
||||
=/ upd (scry-for (unit update:store) /contact/(scot %p ship))
|
||||
?~ upd ~
|
||||
?> ?=(%add -.u.upd)
|
||||
`contact.u.upd
|
||||
=/ =rolodex:store
|
||||
(scry-for rolodex:store /all)
|
||||
(~(get by rolodex) ship)
|
||||
::
|
||||
++ scry-is-public
|
||||
.^ ?
|
||||
%gx
|
||||
(scot %p our.bowl)
|
||||
%contact-store
|
||||
(scot %da now.bowl)
|
||||
/is-public/noun
|
||||
==
|
||||
::
|
||||
++ is-allowed
|
||||
|= =ship
|
||||
|= [rid=resource =ship]
|
||||
^- ?
|
||||
=/ shp (scry-for ? /allowed-ship/(scot %p ship))
|
||||
?: shp %.y
|
||||
=/ allowed-groups ~(tap in (scry-for (set resource) /allowed-groups))
|
||||
=/ grp ~(. group bowl)
|
||||
|-
|
||||
?~ allowed-groups %.n
|
||||
?: (~(has in (members:grp i.allowed-groups)) ship)
|
||||
%.y
|
||||
$(allowed-groups t.allowed-groups)
|
||||
=/ allowed-groups (scry-for (set resource) /allowed-groups)
|
||||
?| :: if they are requesting our personal profile, check if we are
|
||||
:: either public, or if they are on the allowed-ships list.
|
||||
:: this is used for direct messages and leap searches
|
||||
::
|
||||
?& =(rid [our.bowl %''])
|
||||
?| :: if our profile is public, allow
|
||||
::
|
||||
scry-is-public
|
||||
:: if the requester is an allowed-ship, allow
|
||||
::
|
||||
(scry-for ? /allowed-ship/(scot %p ship))
|
||||
:: if the requester of our profile is the host of one of
|
||||
:: our allowed-groups, allow
|
||||
::
|
||||
%+ lien ~(tap in allowed-groups)
|
||||
|= res=resource
|
||||
=(entity.res ship)
|
||||
== ==
|
||||
:: if they are requesting our contact data within a group,
|
||||
:: we make sure that we are sharing that group,
|
||||
:: and that they are a member of the group
|
||||
::
|
||||
?& (~(has in scry-sharing) rid)
|
||||
(~(has in (members:grp rid)) ship)
|
||||
== ==
|
||||
--
|
||||
|
@ -11,6 +11,27 @@
|
||||
(snoc `^path`path %noun)
|
||||
==
|
||||
::
|
||||
++ resource-for-update
|
||||
|= =vase
|
||||
^- (list resource)
|
||||
=/ =update:store !<(update:store vase)
|
||||
?- -.q.update
|
||||
%add-graph ~[resource.q.update]
|
||||
%remove-graph ~[resource.q.update]
|
||||
%add-nodes ~[resource.q.update]
|
||||
%remove-nodes ~[resource.q.update]
|
||||
%add-signatures ~[resource.uid.q.update]
|
||||
%remove-signatures ~[resource.uid.q.update]
|
||||
%archive-graph ~[resource.q.update]
|
||||
%unarchive-graph ~
|
||||
%add-tag ~
|
||||
%remove-tag ~
|
||||
%keys ~
|
||||
%tags ~
|
||||
%tag-queries ~
|
||||
%run-updates ~[resource.q.update]
|
||||
==
|
||||
::
|
||||
++ get-graph
|
||||
|= res=resource
|
||||
^- update:store
|
||||
|
@ -3,6 +3,15 @@
|
||||
::
|
||||
|_ =bowl:gall
|
||||
+$ card card:agent:gall
|
||||
::
|
||||
++ resource-for-update
|
||||
|= =vase
|
||||
^- (list resource)
|
||||
=/ =update:store !<(update:store vase)
|
||||
?: ?=(%initial -.update)
|
||||
~
|
||||
~[resource.update]
|
||||
::
|
||||
++ scry-for
|
||||
|* [=mold =path]
|
||||
=. path
|
||||
@ -28,6 +37,15 @@
|
||||
%+ scry-for ,(unit group)
|
||||
`path`groups+(en-path:resource rid)
|
||||
::
|
||||
++ scry-groups
|
||||
.^ ,(set resource)
|
||||
%gy
|
||||
(scot %p our.bowl)
|
||||
%group-store
|
||||
(scot %da now.bowl)
|
||||
/groups/noun
|
||||
==
|
||||
::
|
||||
++ members
|
||||
|= rid=resource
|
||||
=; =group
|
||||
|
@ -90,10 +90,8 @@
|
||||
%chat-cli
|
||||
%herm
|
||||
%contact-store
|
||||
%contact-hook
|
||||
%contact-push-hook
|
||||
%contact-pull-hook
|
||||
%contact-view
|
||||
%metadata-store
|
||||
%s3-store
|
||||
%file-server
|
||||
|
@ -4,6 +4,13 @@
|
||||
/+ resource
|
||||
::
|
||||
|_ =bowl:gall
|
||||
++ resource-for-update
|
||||
|= =vase
|
||||
^- (list resource)
|
||||
=/ =update:store !<(update:store vase)
|
||||
?. ?=(?(%add %remove %initial-group) -.update) ~
|
||||
~[group.update]
|
||||
::
|
||||
++ app-paths-from-group
|
||||
|= [=app-name:store group=resource]
|
||||
^- (list resource)
|
||||
|
@ -30,12 +30,15 @@
|
||||
:: .store-name: name of the store to send subscription updates to.
|
||||
:: .update-mark: mark that updates will be tagged with
|
||||
:: .push-hook-name: name of the corresponding push-hook
|
||||
:: .no-validate: If true, don't validate that resource/wire/src match
|
||||
:: up
|
||||
::
|
||||
+$ config
|
||||
$: store-name=term
|
||||
update=mold
|
||||
update-mark=term
|
||||
push-hook-name=term
|
||||
no-validate=_|
|
||||
==
|
||||
::
|
||||
:: $base-state-0: state for the pull hook
|
||||
@ -106,6 +109,14 @@
|
||||
++ on-pull-kick
|
||||
|~ resource
|
||||
*(unit path)
|
||||
:: +resource-for-update: get resources from vase
|
||||
::
|
||||
:: This should be identical to the +resource-for-update arm in the
|
||||
:: corresponding push-hook
|
||||
::
|
||||
++ resource-for-update
|
||||
|~ vase
|
||||
*(list resource)
|
||||
::
|
||||
:: from agent:gall
|
||||
++ on-init
|
||||
@ -470,24 +481,30 @@
|
||||
/helper/pull-hook
|
||||
wire
|
||||
::
|
||||
++ get-conversion
|
||||
.^ tube:clay
|
||||
%cc (scot %p our.bowl) %home (scot %da now.bowl)
|
||||
/[update-mark.config]/resource
|
||||
==
|
||||
::
|
||||
++ give-update
|
||||
^- card
|
||||
[%give %fact ~[/tracking] %pull-hook-update !>(tracking)]
|
||||
::
|
||||
++ check-src
|
||||
|= resources=(set resource)
|
||||
^- ?
|
||||
%+ roll ~(tap in resources)
|
||||
|= [rid=resource out=_|]
|
||||
?: out %.y
|
||||
?~ ship=(~(get by tracking) rid)
|
||||
%.n
|
||||
=(src.bowl u.ship)
|
||||
::
|
||||
++ update-store
|
||||
|= [wire-rid=resource =vase]
|
||||
^- card
|
||||
=/ =wire
|
||||
(make-wire /store)
|
||||
=+ !<(rid=resource (get-conversion vase))
|
||||
?> =(src.bowl (~(got by tracking) rid))
|
||||
?> =(wire-rid rid)
|
||||
=+ resources=(~(gas in *(set resource)) (resource-for-update:og vase))
|
||||
?> ?| no-validate.config
|
||||
?& (check-src resources)
|
||||
(~(has in resources) wire-rid)
|
||||
== ==
|
||||
[%pass wire %agent [our.bowl store-name.config] %poke update-mark.config vase]
|
||||
--
|
||||
--
|
||||
|
@ -67,6 +67,16 @@
|
||||
|* =config
|
||||
$_ ^|
|
||||
|_ bowl:gall
|
||||
::
|
||||
:: +resource-for-update: get affected resources from an update
|
||||
::
|
||||
:: Given a vase of the update, the mark of which is
|
||||
:: update-mark.config, produce the affected resources, if any.
|
||||
::
|
||||
++ resource-for-update
|
||||
|~ vase
|
||||
*(list resource)
|
||||
::
|
||||
:: +take-update: handle update from store
|
||||
::
|
||||
:: Given an update from the store, do other things after proxying
|
||||
@ -145,12 +155,12 @@
|
||||
=* state -
|
||||
^- agent:gall
|
||||
=<
|
||||
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
og ~(. push-hook bowl)
|
||||
hc ~(. +> bowl)
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
::
|
||||
++ on-init
|
||||
=^ cards push-hook
|
||||
on-init:og
|
||||
@ -165,11 +175,9 @@
|
||||
|^
|
||||
?- -.old
|
||||
%1
|
||||
=. cards
|
||||
:_(cards (build-mark:hc %sing))
|
||||
=^ og-cards push-hook
|
||||
(on-load:og inner-state.old)
|
||||
[(weld (flop cards) og-cards) this(state old)]
|
||||
[(weld cards og-cards) this(state old)]
|
||||
::
|
||||
%0
|
||||
%_ $
|
||||
@ -261,6 +269,7 @@
|
||||
(push-updates:hc q.cage.sign)
|
||||
cards
|
||||
==
|
||||
::
|
||||
++ on-leave
|
||||
|= =path
|
||||
=^ cards push-hook
|
||||
@ -269,20 +278,16 @@
|
||||
::
|
||||
++ on-arvo
|
||||
|= [=wire =sign-arvo]
|
||||
?. ?=([%helper %push-hook @ *] wire)
|
||||
=^ cards push-hook
|
||||
(on-arvo:og wire sign-arvo)
|
||||
[cards this]
|
||||
?. ?=(%resource-conversion i.t.t.wire)
|
||||
(on-arvo:def wire sign-arvo)
|
||||
:_ this
|
||||
~[(build-mark:hc %next)]
|
||||
=^ cards push-hook
|
||||
(on-arvo:og wire sign-arvo)
|
||||
[cards this]
|
||||
::
|
||||
++ on-fail
|
||||
|= [=term =tang]
|
||||
=^ cards push-hook
|
||||
(on-fail:og term tang)
|
||||
[cards this]
|
||||
::
|
||||
++ on-peek
|
||||
|= =path
|
||||
^- (unit (unit cage))
|
||||
@ -311,6 +316,7 @@
|
||||
%remove (remove +.action)
|
||||
%revoke (revoke +.action)
|
||||
==
|
||||
::
|
||||
++ add
|
||||
|= rid=resource
|
||||
=. sharing
|
||||
@ -322,7 +328,7 @@
|
||||
=/ pax=path
|
||||
[%resource (en-path:resource rid)]
|
||||
=/ paths=(set path)
|
||||
%- sy
|
||||
%- silt
|
||||
%+ turn
|
||||
(incoming-subscriptions pax)
|
||||
|=([ship pox=path] pox)
|
||||
@ -344,6 +350,7 @@
|
||||
~
|
||||
`[%give %kick ~[path] `her]
|
||||
--
|
||||
::
|
||||
++ incoming-subscriptions
|
||||
|= prefix=path
|
||||
^- (list (pair ship path))
|
||||
@ -371,58 +378,50 @@
|
||||
++ push-updates
|
||||
|= =vase
|
||||
^- (list card:agent:gall)
|
||||
=/ rid=(unit resource)
|
||||
(resource-for-update vase)
|
||||
?~ rid ~
|
||||
=/ rids=(list resource) (resource-for-update vase)
|
||||
=| cards=(list card:agent:gall)
|
||||
|-
|
||||
?~ rids cards
|
||||
=/ prefix=path
|
||||
resource+(en-path:resource u.rid)
|
||||
resource+(en-path:resource i.rids)
|
||||
=/ paths=(list path)
|
||||
%~ tap in
|
||||
%- silt
|
||||
%+ turn
|
||||
(incoming-subscriptions prefix)
|
||||
|=([ship pax=path] pax)
|
||||
?~ paths ~
|
||||
[%give %fact paths update-mark.config vase]~
|
||||
?~ paths $(rids t.rids)
|
||||
%_ $
|
||||
rids t.rids
|
||||
cards (snoc cards [%give %fact paths update-mark.config vase])
|
||||
==
|
||||
::
|
||||
++ forward-update
|
||||
|= update=vase
|
||||
|= =vase
|
||||
^- (list card:agent:gall)
|
||||
=/ rid=resource
|
||||
(need (resource-for-update update))
|
||||
=/ rids=(list resource) (resource-for-update vase)
|
||||
=| cards=(list card:agent:gall)
|
||||
|-
|
||||
?~ rids cards
|
||||
=/ =path
|
||||
resource+(en-path:resource rid)
|
||||
resource+(en-path:resource i.rids)
|
||||
=/ =wire
|
||||
(make-wire resource+(en-path:resource rid))
|
||||
(make-wire resource+(en-path:resource i.rids))
|
||||
=/ dap=term
|
||||
?:(=(our.bowl entity.rid) store-name.config dap.bowl)
|
||||
[%pass wire %agent [entity.rid dap] %poke update-mark.config update]~
|
||||
::
|
||||
++ get-conversion
|
||||
.^ tube:clay
|
||||
%cc (scot %p our.bowl) %home (scot %da now.bowl)
|
||||
/[update-mark.config]/resource
|
||||
?:(=(our.bowl entity.i.rids) store-name.config dap.bowl)
|
||||
%_ $
|
||||
rids t.rids
|
||||
::
|
||||
cards
|
||||
%+ snoc cards
|
||||
[%pass wire %agent [entity.i.rids dap] %poke update-mark.config vase]
|
||||
==
|
||||
::
|
||||
++ resource-for-update
|
||||
|= update=vase
|
||||
^- (unit resource)
|
||||
=/ converted=(each vase (list tank))
|
||||
(mule |.((get-conversion update)))
|
||||
?: ?=(%| -.converted)
|
||||
%- (slog p.converted)
|
||||
~
|
||||
[~ !<(resource p.converted)]
|
||||
::
|
||||
++ build-mark
|
||||
|= rav=?(%sing %next)
|
||||
^- card
|
||||
=/ =wire
|
||||
(make-wire /resource-conversion)
|
||||
=/ =mood:clay
|
||||
[%c da+now.bowl /[update-mark.config]/resource]
|
||||
=/ =rave:clay
|
||||
?:(?=(%next rav) [rav mood] [rav mood])
|
||||
[%pass wire %arvo %c %warp our.bowl [%home `rave]]
|
||||
|= =vase
|
||||
^- (list resource)
|
||||
%~ tap in
|
||||
%- silt
|
||||
(resource-for-update:og vase)
|
||||
--
|
||||
--
|
||||
|
15
pkg/arvo/mar/contact/share.hoon
Normal file
15
pkg/arvo/mar/contact/share.hoon
Normal file
@ -0,0 +1,15 @@
|
||||
/+ *contact-store
|
||||
::
|
||||
|_ share=[%share =ship]
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
++ noun share
|
||||
--
|
||||
::
|
||||
++ grab
|
||||
|%
|
||||
++ noun _share
|
||||
++ json share:share-dejs
|
||||
--
|
||||
--
|
@ -6,22 +6,6 @@
|
||||
|%
|
||||
++ noun upd
|
||||
++ json (update:enjs upd)
|
||||
++ resource
|
||||
|^
|
||||
?- -.upd
|
||||
%initial [nobody %contacts]
|
||||
%add [nobody %contacts]
|
||||
%remove [nobody %contacts]
|
||||
%edit [nobody %contacts]
|
||||
%allow !!
|
||||
%disallow !!
|
||||
%set-public !!
|
||||
==
|
||||
::
|
||||
++ nobody
|
||||
^- @p
|
||||
(bex 128)
|
||||
--
|
||||
--
|
||||
::
|
||||
++ grab
|
||||
|
@ -7,13 +7,6 @@
|
||||
|%
|
||||
++ noun upd
|
||||
++ json (update:enjs upd)
|
||||
++ resource
|
||||
?+ -.q.upd !!
|
||||
?(%run-updates %add-nodes %remove-nodes %add-graph) resource.q.upd
|
||||
?(%remove-graph %archive-graph %unarchive-graph) resource.q.upd
|
||||
?(%add-tag %remove-tag) resource.q.upd
|
||||
?(%add-signatures %remove-signatures) resource.uid.q.upd
|
||||
==
|
||||
++ mime [/application/x-urb-graph-update (as-octs (jam upd))]
|
||||
--
|
||||
::
|
||||
|
@ -4,10 +4,6 @@
|
||||
++ grow
|
||||
|%
|
||||
++ noun upd
|
||||
++ resource
|
||||
?< ?=(%initial -.upd)
|
||||
resource.upd
|
||||
::
|
||||
++ json
|
||||
%+ frond:enjs:format 'groupUpdate'
|
||||
(update:enjs upd)
|
||||
|
@ -4,9 +4,6 @@
|
||||
++ grow
|
||||
|%
|
||||
++ noun update
|
||||
++ resource
|
||||
?> ?=(?(%add %remove %initial-group) -.update)
|
||||
group.update
|
||||
++ json (update:enjs:store update)
|
||||
--
|
||||
::
|
||||
|
@ -45,6 +45,7 @@
|
||||
[%add rid groups+rid metadatum]
|
||||
;< ~ bind:m (poke-our %metadata-store %metadata-action !>(met-action))
|
||||
;< ~ bind:m (poke-our %metadata-push-hook push-hook-act)
|
||||
;< ~ bind:m (poke-our %contact-push-hook push-hook-act)
|
||||
(pure:m !>(~))
|
||||
|
||||
|
||||
|
@ -26,5 +26,6 @@
|
||||
;< ~ bind:m (cleanup-md:view rid)
|
||||
;< ~ bind:m (poke-our %group-store %group-update !>([%remove-group rid ~]))
|
||||
;< ~ bind:m (poke-our %metadata-push-hook push-hook-act)
|
||||
;< ~ bind:m (poke-our %contact-push-hook push-hook-act)
|
||||
;< ~ bind:m (poke-our %group-push-hook push-hook-act)
|
||||
(pure:m !>(~))
|
||||
|
@ -22,6 +22,7 @@
|
||||
:- %pull-hook-action
|
||||
!> ^- action:pull-hook
|
||||
[%remove rid]
|
||||
;< ~ bind:m (poke-our %contact-pull-hook pull-hook-act)
|
||||
;< ~ bind:m (poke-our %metadata-pull-hook pull-hook-act)
|
||||
;< ~ bind:m (poke-our %group-pull-hook pull-hook-act)
|
||||
;< ~ bind:m (poke-our %group-store %group-update !>([%remove-group rid ~]))
|
||||
|
@ -57,6 +57,7 @@ export default class BaseApi<S extends object = {}> {
|
||||
}
|
||||
|
||||
scry<T>(app: string, path: Path): Promise<T> {
|
||||
console.log(path);
|
||||
return fetch(`/~/scry/${app}${path}.json`).then(r => r.json() as Promise<T>);
|
||||
}
|
||||
|
||||
|
@ -34,12 +34,35 @@ export default class ContactsApi extends BaseApi<StoreState> {
|
||||
});
|
||||
}
|
||||
|
||||
allow(ship) {
|
||||
return this.storeAction({
|
||||
allow: ship
|
||||
});
|
||||
}
|
||||
|
||||
setPublic(setPublic: any) {
|
||||
return this.storeAction({
|
||||
'set-public': setPublic
|
||||
});
|
||||
}
|
||||
|
||||
share(recipient, us) {
|
||||
return this.action(
|
||||
'contact-push-hook',
|
||||
'contact-share',
|
||||
{ share: us },
|
||||
recipient
|
||||
);
|
||||
}
|
||||
|
||||
fetchIsAllowed(entity, name, ship, personal) {
|
||||
const isPersonal = personal ? 'true' : 'false';
|
||||
return this.scry<any>(
|
||||
'contact-store',
|
||||
`/is-allowed/${entity}/${name}/${ship}/${isPersonal}`
|
||||
);
|
||||
}
|
||||
|
||||
private storeAction(action: any): Promise<any> {
|
||||
return this.action('contact-store', 'contact-update', action)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useRef, useCallback, useEffect } from 'react';
|
||||
import React, { useRef, useCallback, useEffect, useState } from 'react';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
import { Col } from '@tlon/indigo-react';
|
||||
import _ from 'lodash';
|
||||
@ -36,6 +36,7 @@ export function ChatResource(props: ChatResourceProps) {
|
||||
|
||||
const [,, owner, name] = station.split('/');
|
||||
const ourContact = contacts?.[`~${window.ship}`];
|
||||
console.log(contacts);
|
||||
|
||||
const chatInput = useRef<ChatInput>();
|
||||
|
||||
@ -89,7 +90,15 @@ export function ChatResource(props: ChatResourceProps) {
|
||||
|
||||
return (
|
||||
<Col {...bind} height="100%" overflow="hidden" position="relative">
|
||||
<ShareProfile our={ourContact} />
|
||||
<ShareProfile
|
||||
our={ourContact}
|
||||
api={props.api}
|
||||
recipient={owner}
|
||||
group={group}
|
||||
groupPath={groupPath}
|
||||
hideBanner={() => {
|
||||
setProfileAllowed(true);
|
||||
}} />
|
||||
{dragging && <SubmitDragger />}
|
||||
<ChatWindow
|
||||
mailboxSize={5}
|
||||
|
@ -1,16 +1,100 @@
|
||||
import React from 'react';
|
||||
import React, {
|
||||
useState,
|
||||
useEffect
|
||||
} from 'react';
|
||||
import { Box, Row, Text, BaseImage } from '@tlon/indigo-react';
|
||||
import { uxToHex } from '~/logic/lib/util';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
|
||||
export const ShareProfile = (props) => {
|
||||
const image = (props?.our?.avatar)
|
||||
? <BaseImage src={props.our.avatar} width='24px' height='24px' borderRadius={2} style={{ objectFit: 'cover' }} />
|
||||
: <Row p={1} alignItems="center" borderRadius={2} backgroundColor={`#${uxToHex(props?.our?.color)}` || "#000000"}>
|
||||
<Sigil ship={window.ship} size={16} icon color={`#${uxToHex(props?.our?.color)}` || "#000000"} />
|
||||
</Row>;
|
||||
const pathAsResource = (path) => {
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
const pathArr = path.split('/');
|
||||
if (pathArr.length !== 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
return {
|
||||
entity: pathArr[2],
|
||||
name: pathArr[3]
|
||||
};
|
||||
};
|
||||
|
||||
export const ShareProfile = (props) => {
|
||||
const { api, recipient, hideBanner, group, groupPath } = props;
|
||||
console.log(groupPath);
|
||||
// TODO: use isContactPublic somewhere
|
||||
|
||||
const [showBanner, setShowBanner] = useState(false);
|
||||
const res = pathAsResource(groupPath);
|
||||
|
||||
useEffect(() => {
|
||||
if (!res) { return; }
|
||||
if (!group) { return; }
|
||||
console.log(group);
|
||||
if (group.hidden) {
|
||||
// TODO:
|
||||
// take the union of the pending set and the members set,
|
||||
// subtract ourselves, then if *anyone* has not already been shared with,
|
||||
// show the banner
|
||||
// Promise.all all the members of the set
|
||||
let check =
|
||||
Promise.all()
|
||||
props.api.contacts.fetchIsAllowed(
|
||||
`~${window.ship}`,
|
||||
'personal', // not used
|
||||
recipient,
|
||||
true
|
||||
).then((retVal) => {
|
||||
console.log(retVal);
|
||||
setShowBanner(!retVal);
|
||||
});
|
||||
} else {
|
||||
// TODO:
|
||||
// if the group is not in the allowed-groups set, then show the banner
|
||||
props.api.contacts.fetchIsAllowed(
|
||||
res.entity,
|
||||
res.name,
|
||||
recipient,
|
||||
false
|
||||
).then((retVal) => {
|
||||
console.log(retVal);
|
||||
setShowBanner(!retVal);
|
||||
});
|
||||
}
|
||||
}, [recipient, res, group]);
|
||||
|
||||
const image = (props?.our?.avatar)
|
||||
? (
|
||||
<BaseImage
|
||||
src={props.our.avatar}
|
||||
width='24px'
|
||||
height='24px'
|
||||
borderRadius={2}
|
||||
style={{ objectFit: 'cover' }} />
|
||||
) : (
|
||||
<Row
|
||||
p={1}
|
||||
alignItems="center"
|
||||
borderRadius={2}
|
||||
backgroundColor={!props.our ? `#${uxToHex(props.our.color)}` : "#000000"}>
|
||||
<Sigil
|
||||
ship={window.ship}
|
||||
size={16}
|
||||
color={`#${uxToHex(props?.our?.color)}` || "#000000"}
|
||||
icon />
|
||||
</Row>
|
||||
);
|
||||
|
||||
const onClick = () => {
|
||||
api.contacts.allow(recipient).then(() => {
|
||||
api.contacts.share(recipient, window.ship);
|
||||
});
|
||||
hideBanner();
|
||||
};
|
||||
|
||||
return showBanner ? (
|
||||
<Row
|
||||
height="48px"
|
||||
alignItems="center"
|
||||
@ -22,9 +106,9 @@ export const ShareProfile = (props) => {
|
||||
{image}
|
||||
<Text verticalAlign="middle" pl={2}>Share private profile?</Text>
|
||||
</Row>
|
||||
<Box pr={2}>
|
||||
<Box pr={2} onClick={onClick}>
|
||||
<Text color="blue" bold cursor="pointer">Share</Text>
|
||||
</Box>
|
||||
</Row>
|
||||
);
|
||||
) : null;
|
||||
};
|
||||
|
@ -1,167 +0,0 @@
|
||||
import React from "react";
|
||||
import { Sigil } from "~/logic/lib/sigil";
|
||||
import * as Yup from "yup";
|
||||
|
||||
import { uxToHex } from "~/logic/lib/util";
|
||||
import {
|
||||
ManagedForm as Form,
|
||||
Col,
|
||||
ManagedTextInputField as Input,
|
||||
Box,
|
||||
Text,
|
||||
Row,
|
||||
BaseImage
|
||||
} from "@tlon/indigo-react";
|
||||
import { Formik, FormikHelpers } from "formik";
|
||||
import { Contact } from "~/types/contact-update";
|
||||
import { AsyncButton } from "~/views/components/AsyncButton";
|
||||
import { ColorInput } from "~/views/components/ColorInput";
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import { ImageInput } from "~/views/components/ImageInput";
|
||||
import { S3State } from "~/types";
|
||||
import useLocalState from "~/logic/state/local";
|
||||
|
||||
interface ContactCardProps {
|
||||
contact: Contact;
|
||||
path: string;
|
||||
api: GlobalApi;
|
||||
s3: S3State;
|
||||
rootIdentity: Contact;
|
||||
}
|
||||
|
||||
const formSchema = Yup.object({
|
||||
color: Yup.string(),
|
||||
nickname: Yup.string(),
|
||||
email: Yup.string().matches(
|
||||
new RegExp(
|
||||
String(
|
||||
/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*/.source
|
||||
) +
|
||||
/@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/
|
||||
.source
|
||||
),
|
||||
"Not a valid email"
|
||||
),
|
||||
phone: Yup.string().matches(
|
||||
new RegExp(
|
||||
String(/^\s*(?:\+?(\d{1,3}))?/.source) +
|
||||
/([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/
|
||||
.source
|
||||
),
|
||||
"Not a valid phone"
|
||||
),
|
||||
|
||||
website: Yup.string().matches(
|
||||
new RegExp(
|
||||
String(/[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}/.source) +
|
||||
/\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.source
|
||||
),
|
||||
"Not a valid website"
|
||||
),
|
||||
});
|
||||
|
||||
const emptyContact = {
|
||||
avatar: null,
|
||||
color: '0',
|
||||
nickname: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
website: '',
|
||||
notes: ''
|
||||
};
|
||||
|
||||
export function ContactCard(props: ContactCardProps) {
|
||||
const { hideAvatars, hideNicknames } = useLocalState(({ hideAvatars, hideNicknames }) => ({
|
||||
hideAvatars, hideNicknames
|
||||
}));
|
||||
const us = `~${window.ship}`;
|
||||
const { contact, rootIdentity } = props;
|
||||
const onSubmit = async (values: any, actions: FormikHelpers<Contact>) => {
|
||||
try {
|
||||
if(!contact) {
|
||||
const [,,ship] = props.path.split('/');
|
||||
values.color = uxToHex(values.color);
|
||||
const sharedValues = Object.assign({}, values);
|
||||
sharedValues.avatar = !values.avatar ? null : { url: values.avatar };
|
||||
console.log(values);
|
||||
await props.api.contacts.share(ship, props.path, us, sharedValues);
|
||||
actions.setStatus({ success: null });
|
||||
return;
|
||||
}
|
||||
|
||||
await Object.keys(values).reduce((acc, key) => {
|
||||
const newValue = key !== "color" ? values[key] : uxToHex(values[key]);
|
||||
if (newValue !== contact[key]) {
|
||||
if (key === "avatar") {
|
||||
return acc.then(() =>
|
||||
props.api.contacts.edit(props.path, us, {
|
||||
avatar: { url: newValue },
|
||||
} as any)
|
||||
);
|
||||
}
|
||||
|
||||
return acc.then(() =>
|
||||
props.api.contacts.edit(props.path, us, {
|
||||
[key]: newValue,
|
||||
} as any)
|
||||
);
|
||||
}
|
||||
return acc;
|
||||
}, Promise.resolve());
|
||||
actions.setStatus({ success: null });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
actions.setStatus({ error: e.message });
|
||||
}
|
||||
};
|
||||
|
||||
const hexColor = contact?.color ? `#${uxToHex(contact.color)}` : "#000000";
|
||||
const image = (!hideAvatars && contact?.avatar)
|
||||
? <BaseImage src={contact.avatar} width='100%' height='100%' style={{ objectFit: 'cover' }} />
|
||||
: <Sigil ship={us} size={32} color={hexColor} />;
|
||||
|
||||
const nickname = (!hideNicknames && contact?.nickname) ? contact.nickname : "";
|
||||
|
||||
return (
|
||||
<Box p={4} height="100%" overflowY="auto">
|
||||
<Formik
|
||||
validationSchema={formSchema}
|
||||
initialValues={contact || rootIdentity || emptyContact}
|
||||
onSubmit={onSubmit}
|
||||
>
|
||||
<Form
|
||||
display="grid"
|
||||
gridAutoRows="auto"
|
||||
gridTemplateColumns="100%"
|
||||
gridRowGap="5"
|
||||
maxWidth="400px"
|
||||
width="100%"
|
||||
>
|
||||
<Row
|
||||
borderBottom={1}
|
||||
borderBottomColor="washedGray"
|
||||
pb={3}
|
||||
alignItems="center"
|
||||
>
|
||||
<Box height='32px' width='32px'>
|
||||
{image}
|
||||
</Box>
|
||||
<Box ml={2}>
|
||||
<Text mono={!Boolean(nickname)}>{nickname}</Text>
|
||||
</Box>
|
||||
</Row>
|
||||
<ImageInput id="avatar" label="Avatar" s3={props.s3} />
|
||||
<ColorInput id="color" label="Sigil Color" />
|
||||
<Input id="nickname" label="Nickname" />
|
||||
<Input id="email" label="Email" />
|
||||
<Input id="phone" label="Phone" />
|
||||
<Input id="website" label="Website" />
|
||||
<Input id="notes" label="Notes" />
|
||||
<AsyncButton primary loadingText="Updating..." border>
|
||||
{(contact) ? "Save" : "Share Contact"}
|
||||
</AsyncButton>
|
||||
</Form>
|
||||
</Formik>
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -59,3 +59,4 @@ export function SetStatus(props: any) {
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user