mirror of
https://github.com/urbit/shrub.git
synced 2024-12-20 17:32:11 +03:00
Merge branch 'next/vere' into jo/khan-c3
This commit is contained in:
commit
f9ac078b60
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@ -74,15 +74,15 @@ jobs:
|
||||
# for the docker build. We don't want in on Mac, where it isn't but
|
||||
# it breaks the nix install. The two `if` clauses should be mutually
|
||||
# exclusive
|
||||
- uses: cachix/install-nix-action@v12
|
||||
- uses: cachix/install-nix-action@v13
|
||||
with:
|
||||
extra_nix_config: |
|
||||
system-features = nixos-test benchmark big-parallel kvm
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
- uses: cachix/install-nix-action@v12
|
||||
- uses: cachix/install-nix-action@v13
|
||||
if: ${{ matrix.os != 'ubuntu-latest' }}
|
||||
|
||||
- uses: cachix/cachix-action@v8
|
||||
- uses: cachix/cachix-action@v10
|
||||
with:
|
||||
name: ares
|
||||
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
|
||||
@ -107,8 +107,8 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: cachix/install-nix-action@v12
|
||||
- uses: cachix/cachix-action@v8
|
||||
- uses: cachix/install-nix-action@v13
|
||||
- uses: cachix/cachix-action@v10
|
||||
with:
|
||||
name: ares
|
||||
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
|
||||
|
20
.github/workflows/ops-group-timer.yml
vendored
20
.github/workflows/ops-group-timer.yml
vendored
@ -1,20 +0,0 @@
|
||||
name: group-timer
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'ops/group-timer'
|
||||
jobs:
|
||||
glob:
|
||||
runs-on: ubuntu-latest
|
||||
name: "Create and deploy a glob to ~difmex-passed"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
lfs: true
|
||||
- uses: ./.github/actions/glob
|
||||
with:
|
||||
ship: 'difmex-passed'
|
||||
credentials: ${{ secrets.JANEWAY_SERVICE_KEY }}
|
||||
ssh-sec-key: ${{ secrets.JANEWAY_SSH_SEC_KEY }}
|
||||
ssh-pub-key: ${{ secrets.JANEWAY_SSH_PUB_KEY }}
|
||||
|
4
.github/workflows/release-docker.yml
vendored
4
.github/workflows/release-docker.yml
vendored
@ -16,11 +16,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: cachix/install-nix-action@v12
|
||||
- uses: cachix/install-nix-action@v13
|
||||
with:
|
||||
extra_nix_config: |
|
||||
system-features = nixos-test benchmark big-parallel kvm
|
||||
- uses: cachix/cachix-action@v8
|
||||
- uses: cachix/cachix-action@v10
|
||||
with:
|
||||
name: ares
|
||||
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
|
||||
|
7
.github/workflows/release.yml
vendored
7
.github/workflows/release.yml
vendored
@ -17,8 +17,8 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: cachix/install-nix-action@v12
|
||||
- uses: cachix/cachix-action@v8
|
||||
- uses: cachix/install-nix-action@v13
|
||||
- uses: cachix/cachix-action@v10
|
||||
with:
|
||||
name: ${{ secrets.CACHIX_NAME }}
|
||||
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
|
||||
@ -35,7 +35,8 @@ jobs:
|
||||
- name: Run upload to bootstrap.urbit.org
|
||||
run: |
|
||||
version="$(cat ./pkg/urbit/version)"
|
||||
system="$(nix eval --raw '(builtins.currentSystem)')"
|
||||
system="$(nix-instantiate --eval --expr 'builtins.currentSystem')"
|
||||
system=${system:1:${#system}-2}
|
||||
target="gs://bootstrap.urbit.org/ci/urbit-v${version}-${system}-${GITHUB_SHA:0:9}.tgz"
|
||||
|
||||
gsutil cp -n ./result "$target"
|
||||
|
1
.husky/.gitignore
vendored
1
.husky/.gitignore
vendored
@ -1 +0,0 @@
|
||||
_
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-checkout.\n"; exit 2; }
|
||||
git lfs post-checkout "$@"
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-commit.\n"; exit 2; }
|
||||
git lfs post-commit "$@"
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-merge.\n"; exit 2; }
|
||||
git lfs post-merge "$@"
|
@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
command -v npx > /dev/null || {
|
||||
exit 0
|
||||
}
|
||||
|
||||
npx lint-staged
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/pre-push.\n"; exit 2; }
|
||||
git lfs pre-push "$@"
|
@ -1,11 +0,0 @@
|
||||
> Why do I have a folder named ".vercel" in my project?
|
||||
The ".vercel" folder is created when you link a directory to a Vercel project.
|
||||
|
||||
> What does the "project.json" file contain?
|
||||
The "project.json" file contains:
|
||||
- The ID of the Vercel project that you linked ("projectId")
|
||||
- The ID of the user or team your Vercel project is owned by ("orgId")
|
||||
|
||||
> Should I commit the ".vercel" folder?
|
||||
No, you should not share the ".vercel" folder with anyone.
|
||||
Upon creation, it will be automatically added to your ".gitignore" file.
|
@ -1 +0,0 @@
|
||||
{"orgId":"EDiU8DZExvM9N4unZGYQbG3d","projectId":"prj_fbAU5smemBgtr5t8lsk5ZoT9zNtI"}
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8229a2dc1908d4bb322a3300e68f79e79e3352507b8ef68d40e802bcbdb19550
|
||||
size 5437325
|
||||
oid sha256:049801d388b4cb7203854b4668826688c21089f90430bd547d276e7b59386e8d
|
||||
size 5588170
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:618a74c199baa6d52ae9eea8c40f4f5b15e95b441e743d0f989275321e5b0703
|
||||
size 7299622
|
||||
oid sha256:c27cdb47bccda98ba68556181cae6cd845c6daf8d7426d82adf67c1e8f532be9
|
||||
size 7454265
|
||||
|
@ -12,11 +12,7 @@
|
||||
"watch-libs": "lerna run watch --no-private --parallel",
|
||||
"build-libs": "lerna run build --no-private",
|
||||
"test": "lerna run test",
|
||||
"prepare": "husky install .husky",
|
||||
"bootstrap": "lerna bootstrap",
|
||||
"build:prod": "lerna run build:prod"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,ts,tsx}": "eslint --cache --fix --quiet"
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
=> |% :: external structures
|
||||
+$ id @tasession :: session id
|
||||
+$ house :: all state
|
||||
$: %7
|
||||
$: %8
|
||||
egg=@u :: command count
|
||||
hoc=(map id session) :: conversations
|
||||
acl=(set ship) :: remote access whitelist
|
||||
@ -65,7 +65,7 @@
|
||||
$~ [%ex *hoon]
|
||||
$% [%ur p=@t] :: http GET request
|
||||
[%ge p=dojo-model] :: generator
|
||||
[%te p=term q=(list dojo-source)] :: thread
|
||||
[%te p=[=desk =term] q=(list dojo-source)] :: thread
|
||||
[%dv p=beak q=path] :: core from source
|
||||
[%ex p=hoon] :: hoon expression
|
||||
[%sa p=mark] :: example mark value
|
||||
@ -224,7 +224,7 @@
|
||||
;~ pose
|
||||
;~(plug (cold %ur lus) parse-url)
|
||||
;~(plug (cold %ge lus) parse-model)
|
||||
;~(plug (cold %te hep) sym (star ;~(pfix ace parse-source)))
|
||||
;~(plug (cold %te hep) parse-thread (star ;~(pfix ace parse-source)))
|
||||
;~(plug (cold %as pam) sym ;~(pfix ace parse-source))
|
||||
;~(plug (cold %do cab) parse-hoon ;~(pfix ace parse-source))
|
||||
parse-value
|
||||
@ -278,6 +278,12 @@
|
||||
(most fas sym)
|
||||
==
|
||||
::
|
||||
++ parse-thread
|
||||
;~ plug
|
||||
;~(pose ;~(sfix sym zap) (easy q.dir))
|
||||
sym
|
||||
==
|
||||
::
|
||||
++ parse-hoon tall:hoon-parser
|
||||
::
|
||||
++ parse-rood
|
||||
@ -693,7 +699,7 @@
|
||||
[%sa mark]
|
||||
[%as mark dy-shown]
|
||||
[%do hoon dy-shown]
|
||||
[%te term (list dy-shown)]
|
||||
[%te [desk term] (list dy-shown)]
|
||||
[%ge [desk path] (list dy-shown) (map term (unit dy-shown))]
|
||||
[%dv beak path]
|
||||
==
|
||||
@ -870,7 +876,7 @@
|
||||
(dy-hand %noun q.cag)
|
||||
::
|
||||
++ dy-wool-poke
|
||||
|= [fil=term src=(list dojo-source)]
|
||||
|= [[=desk =term] src=(list dojo-source)]
|
||||
^+ +>+>
|
||||
?> ?=(~ pux)
|
||||
=/ tid (scot %ta (cat 3 'dojo_' (scot %uv (sham eny.hid))))
|
||||
@ -880,8 +886,9 @@
|
||||
[%pass /wool %agent [our.hid %spider] %watch /thread-result/[tid]]
|
||||
%- he-card
|
||||
=/ =cage :: also sub
|
||||
:: TODO: support threads on other desks
|
||||
[%spider-start !>([~ `tid he-beak fil (dy-some src)])]
|
||||
::TODO would be nice if spider supported starting from paths,
|
||||
:: for semantics/abilities/code closer to generators.
|
||||
[%spider-start !>([~ `tid he-beak(q.dir desk) term (dy-some src)])]
|
||||
[%pass /wool %agent [our.hid %spider] %poke cage]
|
||||
::
|
||||
++ dy-make :: build step
|
||||
@ -1522,16 +1529,17 @@
|
||||
|^ =+ old=!<(house-any ole)
|
||||
=? old ?=(%5 -.old)
|
||||
(house-5-to-6 old)
|
||||
=? old ?=(%6 -.old)
|
||||
(house-6-to-7 old)
|
||||
?> ?=(%7 -.old)
|
||||
=? old ?=(?(%6 %7) -.old)
|
||||
(house-6-7-to-8 +.old)
|
||||
?> ?=(%8 -.old)
|
||||
`..on-init(state old)
|
||||
::
|
||||
+$ house-any $%(house house-6 house-5)
|
||||
+$ house-any $%(house house-7 house-6 house-5)
|
||||
::
|
||||
+$ house-6 :: all state
|
||||
$: %6
|
||||
egg=@u :: command count
|
||||
+$ house-7 [%7 house-6-7]
|
||||
+$ house-6 [%6 house-6-7]
|
||||
+$ house-6-7
|
||||
$: egg=@u :: command count
|
||||
hoc=(map id session-6) :: conversations
|
||||
acl=(set ship) :: remote access whitelist
|
||||
== ::
|
||||
@ -1550,10 +1558,10 @@
|
||||
old=(set term) :: used TLVs
|
||||
buf=tape :: multiline buffer
|
||||
== ::
|
||||
++ house-6-to-7
|
||||
|= old=house-6
|
||||
[%7 egg.old (~(run by hoc.old) session-6-to-7) acl.old]
|
||||
++ session-6-to-7
|
||||
++ house-6-7-to-8
|
||||
|= old=house-6-7
|
||||
[%8 egg.old (~(run by hoc.old) session-6-to-8) acl.old]
|
||||
++ session-6-to-8
|
||||
|= old=session-6
|
||||
~? ?=(^ poy.old) [dap.hid %cancelling-for-load]
|
||||
old(poy ~, -.dir [our.hid %base ud+0])
|
||||
|
@ -2,8 +2,8 @@
|
||||
/+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln
|
||||
|%
|
||||
+$ state
|
||||
$~ [%21 *state:drum *state:helm *state:kiln]
|
||||
$>(%21 any-state)
|
||||
$~ [%22 *state:drum *state:helm *state:kiln]
|
||||
$>(%22 any-state)
|
||||
::
|
||||
+$ any-state
|
||||
$% [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)]
|
||||
@ -22,6 +22,7 @@
|
||||
[%19 drum=state-4:drum helm=state:helm kiln=state-6:kiln]
|
||||
[%20 drum=state-4:drum helm=state:helm kiln=state-7:kiln]
|
||||
[%21 drum=state-4:drum helm=state:helm kiln=state-8:kiln]
|
||||
[%22 drum=state-4:drum helm=state:helm kiln=state-9:kiln]
|
||||
==
|
||||
+$ any-state-tuple
|
||||
$: drum=any-state:drum
|
||||
|
@ -1,30 +0,0 @@
|
||||
/- ms=metadata-store
|
||||
/+ crunch
|
||||
:- %say
|
||||
|= [[now=@da * bec=beak] [csv-path=path from=@da ~] [to=@da groups=(list path) content=(unit ?) ~]]
|
||||
=/ our=@p p.bec
|
||||
:: check given path has `csv` mark
|
||||
::
|
||||
?> =(%csv (snag (dec (lent csv-path)) csv-path))
|
||||
:: get all graph associations ship is a part of
|
||||
::
|
||||
=/ associations=associations:ms
|
||||
(~(scry-graph-associations crunch [our now]))
|
||||
:: filter by input groups, if any (default: all from scry)
|
||||
::
|
||||
=/ filtered-associations=associations:ms
|
||||
?~ groups
|
||||
associations
|
||||
%+ filter-associations-by-group-resources.crunch
|
||||
associations
|
||||
(paths-to-resources.crunch groups)
|
||||
:: walk graphs to extract content
|
||||
::
|
||||
=/ file-content=wain
|
||||
%: ~(walk-graph-associations crunch [our now])
|
||||
filtered-associations
|
||||
?~ content %.n u.content
|
||||
from
|
||||
?: =(*@da to) now to
|
||||
==
|
||||
[%helm-pass (note-write-csv-to-clay.crunch csv-path file-content)]
|
@ -1,6 +1,34 @@
|
||||
:- %say
|
||||
:: |nuke: wipe agent state & subscriptions after confirmation
|
||||
::
|
||||
/+ *generators
|
||||
:- %ask
|
||||
|= $: [now=@da eny=@uvJ bec=beak]
|
||||
[=term ~]
|
||||
desk=_|
|
||||
[desk=_| hard=_|]
|
||||
==
|
||||
[%kiln-nuke term desk]
|
||||
?: hard (produce %kiln-nuke term desk)
|
||||
=/ m1
|
||||
'nuking agents will permanently delete all their state and subscriptions.'
|
||||
=/ m2
|
||||
'if other agents depend on the one(s) you nuke, \
|
||||
/their behavior could be negatively impacted. \
|
||||
/if you do not understand the risks, you may \
|
||||
/want to contact the agent\'s developers.'
|
||||
=/ m3
|
||||
%+ rap 3
|
||||
:~ 'are you sure you want to continue and nuke '
|
||||
::
|
||||
?. desk (cat 3 '%' term)
|
||||
(cat 3 'all agents in ' term)
|
||||
::
|
||||
'?'
|
||||
==
|
||||
::NOTE yes, printing order is weird
|
||||
%+ print m3
|
||||
%+ print m2
|
||||
%+ print m1
|
||||
%+ prompt [%& %prompt "nuke? (y/N) "]
|
||||
|= in=tape
|
||||
?. |(=("y" in) =("Y" in) =("yes" in))
|
||||
no-product
|
||||
(produce %kiln-nuke term desk)
|
||||
|
@ -8,11 +8,11 @@
|
||||
::
|
||||
:- %say
|
||||
|= $: [now=@da eny=@uvJ bec=beak]
|
||||
[arg=?(~ [%disable ~] [her=@p sud=@tas ~]) ~]
|
||||
arg=?([%disable ~] [her=@p sud=?(~ [@tas ~])])
|
||||
~
|
||||
==
|
||||
?~ arg
|
||||
:- %kiln-ota-info ~
|
||||
:- %kiln-ota
|
||||
:- %kiln-install
|
||||
?: ?=([%disable ~] arg)
|
||||
~
|
||||
`[her sud]:arg
|
||||
[%base p.bec %base]
|
||||
:+ %base her.arg
|
||||
?@(sud.arg %kids -.sud.arg)
|
||||
|
@ -1,356 +0,0 @@
|
||||
/- c=crunch, gs=graph-store, ms=metadata-store, p=post, r=resource
|
||||
::
|
||||
=<
|
||||
|_ [our=ship now=@da]
|
||||
++ walk-graph-associations
|
||||
|= [=associations:ms content=? from=@da to=@da]
|
||||
^- wain
|
||||
:: graph resources in `our`; used to avoid scrying, e.g.,
|
||||
:: a graph `our` has left and can no longer access
|
||||
::
|
||||
=/ accessible-graphs=(set resource:r) (scry-graph-resources)
|
||||
%- ~(rep by associations)
|
||||
|= [[=md-resource:ms =association:ms] out=wain]
|
||||
^- wain
|
||||
?. ?=(%graph app-name.md-resource)
|
||||
out
|
||||
?. ?=(%graph -.config.metadatum.association)
|
||||
out
|
||||
:: ensure graph, given by association, exists in `our`
|
||||
::
|
||||
?. (~(has in accessible-graphs) resource.md-resource)
|
||||
out
|
||||
:: scry the graph
|
||||
::
|
||||
=/ graph=(unit graph:gs) (scry-graph resource.md-resource)
|
||||
?~ graph
|
||||
out
|
||||
:: prepare channel-info argument
|
||||
::
|
||||
=/ channel-info=channel-info:c
|
||||
:* group.association
|
||||
resource.md-resource
|
||||
module.config.metadatum.association
|
||||
==
|
||||
:: walk the graph
|
||||
::
|
||||
?+ module.config.metadatum.association
|
||||
:: non-chat (e.g. links & notes)
|
||||
::
|
||||
%+ weld out
|
||||
%: walk-nested-graph-for-most-recent-entries
|
||||
u.graph
|
||||
content
|
||||
channel-info
|
||||
from
|
||||
to
|
||||
==
|
||||
::
|
||||
%chat
|
||||
%+ weld out
|
||||
%: walk-chat-graph
|
||||
u.graph
|
||||
content
|
||||
channel-info
|
||||
from
|
||||
to
|
||||
==
|
||||
==
|
||||
::
|
||||
++ scry-graph
|
||||
|= graph-resource=resource:r
|
||||
^- (unit graph:gs)
|
||||
=/ scry-response=update:gs
|
||||
.^ update:gs
|
||||
%gx
|
||||
(scot %p our)
|
||||
%graph-store
|
||||
(scot %da now)
|
||||
%graph
|
||||
(scot %p entity.graph-resource)
|
||||
name.graph-resource
|
||||
/noun
|
||||
==
|
||||
?. ?=(%add-graph -.q.scry-response)
|
||||
~
|
||||
?~ graph.q.scry-response
|
||||
~
|
||||
[~ graph.q.scry-response]
|
||||
::
|
||||
++ scry-graph-resources
|
||||
|= ~
|
||||
^- (set resource:r)
|
||||
=/ scry-response=update:gs
|
||||
.^ update:gs
|
||||
%gx
|
||||
(scot %p our)
|
||||
%graph-store
|
||||
(scot %da now)
|
||||
/keys/noun
|
||||
==
|
||||
?. ?=(%keys -.q.scry-response)
|
||||
~
|
||||
resources.q.scry-response
|
||||
:: helper arm for callers to get graph associations
|
||||
:: to pass to `walk-graph-associations`
|
||||
::
|
||||
++ scry-graph-associations
|
||||
|= ~
|
||||
^- associations:ms
|
||||
.^ associations:ms
|
||||
%gx
|
||||
(scot %p our)
|
||||
%metadata-store
|
||||
(scot %da now)
|
||||
/app-name/graph/noun
|
||||
==
|
||||
--
|
||||
::
|
||||
|%
|
||||
::
|
||||
:: parsing and formatting
|
||||
::
|
||||
++ resource-to-cord
|
||||
|= =resource:r
|
||||
^- @t
|
||||
(rap 3 (scot %p entity.resource) '/' (scot %tas name.resource) ~)
|
||||
::
|
||||
++ paths-to-resources
|
||||
|= paxs=(list path)
|
||||
^- (set resource:r)
|
||||
%- ~(gas in *(set resource:r))
|
||||
(turn paxs path-to-resource)
|
||||
::
|
||||
++ path-to-resource
|
||||
|= pax=path
|
||||
^- resource:r
|
||||
=/ entity=@p (slav %p -.pax)
|
||||
=/ name=@tas -.+.pax
|
||||
[entity name]
|
||||
::
|
||||
++ escape-characters-in-cord
|
||||
|= =cord
|
||||
^- @t
|
||||
%- crip
|
||||
%- mesc
|
||||
:: specific to CSVs: make sure content does not
|
||||
:: contain commas (only allowed as delimiters)
|
||||
::
|
||||
%- replace-tape-commas-with-semicolons
|
||||
%- trip
|
||||
cord
|
||||
::
|
||||
++ replace-tape-commas-with-semicolons
|
||||
|= string=tape
|
||||
^- tape
|
||||
=/ comma-indices=(list @ud) (fand "," string)
|
||||
|-
|
||||
^- tape
|
||||
?~ comma-indices
|
||||
string
|
||||
$(string (snap string i.comma-indices ';'), comma-indices t.comma-indices)
|
||||
::
|
||||
++ contents-to-cord
|
||||
|= contents=(list content:p)
|
||||
^- @t
|
||||
?~ contents
|
||||
''
|
||||
%+ join-cords
|
||||
' '
|
||||
(turn contents content-to-cord)
|
||||
::
|
||||
++ content-to-cord
|
||||
|= =content:p
|
||||
^- @t
|
||||
?- -.content
|
||||
%text (escape-characters-in-cord text.content)
|
||||
%mention (scot %p ship.content)
|
||||
%url url.content
|
||||
%code expression.content :: TODO: also print output?
|
||||
%reference (reference-content-to-cord reference.content)
|
||||
==
|
||||
::
|
||||
++ reference-content-to-cord
|
||||
|= =reference:p
|
||||
^- @t
|
||||
?- -.reference
|
||||
%group (resource-to-cord group.reference)
|
||||
%graph (rap 3 (resource-to-cord group.reference) ': ' (resource-to-cord resource.uid.reference) ~)
|
||||
==
|
||||
::
|
||||
++ format-post-to-comma-separated-cord
|
||||
|= [=post:gs =channel-info:c]
|
||||
^- @t
|
||||
%+ join-cords
|
||||
','
|
||||
:~ (scot %da time-sent.post)
|
||||
(scot %p author.post)
|
||||
(resource-to-cord group.channel-info)
|
||||
(resource-to-cord channel.channel-info)
|
||||
(scot %tas channel-type.channel-info)
|
||||
:: exclude content; optionally add later
|
||||
::
|
||||
==
|
||||
::
|
||||
++ join-cords
|
||||
|= [delimiter=@t cords=(list @t)]
|
||||
^- @t
|
||||
%+ roll cords
|
||||
|= [cord=@t out=@t]
|
||||
^- @t
|
||||
?: =('' out)
|
||||
:: don't put delimiter before first element
|
||||
::
|
||||
cord
|
||||
(rap 3 out delimiter cord ~)
|
||||
::
|
||||
:: walking graphs
|
||||
::
|
||||
++ walk-chat-graph
|
||||
|= [=graph:gs content=? =channel-info:c from=@da to=@da]
|
||||
^- wain
|
||||
%- flop
|
||||
%+ roll
|
||||
:: filter by time
|
||||
::
|
||||
%+ only-nodes-older-than to
|
||||
%+ only-nodes-newer-than from
|
||||
~(val by graph)
|
||||
|= [=node:gs out=wain]
|
||||
^- wain
|
||||
?- -.post.node
|
||||
%|
|
||||
:: do not output deleted posts
|
||||
::
|
||||
out
|
||||
%&
|
||||
?~ contents.p.post.node
|
||||
:: do not output structural nodes
|
||||
::
|
||||
out
|
||||
:_ out
|
||||
=/ post-no-content=@t (format-post-to-comma-separated-cord p.post.node channel-info)
|
||||
?- content
|
||||
%| post-no-content
|
||||
%&
|
||||
%+ join-cords ','
|
||||
~[post-no-content (contents-to-cord contents.p.post.node)]
|
||||
==
|
||||
==
|
||||
::
|
||||
++ walk-nested-graph-for-most-recent-entries
|
||||
|= [=graph:gs content=? =channel-info:c from=@da to=@da]
|
||||
^- wain
|
||||
=| out=wain
|
||||
=| most-recent-post-content=@t
|
||||
=/ nodes
|
||||
:: filter by time
|
||||
::
|
||||
%+ only-nodes-older-than to
|
||||
%+ only-nodes-newer-than from
|
||||
~(val by graph)
|
||||
%- flop
|
||||
|-
|
||||
^- wain
|
||||
?~ nodes
|
||||
?: =('' most-recent-post-content)
|
||||
:: don't return a cell: `['' ~]`
|
||||
:: we want either an empty list `~`
|
||||
:: or a list populated with actual entries
|
||||
::
|
||||
out
|
||||
[most-recent-post-content out]
|
||||
::
|
||||
=? out ?=(%graph -.children.i.nodes)
|
||||
%+ weld out
|
||||
%: walk-nested-graph-for-most-recent-entries
|
||||
p.children.i.nodes
|
||||
content
|
||||
channel-info
|
||||
from
|
||||
to
|
||||
==
|
||||
::
|
||||
?- -.post.i.nodes
|
||||
%|
|
||||
:: do not keep deleted posts
|
||||
::
|
||||
$(nodes t.nodes)
|
||||
%&
|
||||
?~ contents.p.post.i.nodes
|
||||
:: do not keep structural nodes
|
||||
::
|
||||
$(nodes t.nodes)
|
||||
=/ post-no-content=@t (format-post-to-comma-separated-cord p.post.i.nodes channel-info)
|
||||
%= $
|
||||
nodes t.nodes
|
||||
most-recent-post-content
|
||||
?- content
|
||||
%| post-no-content
|
||||
%&
|
||||
%+ join-cords ','
|
||||
~[post-no-content (contents-to-cord contents.p.post.i.nodes)]
|
||||
==
|
||||
==
|
||||
==
|
||||
::
|
||||
:: filters
|
||||
::
|
||||
++ filter-associations-by-group-resources
|
||||
|= [=associations:ms group-resources=(set resource:r)]
|
||||
^- associations:ms
|
||||
%- ~(rep by associations)
|
||||
|= [[=md-resource:ms =association:ms] out=associations:ms]
|
||||
^- associations:ms
|
||||
?. (~(has in group-resources) group.association)
|
||||
out
|
||||
(~(put by out) md-resource association)
|
||||
:: wrappers for intuitive use of `filter-nodes-by-timestamp`:
|
||||
:: pass `nodes` as given by the `graph-store` scry and no
|
||||
:: need to worry about comparators
|
||||
::
|
||||
++ only-nodes-older-than
|
||||
|= [time=@da nodes=(list node:gs)]
|
||||
(filter-nodes-by-timestamp nodes lte time)
|
||||
::
|
||||
++ only-nodes-newer-than
|
||||
|= [time=@da nodes=(list node:gs)]
|
||||
%- flop
|
||||
(filter-nodes-by-timestamp (flop nodes) gte time)
|
||||
::
|
||||
++ filter-nodes-by-timestamp
|
||||
|= [nodes=(list node:gs) comparator=$-([@ @] ?) time=@da]
|
||||
=| out=(list node:gs)
|
||||
:: return `out` in same time-order as `nodes`
|
||||
::
|
||||
%- flop
|
||||
|-
|
||||
^- (list node:gs)
|
||||
?~ nodes
|
||||
out
|
||||
?- -.post.i.nodes
|
||||
%|
|
||||
:: skip deleted posts
|
||||
::
|
||||
$(nodes t.nodes)
|
||||
%&
|
||||
?. (comparator time-sent.p.post.i.nodes time)
|
||||
:: assume:
|
||||
:: * time is monotonic
|
||||
:: * first `%.n` we hit indicates nodes further on are `%.n`
|
||||
:: (i.e. `nodes` must be ordered st. they start `%.y`,
|
||||
:: e.g. if want all `nodes` older than given time,
|
||||
:: `nodes` must start with oldest and comparator is `lth`)
|
||||
::
|
||||
out
|
||||
$(nodes t.nodes, out [i.nodes out])
|
||||
==
|
||||
::
|
||||
:: io
|
||||
::
|
||||
++ note-write-csv-to-clay
|
||||
|= [pax=path file-content=wain]
|
||||
?> =(%csv (snag (dec (lent pax)) pax))
|
||||
[%c [%info %base %& [pax %ins %csv !>(file-content)]~]]
|
||||
::
|
||||
--
|
@ -4,8 +4,9 @@
|
||||
=, format
|
||||
=* dude dude:gall
|
||||
|%
|
||||
+$ state state-8
|
||||
+$ state-8 [%8 pith-8]
|
||||
+$ state state-9
|
||||
+$ state-9 [%9 pith-9]
|
||||
+$ state-8 [%8 pith-9]
|
||||
+$ state-7 [%7 pith-7]
|
||||
+$ state-6 [%6 pith-6]
|
||||
+$ state-5 [%5 pith-5]
|
||||
@ -16,7 +17,8 @@
|
||||
+$ state-0 [%0 pith-0]
|
||||
+$ any-state
|
||||
$~ *state
|
||||
$% state-8
|
||||
$% state-9
|
||||
state-8
|
||||
state-7
|
||||
state-6
|
||||
state-5
|
||||
@ -27,7 +29,7 @@
|
||||
state-0
|
||||
==
|
||||
::
|
||||
+$ pith-8
|
||||
+$ pith-9
|
||||
$: wef=(unit weft)
|
||||
rem=(map desk per-desk) ::
|
||||
syn=(map kiln-sync let=@ud) ::
|
||||
@ -380,7 +382,10 @@
|
||||
?~ rail.a ~
|
||||
`[(get-publisher our d now) u.rail.a]
|
||||
::
|
||||
?> ?=(%8 -.old)
|
||||
=? old ?=(%8 -.old)
|
||||
[%9 +.old]
|
||||
::
|
||||
?> ?=(%9 -.old)
|
||||
=. state old
|
||||
::
|
||||
=? kiln (lth old-version %7)
|
||||
@ -389,8 +394,31 @@
|
||||
abet:(install:vats %base [her sud]:u.old-ota)
|
||||
=? kiln (lth old-version %7)
|
||||
abet:gall-lyv:vats
|
||||
:: kiln %7 had a bug where it failed to properly emit a +listen
|
||||
:: due to an unexpected crash. here we detect the cause of the crash
|
||||
:: (not-yet-installed desks) and emit the +listen anew to make sure we
|
||||
:: stay aware of commits to base.
|
||||
::
|
||||
=? kiln
|
||||
?& =(%8 old-version)
|
||||
::
|
||||
%+ lien ~(tap by ark.old)
|
||||
|= [d=desk *]
|
||||
=- =(0 rev)
|
||||
.^([rev=@ud @da] %cw /(scot %p our)/[d]/(scot %da now))
|
||||
==
|
||||
take-commit:(abed:vats %base)
|
||||
=? kiln ?=(^ wef)
|
||||
=/ except=(set desk) (sy %base %kids ~)
|
||||
=/ except=(set desk)
|
||||
=/ base=(set desk) (sy %base %kids ~)
|
||||
%- ~(gas in base)
|
||||
%+ murn ~(tap by ark.old)
|
||||
|= [loc=desk ark=arak]
|
||||
^- (unit desk)
|
||||
?. liv.rein.ark `loc
|
||||
?~ rail.ark `loc
|
||||
?: paused.u.rail.ark `loc
|
||||
~
|
||||
(bump:vats u.wef except force=%.n)
|
||||
=. wef ~
|
||||
abet:kiln
|
||||
@ -551,8 +579,8 @@
|
||||
=. vats (abed lac)
|
||||
?^ rail.rak
|
||||
go
|
||||
~> %slog.(fmt "{<lac>} already installed locally, ignoring")
|
||||
vats
|
||||
~> %slog.(fmt "{<lac>} already installed locally, refreshing")
|
||||
update-running-dudes
|
||||
::
|
||||
++ go
|
||||
=. loc lac
|
||||
@ -586,7 +614,7 @@
|
||||
vats
|
||||
~> %slog.(fmt "{<lac>} pausing updates")
|
||||
=/ rel ral
|
||||
=. rail.rak `rel(paused &, aeon 0)
|
||||
=. rail.rak `rel(paused &, aeon 0, next ~)
|
||||
vats
|
||||
::
|
||||
:: +gall-lyv: watch gall source for reloading
|
||||
@ -710,7 +738,11 @@
|
||||
~> %slog.(fmt "bump {<desk>} to {<[lal num]:kel>}")
|
||||
=< abet ^+ vats
|
||||
=. vats (abed desk)
|
||||
?: =([~ kel] (read-kelvin-local our desk now))
|
||||
=/ kul (read-kelvin-local our desk now)
|
||||
?~ kul
|
||||
~> %slog.(fmt "{here} not yet installed")
|
||||
vats
|
||||
?: =(kel u.kul)
|
||||
~> %slog.(fmt "{here} already at {<[lal num]:kel>}")
|
||||
update-running-dudes
|
||||
=^ tem rail.rak (crank-next %| kel)
|
||||
@ -874,20 +906,23 @@
|
||||
::
|
||||
?. (~(has by ark) lac)
|
||||
kiln
|
||||
=. vats (from-wire wire)
|
||||
take-commit
|
||||
::
|
||||
++ take-commit
|
||||
^+ kiln
|
||||
=. kiln
|
||||
=< abet
|
||||
=. vats (from-wire wire)
|
||||
~> %slog.(fmt "commit detected at {here}")
|
||||
=. rail.rak
|
||||
?~ rail.rak ~
|
||||
`[(get-publisher our loc now) +.u.rail.rak]
|
||||
=. vats (emil listen:pass (diff:give %commit loc rak) ~)
|
||||
|
||||
?. liv.rein.rak
|
||||
~> %slog.(fmt "{<loc>} not running")
|
||||
vats
|
||||
update-running-dudes
|
||||
?. =(%base lac)
|
||||
?. =(%base loc)
|
||||
kiln
|
||||
=/ kel=[@tas @ud]
|
||||
?~ rail.rak zuse/zuse
|
||||
@ -912,7 +947,7 @@
|
||||
~> %slog.(fmt "merge into {<loc>} succeeded")
|
||||
?. =(%base loc)
|
||||
vats
|
||||
~> %slog.(fmt "merging %base into %kids at {<kel>}")
|
||||
~> %slog.(fmt "merging %base into %kids")
|
||||
(emit merge-kids:pass)
|
||||
::
|
||||
++ take-merge-kids
|
||||
@ -970,7 +1005,9 @@
|
||||
++ crank-next
|
||||
|= new=(each aeon weft)
|
||||
^+ [match=*(unit rung) rail.rak]
|
||||
?~ rail.rak !!
|
||||
?~ rail.rak
|
||||
~| [%no-rail-for desk=loc]
|
||||
!!
|
||||
=/ rog next.u.rail.rak
|
||||
=- [match `u.rail.rak(next next)]
|
||||
|- ^- [match=(unit rung) next=(list rung)]
|
||||
|
@ -1,15 +0,0 @@
|
||||
=, format
|
||||
=, mimes:html
|
||||
|_ csv=wain
|
||||
::
|
||||
++ grab :: convert from
|
||||
|%
|
||||
++ mime |=((pair mite octs) (to-wain q.q))
|
||||
++ noun wain :: clam from %noun
|
||||
--
|
||||
++ grow
|
||||
|%
|
||||
++ mime [/text/csv (as-octs (of-wain csv))]
|
||||
--
|
||||
++ grad %mime
|
||||
--
|
@ -1,9 +0,0 @@
|
||||
/- resource
|
||||
::
|
||||
|%
|
||||
+$ channel-info
|
||||
$: group=resource:resource
|
||||
channel=resource:resource
|
||||
channel-type=term
|
||||
==
|
||||
--
|
@ -4086,6 +4086,10 @@
|
||||
++ read-u
|
||||
|= [yon=aeon pax=path]
|
||||
^- (unit (unit (each [%flag (hypo ?)] lobe)))
|
||||
:: if asked for version 0, that never exists, so always give false
|
||||
::
|
||||
?: =(0 yon)
|
||||
``[%& %flag -:!>(*?) |]
|
||||
:: if asked for a future version, we don't have an answer
|
||||
::
|
||||
?~ tak=(~(get by hit.dom) yon)
|
||||
|
@ -66,7 +66,7 @@
|
||||
=/ fire-arm=nock
|
||||
~| [%failed-to-compile-test-arm name]
|
||||
q:(~(mint ut typ) p:!>(*tang) [%limb name])
|
||||
[name |.(;;(tang .*(cor fire-arm)))]
|
||||
[name |.(;;(tang ~>(%bout.[1 name] .*(cor fire-arm))))]
|
||||
:: +has-test-prefix: does the arm define a test we should run?
|
||||
::
|
||||
++ has-test-prefix
|
||||
|
@ -36,6 +36,14 @@
|
||||
:+ "set of three"
|
||||
0xc7c0.c1c0.c3c0.c1c0
|
||||
l+[l+~ l+[l+~ ~] l+[l+~ l+[l+~ ~] ~] ~]
|
||||
::
|
||||
:+ "list with zero byte"
|
||||
0xc311.0022
|
||||
l+~[b+1^0x11 b+1^0x0 b+1^0x22]
|
||||
::
|
||||
:+ "list of zero bytes"
|
||||
0xc300.0000
|
||||
l+~[b+1^0x0 b+1^0x0 b+1^0x0]
|
||||
==
|
||||
::
|
||||
|%
|
||||
@ -48,8 +56,8 @@
|
||||
%+ weld
|
||||
%+ category "encode"
|
||||
%+ expect-eq
|
||||
!> dat
|
||||
!> (encode rlp)
|
||||
!> `@ux`dat
|
||||
!> `@ux`(encode rlp)
|
||||
%+ category "decode"
|
||||
%+ expect-eq
|
||||
!> rlp
|
||||
|
@ -51,4 +51,103 @@
|
||||
dcf7.12fc.3667.bb5a.cb13.94a0.382f.0c95.7ef4.
|
||||
20dd.dfaa.e6f8.beaa.09c1.f162.a5a8.37a3.7237.
|
||||
77c2.9c6a.7a05.65a5
|
||||
::
|
||||
++ test-signing-transaction-to-zero
|
||||
%+ expect-eq
|
||||
!> %+ sign-typed-transaction:key:ethereum
|
||||
:- %0x0
|
||||
:* 14
|
||||
5.000.000.000
|
||||
21.000
|
||||
0x0
|
||||
100.000.000.000.000.000
|
||||
0x0
|
||||
0x3
|
||||
==
|
||||
0x7f50.12dc.a92e.4aef.d3e1.a9f7.e761.f459.
|
||||
c350.74e0.2f0c.93eb.5bb2.dafb.f5ea.8058
|
||||
!> 0xf86c.0e85.012a.05f2.0082.5208.9400.0000.0000.
|
||||
0000.0000.0000.0000.0000.0000.0000.0088.0163.
|
||||
4578.5d8a.0000.8029.a0f6.9c2c.fb99.2673.928e.
|
||||
9fdd.5056.487d.3664.48e3.37c3.c024.4187.544a.
|
||||
231e.c67a.98a0.0d6d.eb23.173b.26eb.62c7.3ad2.
|
||||
3bc2.afb9.efac.6879.f6b2.8063.f686.586e.31da.
|
||||
2343
|
||||
::
|
||||
++ test-signing-transaction-1559
|
||||
%+ expect-eq
|
||||
!> 0x2f8.7303.0b84.3b9a.ca00.8501.2a05.f200.8252.
|
||||
0894.24f9.63d6.9f36.d51c.c40d.5208.2d49.78d2.
|
||||
c4c2.7a17.8801.6345.785d.8a00.0080.c080.a05d.
|
||||
dc02.7d72.48d2.d542.75c7.3f1b.5bac.edd6.5af9.
|
||||
d136.5829.e637.7473.1ebf.5ca6.86a0.404b.71cc.
|
||||
a3d0.409f.dd84.9857.fb15.0f7d.f943.9fca.c425.
|
||||
c141.236a.a963.6528.2bb5
|
||||
!> %+ sign-typed-transaction:key:ethereum
|
||||
:- %0x2
|
||||
:* 0x3
|
||||
11
|
||||
1.000.000.000
|
||||
5.000.000.000
|
||||
21.000
|
||||
0x24f9.63d6.9f36.d51c.c40d.5208.2d49.78d2.c4c2.7a17
|
||||
100.000.000.000.000.000
|
||||
0x0
|
||||
~
|
||||
==
|
||||
0x7f50.12dc.a92e.4aef.d3e1.a9f7.e761.f459.
|
||||
c350.74e0.2f0c.93eb.5bb2.dafb.f5ea.8058
|
||||
::
|
||||
++ test-signing-transaction-1559-access-list
|
||||
%+ expect-eq
|
||||
!> 0x2.f8ac.030c.8477.3594.0085.0254.0be4.0082.
|
||||
7530.9424.f963.d69f.36d5.1cc4.0d52.082d.4978.
|
||||
d2c4.c27a.1788.0163.4578.5d8a.0000.80f8.38f7.
|
||||
9424.f963.d69f.36d5.1cc4.0d52.082d.4978.d2c4.
|
||||
c27a.17e1.a000.0000.0000.0000.0000.0000.0000.
|
||||
0000.0000.0000.0000.0000.0000.0000.0000.0000.
|
||||
0101.a015.5039.4a51.0a1a.601a.54fb.147d.e17f.
|
||||
a6b9.bd41.9bdb.1654.de06.b7bc.3481.f67e.4ba0.
|
||||
4e88.0574.d378.6ede.1de2.586a.fe98.e30f.d63c.
|
||||
ef3b.e31c.76a9.a0bd.66a8.aef7.8191
|
||||
!> %+ sign-typed-transaction:key:ethereum
|
||||
:- %0x2
|
||||
:* 0x3
|
||||
12
|
||||
2.000.000.000
|
||||
10.000.000.000
|
||||
30.000
|
||||
0x24f9.63d6.9f36.d51c.c40d.5208.2d49.78d2.c4c2.7a17
|
||||
100.000.000.000.000.000
|
||||
0x0
|
||||
%+ ~(add ja *(jar address:ethereum @ux))
|
||||
0x24f9.63d6.9f36.d51c.c40d.5208.2d49.78d2.c4c2.7a17
|
||||
0x1
|
||||
==
|
||||
0x7f50.12dc.a92e.4aef.d3e1.a9f7.e761.f459.
|
||||
c350.74e0.2f0c.93eb.5bb2.dafb.f5ea.8058
|
||||
::
|
||||
++ test-signing-transaction-1559-to-zero
|
||||
%+ expect-eq
|
||||
!> 0x2f8.7303.0f84.3b9a.ca00.8501.2a05.f200.8252.
|
||||
0894.0000.0000.0000.0000.0000.0000.0000.0000.
|
||||
0000.0000.8801.6345.785d.8a00.0080.c080.a0c5.
|
||||
43ea.1ee9.04d1.5f9f.d23d.e881.672f.06f3.41e2.
|
||||
69e0.fedc.1ed0.4f0b.20f0.1679.06a0.442e.fe89.
|
||||
1bb6.48cf.d39b.20aa.5b1f.8a16.7be2.0ee2.d45b.
|
||||
3d3d.7b0a.bce5.1dc7.1232
|
||||
!> %+ sign-typed-transaction:key:ethereum
|
||||
:- %0x2
|
||||
:* 0x3
|
||||
15
|
||||
1.000.000.000
|
||||
5.000.000.000
|
||||
21.000
|
||||
0x0
|
||||
100.000.000.000.000.000
|
||||
0x0
|
||||
~
|
||||
==
|
||||
0x7f50.12dc.a92e.4aef.d3e1.a9f7.e761.f459.
|
||||
c350.74e0.2f0c.93eb.5bb2.dafb.f5ea.8058
|
||||
--
|
||||
|
@ -22,29 +22,77 @@
|
||||
%- serialize-point
|
||||
(priv-to-pub prv)
|
||||
::
|
||||
++ sign-typed-transaction
|
||||
|= [tx=typed-transaction:rpc pk=@]
|
||||
^- @ux
|
||||
=- (cat 3 - -.tx)
|
||||
?- -.tx
|
||||
%0x0 (sign-transaction +.tx pk)
|
||||
%0x2 (sign-transaction-1559 +.tx pk)
|
||||
==
|
||||
::
|
||||
++ sign-transaction
|
||||
=, crypto
|
||||
|= [tx=transaction:rpc pk=@]
|
||||
^- @ux
|
||||
:: hash the raw transaction data
|
||||
=/ hash=@
|
||||
=/ dat=@
|
||||
%- encode-atoms:rlp
|
||||
:: with v=chain-id, r=0, s=0
|
||||
tx(chain-id [chain-id.tx 0 0 ~])
|
||||
=+ wid=(met 3 dat)
|
||||
%- keccak-256:keccak
|
||||
[wid (rev 3 wid dat)]
|
||||
:: sign transaction hash with private key
|
||||
=+ (ecdsa-raw-sign:secp256k1:secp hash pk)
|
||||
:: complete transaction is raw data, with r and s
|
||||
:: taken from the signature, and v as per eip-155
|
||||
%- encode-atoms:rlp
|
||||
tx(chain-id [:(add (mul chain-id.tx 2) 35 v) r s ~])
|
||||
|^ ^- @ux
|
||||
:: hash the raw transaction data
|
||||
=/ hash=@
|
||||
%- keccak-256:keccak
|
||||
=+ dat=(encode chain-id.tx 0 0)
|
||||
=+ wid=(met 3 dat)
|
||||
[wid (rev 3 wid dat)]
|
||||
:: sign transaction hash with private key
|
||||
=+ (ecdsa-raw-sign:secp256k1:secp hash pk)
|
||||
:: complete transaction is raw data, with r and s
|
||||
:: taken from the signature, and v as per eip-155
|
||||
(encode :(add (mul chain-id.tx 2) 35 v) r s)
|
||||
::
|
||||
++ encode
|
||||
|= [v=@ r=@ s=@]
|
||||
%+ encode:rlp %l
|
||||
tx(to b+20^to.tx, chain-id [v r s ~])
|
||||
--
|
||||
::
|
||||
++ sign-transaction-1559
|
||||
=, crypto
|
||||
|= [tx=transaction-1559:rpc pk=@]
|
||||
|^ ^- @ux
|
||||
=; hash=@
|
||||
=+ (ecdsa-raw-sign:secp256k1:secp hash pk)
|
||||
::NOTE we retrieve y's parity from the v value
|
||||
(encode-1559 ~ (end 0 v) r s)
|
||||
:: hash the raw transaction data including leading 0x2
|
||||
%- keccak-256:keccak
|
||||
=+ dat=(cat 3 (encode-1559 ~) 0x2)
|
||||
=+ wid=(met 3 dat)
|
||||
[wid (rev 3 wid dat)]
|
||||
::
|
||||
++ encode-1559
|
||||
|= sig=(unit [y=@ r=@ s=@])
|
||||
%+ encode:rlp %l
|
||||
=, tx
|
||||
:* chain-id
|
||||
nonce
|
||||
max-priority-gas-fee
|
||||
max-gas-fee
|
||||
gas
|
||||
b+20^to
|
||||
value
|
||||
data
|
||||
::
|
||||
:- %l
|
||||
%+ turn ~(tap by access-list)
|
||||
|= [a=address b=(list @ux)]
|
||||
l+~[b+20^a l+(turn b |=(c=@ux b+32^c))]
|
||||
::
|
||||
?~ sig ~
|
||||
~[y r s]:u.sig
|
||||
==
|
||||
--
|
||||
--
|
||||
::
|
||||
:: rlp en/decoding
|
||||
::NOTE https://github.com/ethereum/wiki/wiki/RLP
|
||||
::NOTE https://eth.wiki/en/fundamentals/rlp
|
||||
::
|
||||
++ rlp
|
||||
|%
|
||||
@ -53,35 +101,42 @@
|
||||
:: and one-byte zero (and also empty list) we end up with
|
||||
:: this awful type...
|
||||
+$ item
|
||||
$@ @
|
||||
$% [%l l=(list item)]
|
||||
[%b b=byts]
|
||||
==
|
||||
:: +encode-atoms: encode list of atoms as a %l of %b items
|
||||
::
|
||||
++ encode-atoms
|
||||
++ encode-atoms ::NOTE deprecated
|
||||
|= l=(list @)
|
||||
^- @
|
||||
%+ encode %l
|
||||
%+ turn l
|
||||
|=(a=@ b+[(met 3 a) a])
|
||||
(encode l+l)
|
||||
::
|
||||
++ encode
|
||||
|= in=item
|
||||
|^ ^- @
|
||||
?- -.in
|
||||
%b
|
||||
?- in
|
||||
@
|
||||
$(in [%b (met 3 in) in])
|
||||
::
|
||||
[%b *]
|
||||
?: &(=(1 wid.b.in) (lte dat.b.in 0x7f))
|
||||
dat.b.in
|
||||
=- (can 3 ~[b.in [(met 3 -) -]])
|
||||
(encode-length wid.b.in 0x80)
|
||||
::
|
||||
%l
|
||||
=/ out=@
|
||||
%+ roll l.in
|
||||
|= [ni=item en=@]
|
||||
(cat 3 (encode ni) en)
|
||||
%^ cat 3 out
|
||||
(encode-length (met 3 out) 0xc0)
|
||||
[%l *]
|
||||
:: we +can because b+1^0x0 encodes to 0x00
|
||||
::
|
||||
=/ l=(list byts)
|
||||
%+ turn l.in
|
||||
|= ni=item
|
||||
=+ (encode ni)
|
||||
[(max 1 (met 3 -)) -]
|
||||
%+ can 3
|
||||
%- flop
|
||||
=- [(met 3 -)^- l]
|
||||
(encode-length (roll (turn l head) add) 0xc0)
|
||||
==
|
||||
::
|
||||
++ encode-length
|
||||
@ -445,6 +500,11 @@
|
||||
==
|
||||
::
|
||||
:: raw transaction data
|
||||
+$ typed-transaction
|
||||
$% [%0x0 transaction]
|
||||
[%0x2 transaction-1559]
|
||||
==
|
||||
::
|
||||
+$ transaction
|
||||
$: nonce=@ud
|
||||
gas-price=@ud
|
||||
@ -455,6 +515,18 @@
|
||||
chain-id=@ux
|
||||
==
|
||||
::
|
||||
+$ transaction-1559
|
||||
$: chain-id=@ux
|
||||
nonce=@ud
|
||||
max-priority-gas-fee=@ud
|
||||
max-gas-fee=@ud
|
||||
gas=@ud
|
||||
to=address
|
||||
value=@ud
|
||||
data=@ux
|
||||
access-list=(jar address @ux)
|
||||
==
|
||||
::
|
||||
:: ethereum json rpc api
|
||||
::
|
||||
:: supported requests.
|
||||
@ -635,7 +707,7 @@
|
||||
?~ tob.req ~
|
||||
`['toBlock' (block-to-json u.tob.req)]
|
||||
::
|
||||
::TODO fucking tmi
|
||||
::NOTE tmi
|
||||
?: =(0 (lent adr.req)) ~
|
||||
:+ ~ 'address'
|
||||
?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req)))
|
||||
|
@ -156,7 +156,7 @@
|
||||
::
|
||||
:- ~
|
||||
:+ %agent wire.in
|
||||
[%fact (validate-mark q.cage.sign.in p.cage.sign.in bowl.strand-input)]
|
||||
[%fact (validate-mark q.q.cage.sign.in p.cage.sign.in bowl.strand-input)]
|
||||
:: run the strand callback
|
||||
::
|
||||
=/ =output (form.eval-form strand-input)
|
||||
|
@ -176,8 +176,6 @@
|
||||
++ read-bill
|
||||
|= [our=ship =desk now=@da]
|
||||
=/ pax (en-beam [our desk da+now] /desk/bill)
|
||||
?. (~(has in .^((set ^desk) cd/~[(scot %p our) ~ (scot %da now)])) desk)
|
||||
*(list dude)
|
||||
?. .^(? cu/pax)
|
||||
*(list dude)
|
||||
.^((list dude) cx/pax)
|
||||
@ -227,6 +225,7 @@
|
||||
++ get-apps-want
|
||||
|= [duz=(list dude) =rein]
|
||||
^- (list dude)
|
||||
?. liv.rein ~
|
||||
=. duz (skip duz ~(has in sub.rein))
|
||||
=. duz (weld duz (skip ~(tap in add.rein) ~(has in (sy duz))))
|
||||
duz
|
||||
|
@ -4,7 +4,7 @@
|
||||
:: x/scanned: (list xpub) of all scanned wallets
|
||||
:: x/balance/xpub: balance (in sats) of wallet
|
||||
/- *btc-wallet, bp=btc-provider, settings
|
||||
/+ dbug, default-agent, bl=btc, bc=bitcoin, bcu=bitcoin-utils, bip32
|
||||
/+ dbug, default-agent, bl=btc, bc=bitcoin, bcu=bitcoin-utils, bip32, agentio
|
||||
~% %btc-wallet-top ..part ~
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
@ -24,6 +24,7 @@
|
||||
$% state-0
|
||||
state-1
|
||||
state-2
|
||||
state-3
|
||||
==
|
||||
::
|
||||
+$ state-0
|
||||
@ -57,8 +58,9 @@
|
||||
::
|
||||
+$ state-1 [%1 base-state]
|
||||
+$ state-2 [%2 base-state]
|
||||
+$ state-3 [%3 base-state]
|
||||
--
|
||||
=| state-2
|
||||
=| state-3
|
||||
=* state -
|
||||
%- agent:dbug
|
||||
^- agent:gall
|
||||
@ -68,6 +70,8 @@
|
||||
+* this .
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
hc ~(. +> bowl)
|
||||
io ~(. agentio bowl)
|
||||
pass pass:io
|
||||
::
|
||||
++ on-init
|
||||
^- (quip card _this)
|
||||
@ -83,7 +87,7 @@
|
||||
:- cards
|
||||
%_ this
|
||||
state
|
||||
:* %2
|
||||
:* %3
|
||||
~
|
||||
*(map xpub:bc walt)
|
||||
*^btc-state
|
||||
@ -110,8 +114,14 @@
|
||||
=| cards=(list card)
|
||||
|-
|
||||
?- -.ver
|
||||
%3
|
||||
[(flop cards) this(state ver)]
|
||||
::
|
||||
%2
|
||||
[cards this(state ver)]
|
||||
%_ $
|
||||
-.ver %3
|
||||
cards :_(cards (~(wait pass /migrate-settings) (add now.bowl ~s1)))
|
||||
==
|
||||
::
|
||||
%1
|
||||
=? cards ?=(^ prov.ver)
|
||||
@ -138,6 +148,11 @@
|
||||
|^
|
||||
=^ cards state
|
||||
?+ mark (on-poke:def mark vase)
|
||||
::
|
||||
%noun
|
||||
?> =(our.bowl src.bowl)
|
||||
(handle-noun q.vase)
|
||||
::
|
||||
%btc-wallet-command
|
||||
?> =(our.bowl src.bowl)
|
||||
(handle-command !<(command vase))
|
||||
@ -152,6 +167,35 @@
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
++ handle-noun
|
||||
|= non=*
|
||||
?> ?=(%migrate-settings non)
|
||||
:_ state
|
||||
^- (list card)
|
||||
=/ bas=path /(scot %p our.bowl)/settings-store/(scot %da now.bowl)
|
||||
?. .^(? %gu bas)
|
||||
~& [dap.bowl %settings-store-mia]
|
||||
~
|
||||
?. .^(? %gx (weld bas /has-bucket/landscape/btc-wallet/noun))
|
||||
~
|
||||
=/ dat
|
||||
.^(data:settings %gx (weld bas /bucket/landscape/btc-wallet/noun))
|
||||
?> ?=(%bucket -.dat)
|
||||
|^ :- =/ del=event:settings [%del-bucket %landscape %btc-wallet]
|
||||
(poke-our:hc %settings-store %settings-event !>(del))
|
||||
(murn ~(tap by bucket.dat) copy-if-missing)
|
||||
::
|
||||
++ copy-if-missing
|
||||
|= [=key:settings =val:settings]
|
||||
^- (unit card)
|
||||
=/ hav=?
|
||||
.^(? %gx (weld bas /has-entry/[q.byk.bowl]/btc-wallet/[key]/noun))
|
||||
?: hav ~
|
||||
~& [dap.bowl %importing-previous-setting key]
|
||||
=/ put=event:settings [%put-entry q.byk.bowl %btc-wallet key val]
|
||||
`(poke-our:hc %settings-store %settings-event !>(put))
|
||||
--
|
||||
::
|
||||
++ handle-command
|
||||
|= comm=command
|
||||
^- (quip card _state)
|
||||
@ -853,8 +897,8 @@
|
||||
|= upd=update:bp
|
||||
^- (quip card _state)
|
||||
|^
|
||||
?~ prov `state
|
||||
?. =(host.u.prov src.bowl) `state
|
||||
?: =(~ prov) `state
|
||||
?. =(host:(need prov) src.bowl) `state
|
||||
?. ?=(%.y -.upd) `state
|
||||
?- -.p.upd
|
||||
%address-info
|
||||
@ -864,9 +908,9 @@
|
||||
::
|
||||
%tx-info
|
||||
:: TODO: why do we get a nest-fail when using =^ ?
|
||||
=/ [cards=(list card) sty=state-2]
|
||||
=^ cards=(list card) state
|
||||
(handle-tx-info:hc info.p.upd)
|
||||
:_ sty
|
||||
:_ state
|
||||
:_ cards
|
||||
(poke-internal:hc [%close-pym info.p.upd])
|
||||
::
|
||||
@ -1056,7 +1100,12 @@
|
||||
==
|
||||
::
|
||||
++ on-leave on-leave:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-arvo
|
||||
|= [=wire sign=sign-arvo]
|
||||
^- (quip card _this)
|
||||
?. ?=([%migrate-settings ~] wire) (on-arvo:def wire sign)
|
||||
?> ?=([%behn *] sign)
|
||||
(on-poke %noun !>(%migrate-settings))
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
~% %btc-wallet-helper ..card ~
|
||||
|
@ -2,7 +2,7 @@
|
||||
title+'Bitcoin'
|
||||
info+'A Bitcoin Wallet that lets you send and receive Bitcoin directly to and from other Urbit users'
|
||||
color+0xf9.8e40
|
||||
glob-http+['https://bootstrap.urbit.org/glob-0v1.k33ke.d6avi.v264q.38q80.dct6j.glob' 0v1.k33ke.d6avi.v264q.38q80.dct6j]
|
||||
glob-http+['https://bootstrap.urbit.org/glob-0v3.7b5q1.gn30e.cpfem.abmqg.qh77v.glob' 0v3.7b5q1.gn30e.cpfem.abmqg.qh77v]
|
||||
image+'https://urbit.ewr1.vultrobjects.com/hastuc-dibtux/2021.8.24..02.57.38-bitcoin.svg'
|
||||
base+'bitcoin'
|
||||
version+[0 0 1]
|
||||
|
@ -1 +1 @@
|
||||
[%zuse 420]
|
||||
[%zuse 419]
|
||||
|
@ -6,6 +6,7 @@ import { Box, Reset } from '@tlon/indigo-react';
|
||||
import StartupModal from './components/StartupModal';
|
||||
import { useSettings } from './hooks/useSettings';
|
||||
import Body from './components/Body';
|
||||
import Header from './components/Header';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const { loaded, wallet, provider, scanProgress } = useSettings();
|
||||
@ -27,9 +28,8 @@ const App: React.FC = () => {
|
||||
minHeight={loaded && !scanning ? '100%' : 'none'}
|
||||
height={loaded && !scanning ? 'none' : '100%'}
|
||||
style={{ filter: blur ? 'blur(8px)' : 'none' }}
|
||||
px={[0, 4]}
|
||||
pb={[0, 4]}
|
||||
>
|
||||
<Header />
|
||||
<Body />
|
||||
</Box>
|
||||
</ThemeProvider>
|
||||
|
@ -4,7 +4,6 @@ import { Switch, Route } from 'react-router-dom';
|
||||
import Balance from './Balance';
|
||||
import Transactions from './Transactions/Transactions';
|
||||
import Warning from './Warning';
|
||||
import Header from './Header';
|
||||
import Settings from './Settings';
|
||||
import { useSettings } from '../hooks/useSettings';
|
||||
|
||||
@ -25,13 +24,11 @@ const Body: React.FC = () => {
|
||||
<Switch>
|
||||
<Route path="/settings">
|
||||
<Col display="flex" flexDirection="column" width={cardWidth}>
|
||||
<Header settings={true} />
|
||||
<Settings />
|
||||
</Col>
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Col display="flex" flexDirection="column" width={cardWidth}>
|
||||
<Header settings={false} />
|
||||
{!warning ? null : <Warning />}
|
||||
<Balance />
|
||||
<Transactions />
|
||||
|
@ -3,44 +3,29 @@ import { Box, Icon, Row, Text } from '@tlon/indigo-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useSettings } from '../hooks/useSettings';
|
||||
|
||||
const Header = ({ settings }: { settings: boolean }) => {
|
||||
const Header = () => {
|
||||
const { provider } = useSettings();
|
||||
let icon = settings ? 'X' : 'Adjust';
|
||||
let iconColor = settings ? 'black' : 'orange';
|
||||
let iconLink = settings ? '/' : '/settings';
|
||||
|
||||
let connection = null;
|
||||
let badge = null;
|
||||
if (!(provider && provider.connected)) {
|
||||
connection = (
|
||||
<Text fontSize={1} color="red" fontWeight="bold" mr={3}>
|
||||
Provider Offline
|
||||
</Text>
|
||||
);
|
||||
|
||||
if (!settings) {
|
||||
badge = (
|
||||
<Box
|
||||
borderRadius="50%"
|
||||
width="8px"
|
||||
height="8px"
|
||||
backgroundColor="red"
|
||||
position="absolute"
|
||||
top="0px"
|
||||
right="0px"
|
||||
></Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Row
|
||||
height={8}
|
||||
height={7}
|
||||
width="100%"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
pt={5}
|
||||
pb={5}
|
||||
mb={5}
|
||||
px={[2, 4]}
|
||||
style={{
|
||||
boxShadow: '0px 1px 0px rgba(0, 0, 0, 0.1)',
|
||||
}}
|
||||
>
|
||||
<Row alignItems="center" justifyContent="center">
|
||||
<Box
|
||||
@ -60,19 +45,32 @@ const Header = ({ settings }: { settings: boolean }) => {
|
||||
</Row>
|
||||
<Row alignItems="center">
|
||||
{connection}
|
||||
<Link to={iconLink}>
|
||||
<Link to="/settings">
|
||||
<Box
|
||||
backgroundColor="white"
|
||||
borderRadius={4}
|
||||
width={5}
|
||||
height={5}
|
||||
p={2}
|
||||
m={2}
|
||||
position="relative"
|
||||
>
|
||||
{badge}
|
||||
<Icon icon={icon} color={iconColor} />
|
||||
<Icon icon="Adjust" color="orange" />
|
||||
</Box>
|
||||
</Link>
|
||||
<a href="/">
|
||||
<Box
|
||||
backgroundColor="white"
|
||||
borderRadius={4}
|
||||
width={5}
|
||||
height={5}
|
||||
p={2}
|
||||
m={2}
|
||||
position="relative"
|
||||
>
|
||||
<Icon icon="Home" color="orange" />
|
||||
</Box>
|
||||
</a>
|
||||
</Row>
|
||||
</Row>
|
||||
);
|
||||
|
@ -99,9 +99,9 @@ const ProviderModal = () => {
|
||||
</Row>
|
||||
<Box mt={3}>
|
||||
<Text fontSize="14px" fontWeight="regular" color="gray">
|
||||
In order to perform Bitcoin transaction in Landscape, you'll need
|
||||
to set a provider node. A provider node is an urbit which maintains a
|
||||
synced Bitcoin ledger.
|
||||
In order to use the Bitcoin wallet on your ship you'll need to
|
||||
set a provider node. A provider node is an urbit ship which maintains
|
||||
a synced Bitcoin ledger.
|
||||
<a
|
||||
style={{ fontSize: '14px' }}
|
||||
target="_blank"
|
||||
|
@ -25,10 +25,18 @@ type Props = {
|
||||
};
|
||||
|
||||
const BridgeInvoice: React.FC<Props> = ({ payee, stopSending, satsAmount }) => {
|
||||
const { error, currencyRates, fee, broadcastSuccess, denomination, psbt } =
|
||||
useSettings();
|
||||
const {
|
||||
error,
|
||||
currencyRates,
|
||||
fee,
|
||||
broadcastSuccess,
|
||||
denomination,
|
||||
psbt,
|
||||
history,
|
||||
} = useSettings();
|
||||
const [txHex, setTxHex] = useState('');
|
||||
const [ready, setReady] = useState(false);
|
||||
const [historyLength, setHistoryLength] = useState(0);
|
||||
const [localError, setLocalError] = useState('');
|
||||
const [broadcasting, setBroadcasting] = useState(false);
|
||||
const invoiceRef = useRef();
|
||||
@ -44,7 +52,17 @@ const BridgeInvoice: React.FC<Props> = ({ payee, stopSending, satsAmount }) => {
|
||||
|
||||
useEffect(() => {
|
||||
window.open('https://bridge.urbit.org/?kind=btc&utx=' + psbt);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (historyLength === 0) {
|
||||
setHistoryLength(history.length);
|
||||
}
|
||||
if (broadcasting && history.length > historyLength) {
|
||||
setBroadcasting(false);
|
||||
stopSending();
|
||||
}
|
||||
}, [history]);
|
||||
|
||||
const broadCastTx = (hex: string) => {
|
||||
let command = {
|
||||
@ -65,9 +83,14 @@ const BridgeInvoice: React.FC<Props> = ({ payee, stopSending, satsAmount }) => {
|
||||
};
|
||||
|
||||
const checkTxHex = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setTxHex(e.target.value);
|
||||
setReady(txHex.length > 0);
|
||||
setLocalError('');
|
||||
// TODO: validate this hex with something other than length check.
|
||||
if (e.target.value.length > 0) {
|
||||
setTxHex(e.target.value);
|
||||
setReady(true);
|
||||
setLocalError('');
|
||||
} else {
|
||||
setLocalError('Invalid transaction hex');
|
||||
}
|
||||
};
|
||||
|
||||
let inputColor = 'black';
|
||||
|
@ -29,10 +29,18 @@ const ExternalInvoice: React.FC<Props> = ({
|
||||
stopSending,
|
||||
satsAmount,
|
||||
}) => {
|
||||
const { error, currencyRates, fee, broadcastSuccess, denomination, psbt } =
|
||||
useSettings();
|
||||
const {
|
||||
error,
|
||||
currencyRates,
|
||||
fee,
|
||||
broadcastSuccess,
|
||||
denomination,
|
||||
psbt,
|
||||
history,
|
||||
} = useSettings();
|
||||
const [txHex, setTxHex] = useState('');
|
||||
const [ready, setReady] = useState(false);
|
||||
const [historyLength, setHistoryLength] = useState(0);
|
||||
const [localError, setLocalError] = useState('');
|
||||
const [broadcasting, setBroadcasting] = useState(false);
|
||||
const invoiceRef = useRef();
|
||||
@ -46,6 +54,16 @@ const ExternalInvoice: React.FC<Props> = ({
|
||||
}
|
||||
}, [error, broadcasting, setBroadcasting]);
|
||||
|
||||
useEffect(() => {
|
||||
if (historyLength === 0) {
|
||||
setHistoryLength(history.length);
|
||||
}
|
||||
if (broadcasting && history.length > historyLength) {
|
||||
setBroadcasting(false);
|
||||
stopSending();
|
||||
}
|
||||
}, [history]);
|
||||
|
||||
const broadCastTx = (hex: string) => {
|
||||
let command = {
|
||||
'broadcast-tx': hex,
|
||||
@ -65,9 +83,14 @@ const ExternalInvoice: React.FC<Props> = ({
|
||||
};
|
||||
|
||||
const checkTxHex = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setTxHex(e.target.value);
|
||||
setReady(txHex.length > 0);
|
||||
setLocalError('');
|
||||
// TODO: validate this hex with something other than length check.
|
||||
if (e.target.value.length > 0) {
|
||||
setTxHex(e.target.value);
|
||||
setReady(true);
|
||||
setLocalError('');
|
||||
} else {
|
||||
setLocalError('Invalid transaction hex');
|
||||
}
|
||||
};
|
||||
|
||||
const copyPsbt = () => {
|
||||
|
@ -59,9 +59,11 @@ const Invoice: React.FC<Props> = ({ stopSending, payee, satsAmount }) => {
|
||||
broadcastSuccess,
|
||||
network,
|
||||
denomination,
|
||||
history,
|
||||
} = useSettings();
|
||||
const [masterTicket, setMasterTicket] = useState('');
|
||||
const [ready, setReady] = useState(false);
|
||||
const [historyLength, setHistoryLength] = useState(0);
|
||||
const [localError, setLocalError] = useState(error);
|
||||
const [broadcasting, setBroadcasting] = useState(false);
|
||||
|
||||
@ -78,6 +80,16 @@ const Invoice: React.FC<Props> = ({ stopSending, payee, satsAmount }) => {
|
||||
return api.btcWalletCommand(command);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (historyLength === 0) {
|
||||
setHistoryLength(history.length);
|
||||
}
|
||||
if (broadcasting && history.length > historyLength) {
|
||||
setBroadcasting(false);
|
||||
stopSending();
|
||||
}
|
||||
}, [history]);
|
||||
|
||||
const sendBitcoin = (ticket: string, psbt: string) => {
|
||||
const newPsbt = bitcoin.Psbt.fromBase64(psbt);
|
||||
setBroadcasting(true);
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { Row, Text, Button, Col } from '@tlon/indigo-react';
|
||||
import { Box, Icon, Row, Text, Button, Col } from '@tlon/indigo-react';
|
||||
import { useSettings } from '../hooks/useSettings';
|
||||
import { api } from '../lib/api';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const Settings = () => {
|
||||
const { wallet, provider } = useSettings();
|
||||
@ -39,10 +40,15 @@ const Settings = () => {
|
||||
borderRadius="48px"
|
||||
backgroundColor="white"
|
||||
>
|
||||
<Row mb="12px">
|
||||
<Row mb="12px" alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize={1} fontWeight="bold" color="black">
|
||||
XPub Derivation
|
||||
</Text>
|
||||
<Link to="/~btc">
|
||||
<Box backgroundColor="white" width={5} height={5} p={2} m={2}>
|
||||
<Icon icon="X" />
|
||||
</Box>
|
||||
</Link>
|
||||
</Row>
|
||||
<Row
|
||||
borderRadius="12px"
|
||||
|
@ -232,8 +232,8 @@
|
||||
:: if the new chad is a site, we're instantly done
|
||||
::
|
||||
?: ?=(%site -.href.docket)
|
||||
:- ~[add-fact:cha]
|
||||
=. charges (new-chad:cha %site ~)
|
||||
:- ~[add-fact:cha]
|
||||
state
|
||||
::
|
||||
=. by-base (~(put by by-base) base.href.docket desk)
|
||||
@ -478,6 +478,8 @@
|
||||
"""
|
||||
;li:"glob!"
|
||||
==
|
||||
(safari and internet explorer do not support uploading directory
|
||||
trees properly. please glob from other browsers.)
|
||||
;+ ?: =(~ desks)
|
||||
;p:"no desks eligible for glob upload"
|
||||
;form(method "post", enctype "multipart/form-data")
|
||||
@ -510,6 +512,12 @@
|
||||
[[404^~ ~] [~ state]]
|
||||
::
|
||||
=; [desk=@ta =glob err=(list @t)]
|
||||
=* error-result
|
||||
:_ [~ state]
|
||||
[[400 ~] `(upload-page err)]
|
||||
::
|
||||
?. =(~ err) error-result
|
||||
::
|
||||
=* cha ~(. ch desk)
|
||||
=/ =charge (~(got by charges) desk)
|
||||
::
|
||||
@ -518,9 +526,7 @@
|
||||
=? err !?=(%glob -.href.docket.charge)
|
||||
['desk does not use glob' err]
|
||||
::
|
||||
?. =(~ err)
|
||||
:_ [~ state]
|
||||
[[400 ~] `(upload-page err)]
|
||||
?. =(~ err) error-result
|
||||
:- [[200 ~] `(upload-page 'successfully globbed' ~)]
|
||||
?> ?=(%glob -.href.docket.charge)
|
||||
::
|
||||
|
@ -25,6 +25,7 @@
|
||||
state-6
|
||||
state-7
|
||||
state-8
|
||||
state-9
|
||||
==
|
||||
::
|
||||
+$ base-state
|
||||
@ -56,13 +57,16 @@
|
||||
+$ state-8
|
||||
[%8 base-state]
|
||||
::
|
||||
+$ state-9
|
||||
[%9 base-state]
|
||||
::
|
||||
::
|
||||
+$ cached-state
|
||||
$: by-place=(jug place:store [=lid:store =path])
|
||||
~
|
||||
==
|
||||
+$ inflated-state
|
||||
[state-8 cached-state]
|
||||
[state-9 cached-state]
|
||||
::
|
||||
++ orm ((ordered-map @da timebox:store) gth)
|
||||
--
|
||||
@ -91,31 +95,20 @@
|
||||
=/ old
|
||||
!<(versioned-state old-vase)
|
||||
=| cards=(list card)
|
||||
|^ ^- (quip card _this)
|
||||
?: ?=(%8 -.old)
|
||||
|- ^- (quip card _this)
|
||||
?+ -.old
|
||||
:: pre-dist migration
|
||||
:_ this
|
||||
(poke-our:pass %hark-graph-hook hark-graph-migrate+old-vase)^~
|
||||
::
|
||||
%9
|
||||
=. -.state old
|
||||
=. +.state inflate
|
||||
=. +.state inflate:ha
|
||||
:_(this (flop cards))
|
||||
::
|
||||
:_ this
|
||||
(poke-our:pass %hark-graph-hook hark-graph-migrate+old-vase)^~
|
||||
::
|
||||
++ index-timebox
|
||||
|= [=lid:store =timebox:store out=_by-place]
|
||||
^+ by-place
|
||||
%+ roll ~(tap by timebox)
|
||||
|= [[=bin:store =notification:store] out=_out]
|
||||
(~(put ju out) place.bin [lid path.bin])
|
||||
::
|
||||
++ inflate
|
||||
=. by-place (index-timebox seen+~ seen by-place)
|
||||
=. by-place (index-timebox unseen+~ unseen by-place)
|
||||
=. by-place
|
||||
%+ roll (tap:orm archive)
|
||||
|= [[=time =timebox:store] out=_by-place]
|
||||
(index-timebox archive/time timebox out)
|
||||
+.state
|
||||
--
|
||||
%8
|
||||
$(-.old %9, archive.old *archive:store)
|
||||
==
|
||||
::
|
||||
++ on-watch
|
||||
|= =path
|
||||
@ -178,6 +171,10 @@
|
||||
?+ val ~|(%bad-noun-poke !!)
|
||||
%print ~&(+.state [~ state])
|
||||
%clear [~ state(. *inflated-state)]
|
||||
%sane
|
||||
~& +.state
|
||||
~& inflate
|
||||
?>(=(+.state inflate) `state)
|
||||
==
|
||||
::
|
||||
++ poke-us
|
||||
@ -281,14 +278,12 @@
|
||||
^+ poke-core
|
||||
=. poke-core
|
||||
(emit (fact:io hark-update+!>([%add-note bin body]) /notes ~))
|
||||
=. by-place
|
||||
(~(put ju by-place) place.bin unseen+~ path.bin)
|
||||
=/ existing-notif
|
||||
(~(gut by unseen) bin *notification:store)
|
||||
=/ new=notification:store
|
||||
[now.bowl bin [body body.existing-notif]]
|
||||
=. unseen
|
||||
(~(put by unseen) bin new)
|
||||
=. poke-core
|
||||
(put-lid unseen/~ bin new)
|
||||
(give %added new)
|
||||
::
|
||||
++ del-place
|
||||
@ -312,25 +307,19 @@
|
||||
=/ =notification:store (need (get-lid lid bin))
|
||||
=. poke-core (del-lid lid bin)
|
||||
=. poke-core (put-lid archive+now.bowl bin notification)
|
||||
=? poke-core ?=(%unseen -.lid)
|
||||
?~ n=(get-lid seen+~ bin) poke-core
|
||||
=. archive
|
||||
%^ ~(job re archive) now.bowl bin
|
||||
|= og=(unit notification:store)
|
||||
(merge-notification og u.n)
|
||||
poke-core
|
||||
(give %archived now.bowl lid notification)
|
||||
::
|
||||
++ read-note
|
||||
|= =bin:store
|
||||
=/ =notification:store
|
||||
(~(got by unseen) bin)
|
||||
=. unseen
|
||||
(~(del by unseen) bin)
|
||||
=. poke-core
|
||||
(del-lid unseen/~ bin)
|
||||
=/ =time
|
||||
(fall timebox:(gut-place place.bin) now.bowl)
|
||||
=. date.notification time
|
||||
=. archive (~(put re archive) time bin notification)
|
||||
=. poke-core
|
||||
(put-lid archive/time bin notification)
|
||||
(give %note-read time bin)
|
||||
::
|
||||
::
|
||||
@ -412,12 +401,14 @@
|
||||
=/ =time (~(gut by half-open) bin now.bowl)
|
||||
=? half-open !(~(has by half-open) bin)
|
||||
(~(put by half-open) bin now.bowl)
|
||||
=. archive
|
||||
%^ ~(job re archive) time bin
|
||||
|=(n=(unit notification:store) (merge-notification n note))
|
||||
=. by-place (~(put ju by-place) place [archive/now.bowl path.bin])
|
||||
=. poke-core (give %archived now.bowl unseen+~ (~(got re archive) time bin))
|
||||
=. poke-core (give %archived now.bowl seen+~ (~(got re archive) time bin))
|
||||
=/ existing (get-lid archive/time bin)
|
||||
=/ new (merge-notification existing note)
|
||||
=? half-open (lth 30 (lent body.new))
|
||||
(~(del by half-open) bin)
|
||||
=. poke-core
|
||||
(put-lid archive/time bin new)
|
||||
=. poke-core (del-lid lid bin)
|
||||
=. poke-core (give %archived time lid (~(got re archive) time bin))
|
||||
$(bins t.bins)
|
||||
::
|
||||
++ read-count
|
||||
@ -447,18 +438,22 @@
|
||||
poke-core
|
||||
::
|
||||
++ opened
|
||||
=. seen
|
||||
%- ~(gas by *timebox:store)
|
||||
%+ murn ~(tap in (~(uni in ~(key by seen)) ~(key by unseen)))
|
||||
|= =bin:store
|
||||
=/ se (~(get by seen) bin)
|
||||
=/ un (~(get by unseen) bin)
|
||||
?~ un
|
||||
?~(se ~ `[bin u.se])
|
||||
`[bin (merge-notification se u.un)]
|
||||
=. unseen ~
|
||||
=. poke-core (turn-places |=(=stats:store stats(timebox ~)))
|
||||
(give %opened ~)
|
||||
=. poke-core (give %opened ~)
|
||||
%+ roll ~(tap in ~(key by unseen))
|
||||
|= [=bin:store out=_poke-core]
|
||||
(opened-note:out bin)
|
||||
::
|
||||
++ opened-note
|
||||
|= =bin:store
|
||||
^+ poke-core
|
||||
=/ old
|
||||
(~(got by unseen) bin)
|
||||
=. poke-core
|
||||
(del-lid unseen/~ bin)
|
||||
=/ se (~(get by seen) bin)
|
||||
%^ put-lid seen/~ bin
|
||||
(merge-notification se old)
|
||||
|
||||
::
|
||||
++ archive-all
|
||||
@ -483,8 +478,13 @@
|
||||
::
|
||||
++ get-lid
|
||||
|= [=lid:store =bin:store]
|
||||
=/ =timebox:store ?:(?=(%unseen -.lid) unseen seen)
|
||||
(~(get by timebox) bin)
|
||||
=; =timebox:store
|
||||
(~(get by timebox) bin)
|
||||
?- -.lid
|
||||
%unseen unseen
|
||||
%seen seen
|
||||
%archive (fall (get:orm archive time.lid) *timebox:store)
|
||||
==
|
||||
::
|
||||
++ merge-notification
|
||||
|= [existing=(unit notification:store) new=notification:store]
|
||||
@ -522,4 +522,21 @@
|
||||
^- (list [@da timebox:store])
|
||||
%+ skim (tap:orm archive)
|
||||
|=([@da =timebox:store] !=(~(wyt by timebox) 0))
|
||||
::
|
||||
++ inflate
|
||||
=. by-place ~
|
||||
=. by-place (index-timebox seen+~ seen by-place)
|
||||
=. by-place (index-timebox unseen+~ unseen by-place)
|
||||
=. by-place
|
||||
%+ roll (tap:orm archive)
|
||||
|= [[=time =timebox:store] out=_by-place]
|
||||
(index-timebox archive/time timebox out)
|
||||
+.state
|
||||
::
|
||||
++ index-timebox
|
||||
|= [=lid:store =timebox:store out=_by-place]
|
||||
^+ by-place
|
||||
%+ roll ~(tap by timebox)
|
||||
|= [[=bin:store =notification:store] out=_out]
|
||||
(~(put ju out) place.bin [lid path.bin])
|
||||
--
|
||||
|
@ -44,7 +44,7 @@
|
||||
%kick :_(this (drop safe-watch:kiln:cc))
|
||||
::
|
||||
%fact
|
||||
?. ?=(%kiln-vats-diff p.cage.sign) `this
|
||||
?. ?=(%kiln-vats-diff-0 p.cage.sign) `this
|
||||
=+ !<(=diff:hood q.cage.sign)
|
||||
?+ -.diff `this
|
||||
::
|
||||
|
@ -24,11 +24,7 @@
|
||||
def ~(. (default-agent this %|) bol)
|
||||
io ~(. agentio bol)
|
||||
::
|
||||
++ on-init
|
||||
^- (quip card _this)
|
||||
=^ cards state
|
||||
(put-entry:do q.byk.bol %tutorial %seen b+|)
|
||||
[cards this]
|
||||
++ on-init on-init:def
|
||||
::
|
||||
++ on-save !>(state)
|
||||
::
|
||||
|
@ -24,7 +24,7 @@
|
||||
io ~(. agentio bowl)
|
||||
pass pass:io
|
||||
cc ~(. +> bowl)
|
||||
++ on-init
|
||||
++ on-init
|
||||
?: =(our.bowl default-ally) `this
|
||||
(on-poke %ally-update-0 !>([%add default-ally]))
|
||||
++ on-save !>(state)
|
||||
@ -37,12 +37,12 @@
|
||||
|= [=mark =vase]
|
||||
^- (quip card _this)
|
||||
?> (team:title [our src]:bowl)
|
||||
|^
|
||||
|^
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%ally-update-0 (ally-update !<(update:ally vase))
|
||||
%alliance-update-0 (alliance-update !<(update:alliance vase))
|
||||
%alliance-update-0 (alliance-update !<(update:alliance vase))
|
||||
::
|
||||
%noun
|
||||
%noun
|
||||
=+ ;;([%add =desk] q.vase)
|
||||
=/ =docket:docket ~(get-docket so:cc desk)
|
||||
=/ =treaty (treaty-from-docket:cc desk docket)
|
||||
@ -69,7 +69,7 @@
|
||||
=- [[(alliance-update:ca:cc update) -.-] +.-]
|
||||
?+ -.update !!
|
||||
::
|
||||
%add
|
||||
%add
|
||||
=, update
|
||||
=. entente (~(put in entente) [ship desk])
|
||||
?. =(our.bowl ship) `this
|
||||
@ -78,7 +78,7 @@
|
||||
=/ =treaty (treaty-from-docket:cc desk docket)
|
||||
=. sovereign (~(put by sovereign) desk treaty)
|
||||
:_ this
|
||||
~[publish warp give]:so
|
||||
[publish warp give]:so
|
||||
::
|
||||
%del
|
||||
=, update
|
||||
@ -93,8 +93,8 @@
|
||||
|= =path
|
||||
^- (quip card _this)
|
||||
?+ path (on-watch:def path)
|
||||
:: syncing
|
||||
[%treaty @ @ ~]
|
||||
:: syncing
|
||||
[%treaty @ @ ~]
|
||||
=/ =ship (slav %p i.t.path)
|
||||
=* desk i.t.t.path
|
||||
?: =(our.bowl ship)
|
||||
@ -105,6 +105,12 @@
|
||||
?> =(our.bowl src.bowl)
|
||||
=. direct (~(put in direct) [ship desk])
|
||||
:_(this (drop ~(safe-watch tr:cc [ship desk])))
|
||||
::
|
||||
[%treaties ~]
|
||||
:_ this
|
||||
::NOTE this assumes that all treaties in sovereign are also
|
||||
:: present in the treaties map
|
||||
(fact-init:io (treaty-update:cg:cc %ini treaties))^~
|
||||
::
|
||||
[%alliance ~]
|
||||
:_ this
|
||||
@ -141,15 +147,15 @@
|
||||
``(treaty:cg:cc (~(got by treaties) [ship desk]))
|
||||
==
|
||||
::
|
||||
++ on-agent
|
||||
++ on-agent
|
||||
|= [=wire =sign:agent:gall]
|
||||
^- (quip card _this)
|
||||
=* ship src.bowl
|
||||
|^
|
||||
|^
|
||||
?+ wire (on-agent:def wire sign)
|
||||
[%ally @ ~] ?>(=(src.bowl (slav %p i.t.wire)) take-ally)
|
||||
::
|
||||
[%treaty @ @ ~]
|
||||
[%treaty @ @ ~]
|
||||
=* desk i.t.t.wire
|
||||
?> =(ship (slav %p i.t.wire))
|
||||
(take-treaty desk)
|
||||
@ -171,8 +177,8 @@
|
||||
%fact
|
||||
?. =(%alliance-update-0 p.cage.sign) `this
|
||||
=+ !<(=update:alliance q.cage.sign)
|
||||
=^ cards allies
|
||||
?- -.update
|
||||
=^ cards allies
|
||||
?- -.update
|
||||
::
|
||||
%ini
|
||||
:_ (~(put by allies) src.bowl init.update)
|
||||
@ -180,7 +186,7 @@
|
||||
|= [s=^ship =desk]
|
||||
~(safe-watch tr:cc s desk)
|
||||
::
|
||||
%add
|
||||
%add
|
||||
:_ (~(put ju allies) src.bowl [ship desk]:update)
|
||||
(drop ~(safe-watch tr:cc [ship desk]:update))
|
||||
|
||||
@ -195,31 +201,31 @@
|
||||
::
|
||||
++ take-treaty
|
||||
|= =desk
|
||||
=* tr ~(. tr:cc ship desk)
|
||||
?+ -.sign (on-agent:def wire sign)
|
||||
::
|
||||
:: rewatch only if we aren't source
|
||||
:: this would cause a potential kick-rewatch loop otherwise
|
||||
::
|
||||
%kick
|
||||
%kick
|
||||
:_ this
|
||||
?: =(our.bowl src.bowl) ~
|
||||
~(watch tr:cc ship desk)^~
|
||||
?: =(our.bowl ship) ~
|
||||
~[watch:tr]
|
||||
::
|
||||
%watch-ack
|
||||
?~ p.sign `this
|
||||
=: treaties (~(del by treaties) ship desk)
|
||||
direct (~(del in direct) ship desk)
|
||||
==
|
||||
%- (slog leaf+"Withdrew from treaty {<ship>}/{<desk>}" u.p.sign)
|
||||
:_ this
|
||||
(kick-only:io our.bowl /treaty/(scot %p ship)/[desk] ~)^~
|
||||
%- (slog leaf+"treaty: withdrew from {<ship>}/{<desk>}" u.p.sign)
|
||||
[gone:tr this]
|
||||
::
|
||||
%fact
|
||||
?. =(%treaty-0 p.cage.sign) `this
|
||||
=+ !<(=treaty q.cage.sign)
|
||||
?> =([ship desk] [ship desk]:treaty)
|
||||
=. treaties (~(put by treaties) [ship desk]:treaty treaty)
|
||||
[~(give tr ship desk)^~ this]
|
||||
[give:tr this]
|
||||
==
|
||||
--
|
||||
::
|
||||
@ -249,7 +255,7 @@
|
||||
=/ =treaty (treaty-from-docket:cc desk docket)
|
||||
=. sovereign (~(put by sovereign) desk treaty)
|
||||
=* so ~(. so:cc desk)
|
||||
:_(this [give warp ~]:so)
|
||||
:_(this [warp give]:so)
|
||||
--
|
||||
|
||||
::
|
||||
@ -269,7 +275,7 @@
|
||||
++ al
|
||||
|_ =ship
|
||||
++ pass ~(. ^pass /ally/(scot %p ship))
|
||||
++ watch (watch:pass [ship dap.bowl] /alliance)
|
||||
++ watch (watch:pass [ship dap.bowl] /alliance)
|
||||
++ leave (leave:pass ship dap.bowl)
|
||||
--
|
||||
:: +cg: Cage construction
|
||||
@ -285,7 +291,7 @@
|
||||
|%
|
||||
++ watch-docket (~(watch-our pass /docket) %docket /dockets)
|
||||
++ ally-update |=(=update:ally (fact:io (ally-update:cg update) /allies ~))
|
||||
++ alliance-update
|
||||
++ alliance-update
|
||||
|=(=update:alliance (fact:io (alliance-update:cg update) /alliance ~))
|
||||
--
|
||||
:: +tr: engine for treaties
|
||||
@ -298,9 +304,17 @@
|
||||
++ watching (~(has by wex.bowl) [path dock])
|
||||
++ safe-watch `(unit card)`?:(|(watching =(our.bowl ship)) ~ `watch)
|
||||
++ leave (leave:pass dock)
|
||||
++ give
|
||||
++ gone
|
||||
^- (list card)
|
||||
:~ (fact:io (treaty-update:cg %del ship desk) /treaties ~)
|
||||
(kick-only:io our.bowl path ~)
|
||||
==
|
||||
++ give
|
||||
^- (list card)
|
||||
=/ t=treaty (~(got by treaties) ship desk)
|
||||
(fact:io (treaty:cg t) /treaties path ~)
|
||||
:~ (fact:io (treaty-update:cg %add t) /treaties ~)
|
||||
(fact:io (treaty:cg t) path ~)
|
||||
==
|
||||
--
|
||||
:: +so: engine for sovereign treaties
|
||||
++ so
|
||||
@ -314,8 +328,15 @@
|
||||
++ kick
|
||||
(kick:io path ~)
|
||||
++ give
|
||||
:: notably gives on the /treaties path, like +give:tr does.
|
||||
:: this should not give duplicate facts, because sovereign treaties
|
||||
:: are handled in this core, not as "normal"/foreign treaties.
|
||||
::
|
||||
^- (list card)
|
||||
=/ t=treaty (~(got by sovereign) desk)
|
||||
(fact:io (treaty:cg t) /sovereign path ~)
|
||||
:~ (fact:io (treaty-update:cg %add t) /treaties ~)
|
||||
(fact:io (treaty:cg t) path ~)
|
||||
==
|
||||
++ publish
|
||||
(poke-our:pass %hood kiln-permission+!>([desk / &]))
|
||||
--
|
||||
|
@ -1,10 +1,10 @@
|
||||
:~ title+'System'
|
||||
info+'An app launcher for Urbit.'
|
||||
color+0xee.5432
|
||||
glob-http+['https://bootstrap.urbit.org/glob-0v1.0b7ou.danvu.2847h.pj7dp.5in88.glob' 0v1.0b7ou.danvu.2847h.pj7dp.5in88]
|
||||
glob-http+['https://bootstrap.urbit.org/glob-0v5.fdf99.nph65.qecq3.ncpjn.q13mb.glob' 0v5.fdf99.nph65.qecq3.ncpjn.q13mb]
|
||||
::glob-ames+~zod^0v0
|
||||
base+'grid'
|
||||
version+[0 0 1]
|
||||
version+[1 0 1]
|
||||
website+'https://tlon.io'
|
||||
license+'MIT'
|
||||
==
|
||||
|
7
pkg/garden/gen/treaty/unally.hoon
Normal file
7
pkg/garden/gen/treaty/unally.hoon
Normal file
@ -0,0 +1,7 @@
|
||||
:: :treaty|unally: Stop syncing treaty data from ship
|
||||
::
|
||||
:- %say
|
||||
|= $: [now=@da eny=@uvJ bec=beak]
|
||||
[[=ship ~] ~]
|
||||
==
|
||||
[%ally-update-0 %del ship]
|
@ -37,7 +37,7 @@
|
||||
++ cut (jest 'Content-Type: ')
|
||||
++ dim (jest (cat 3 '--' del))
|
||||
++ nip (jest '\0d\0a')
|
||||
++ nab (more fas urs:ab)
|
||||
++ nab (more fas (cook (cury rap 3) (plus qit)))
|
||||
++ nag (dine ;~(less ;~(plug nip dim) next))
|
||||
++ nod (dine ;~(less doq next))
|
||||
++ nom (dine alp)
|
||||
|
@ -77,5 +77,16 @@
|
||||
==
|
||||
==
|
||||
--
|
||||
++ dejs
|
||||
=, dejs:format
|
||||
|%
|
||||
++ ship (su ;~(pfix sig fed:ag))
|
||||
++ ally-update
|
||||
^- $-(json update:ally)
|
||||
%- of
|
||||
:~ add+ship
|
||||
del+ship
|
||||
==
|
||||
--
|
||||
--
|
||||
|
||||
|
@ -10,5 +10,6 @@
|
||||
++ grab
|
||||
|%
|
||||
++ noun update:ally
|
||||
++ json ally-update:dejs:treat
|
||||
--
|
||||
--
|
||||
|
@ -1 +1 @@
|
||||
[%zuse 420]
|
||||
[%zuse 419]
|
||||
|
@ -32,6 +32,6 @@
|
||||
;< =bowl:spider bind:m get-bowl:strandio
|
||||
;< =cage bind:m
|
||||
(watch-one:strandio /glob/(scot %da now.bowl) [ship %docket] /glob/[base]/(scot %uv hash))
|
||||
?> ?=(%glob p.cage)
|
||||
?> ?=(%glob-0 p.cage)
|
||||
(pure:m q.cage)
|
||||
--
|
||||
|
103
pkg/garden/tests/app/hark-store.hoon
Normal file
103
pkg/garden/tests/app/hark-store.hoon
Normal file
@ -0,0 +1,103 @@
|
||||
/- hark=hark-store
|
||||
/+ *test, re=hark-unreads
|
||||
/= agent /app/hark-store
|
||||
|%
|
||||
++ place
|
||||
^- place:hark
|
||||
[%landscape /graph/~zod/test]
|
||||
::
|
||||
++ bin
|
||||
^- bin:hark
|
||||
[/ place]
|
||||
|
||||
::
|
||||
++ body
|
||||
|= run=@
|
||||
:* ~[text/'Title']
|
||||
~[text/(crip "Contents {(scow %ud run)}")]
|
||||
`time`(add (mul ~s1 run) *time)
|
||||
/
|
||||
/test
|
||||
==
|
||||
::
|
||||
++ add-note
|
||||
|= run=@
|
||||
^- action:hark
|
||||
[%add-note bin (body run)]
|
||||
::
|
||||
++ read-count
|
||||
^- action:hark
|
||||
[%read-count place]
|
||||
::
|
||||
+$ state
|
||||
$: %9
|
||||
places=(map place:hark stats:hark)
|
||||
seen=timebox:hark
|
||||
unseen=timebox:hark
|
||||
=archive:hark
|
||||
half-open=(map bin:hark @da)
|
||||
==
|
||||
++ bowl
|
||||
|= run=@ud
|
||||
^- bowl:gall
|
||||
:* [~zod ~zod %hark-store]
|
||||
[~ ~]
|
||||
[run `@uvJ`(shax run) (add (mul run ~s1) *time) [~zod %garden ud+run]]
|
||||
==
|
||||
--
|
||||
|%
|
||||
::
|
||||
++ test-half-open
|
||||
=| run=@ud
|
||||
=^ mov1 agent
|
||||
(~(on-poke agent (bowl run)) %hark-action !>((add-note run)))
|
||||
=^ mova agent
|
||||
(~(on-poke agent (bowl run)) %noun !>(%sane))
|
||||
=. run +(run)
|
||||
=^ mov2 agent
|
||||
(~(on-poke agent (bowl run)) %hark-action !>(read-count))
|
||||
=^ mov3 agent
|
||||
(~(on-poke agent (bowl run)) %noun !>(%sane))
|
||||
=/ expected-archive=notification:hark
|
||||
[(add *time (mul ~s1 0)) bin ~[(body 0)]]
|
||||
=+ !<(=state on-save:agent)
|
||||
=/ actual-archive=notification:hark
|
||||
(~(got re archive.state) (add *time ~s1) bin)
|
||||
(expect-eq !>(expected-archive) !>(actual-archive))
|
||||
::
|
||||
++ test-half-open-double
|
||||
=| run=@ud
|
||||
=^ mov1 agent
|
||||
(~(on-poke agent (bowl run)) %hark-action !>((add-note run)))
|
||||
=. run +(run)
|
||||
=^ mov2 agent
|
||||
(~(on-poke agent (bowl run)) %hark-action !>(read-count))
|
||||
=. run +(run)
|
||||
=^ mov3 agent
|
||||
(~(on-poke agent (bowl run)) %hark-action !>((add-note run)))
|
||||
=. run +(run)
|
||||
=^ mov4 agent
|
||||
(~(on-poke agent (bowl run)) %hark-action !>(read-count))
|
||||
=. run +(run)
|
||||
=^ mov5 agent
|
||||
(~(on-poke agent (bowl run)) %noun !>(%sane))
|
||||
=/ expected-archive=notification:hark
|
||||
[(add *time (mul ~s1 2)) bin ~[(body 2) (body 0)]]
|
||||
=+ !<(=state on-save:agent)
|
||||
=/ actual-archive=notification:hark
|
||||
(~(got re archive.state) (add *time ~s1) bin)
|
||||
(expect-eq !>(expected-archive) !>(actual-archive))
|
||||
::
|
||||
++ test-half-open-capped
|
||||
=| run=@ud
|
||||
|-
|
||||
?: =(run 31)
|
||||
=+ !<(=state on-save:agent)
|
||||
(expect-eq !>(~) !>(half-open.state))
|
||||
=^ movs agent
|
||||
(~(on-poke agent (bowl run)) %hark-action !>((add-note run)))
|
||||
=^ mavs agent
|
||||
(~(on-poke agent (bowl run)) %hark-action !>(read-count))
|
||||
$(run +(run))
|
||||
::
|
||||
--
|
2
pkg/grid/.env
Normal file
2
pkg/grid/.env
Normal file
@ -0,0 +1,2 @@
|
||||
# Change manually to clear local storage once
|
||||
VITE_LAST_WIPE=2021-10-20
|
3
pkg/grid/.gitignore
vendored
3
pkg/grid/.gitignore
vendored
@ -5,5 +5,4 @@ dist-ssr
|
||||
*.local
|
||||
stats.html
|
||||
.eslintcache
|
||||
.vercel
|
||||
.env
|
||||
.vercel
|
@ -18,6 +18,7 @@
|
||||
</head>
|
||||
<body class="text-sm leading-6 font-sans text-gray-900 bg-white antialiased">
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/storage-wipe.ts"></script>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
19268
pkg/grid/package-lock.json
generated
19268
pkg/grid/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@
|
||||
"serve": "vite preview",
|
||||
"lint": "eslint --cache \"**/*.{js,jsx,ts,tsx}\"",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"test": "echo \"No test yet\"",
|
||||
"test": "tsc --noEmit",
|
||||
"tsc": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -39,6 +39,7 @@
|
||||
"react-error-boundary": "^3.1.3",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"slugify": "^1.6.0",
|
||||
"urbit-ob": "^5.0.1",
|
||||
"zustand": "^3.5.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -51,9 +52,9 @@
|
||||
"@types/react-router-dom": "^5.1.8",
|
||||
"@typescript-eslint/eslint-plugin": "^4.26.1",
|
||||
"@typescript-eslint/parser": "^4.26.1",
|
||||
"@urbit/vite-plugin-urbit": "^0.6.0",
|
||||
"@urbit/vite-plugin-urbit": "^0.7.1",
|
||||
"@vitejs/plugin-react-refresh": "^1.3.1",
|
||||
"autoprefixer": "^10.3.1",
|
||||
"autoprefixer": "^10.3.7",
|
||||
"eslint": "^7.28.0",
|
||||
"eslint-config-airbnb": "^18.2.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
@ -66,15 +67,15 @@
|
||||
"eslint-plugin-tailwind": "^0.2.1",
|
||||
"husky": "^7.0.0",
|
||||
"lint-staged": "^11.1.2",
|
||||
"postcss": "^8.3.6",
|
||||
"postcss": "^8.3.9",
|
||||
"prettier": "^2.3.2",
|
||||
"rollup-plugin-analyzer": "^4.0.0",
|
||||
"rollup-plugin-visualizer": "^5.5.2",
|
||||
"tailwindcss": "^2.2.7",
|
||||
"tailwindcss": "^2.2.16",
|
||||
"tailwindcss-theming": "^3.0.0-beta.3",
|
||||
"tailwindcss-touch": "^1.0.1",
|
||||
"typescript": "^4.3.2",
|
||||
"vite": "^2.4.4",
|
||||
"vite": "^2.6.7",
|
||||
"vite-plugin-html-config": "^1.0.5"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
@ -1,28 +0,0 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0)">
|
||||
<rect width="32" height="32" rx="8" fill="#219DFF" fill-opacity="0.3"/>
|
||||
<g style="mix-blend-mode:multiply">
|
||||
<path d="M40.5967 36.0162L19.8147 34.081C19.4445 34.0474 19.1416 33.7445 19.1248 33.3911L17.4084 -2.06444C17.3916 -2.41782 17.6944 -2.68706 18.0646 -2.65341L38.8466 -0.718245C39.2168 -0.68459 39.5197 -0.3817 39.5365 -0.0283222L41.2529 35.4272C41.2866 35.7806 40.9837 36.0498 40.5967 36.0162Z" fill="#E5E5E5"/>
|
||||
<path d="M29.1031 12.1036C31.7113 11.9185 34.2186 14.1229 34.471 16.9499C34.7234 19.8106 32.5022 22.4525 29.7257 22.6545C26.966 22.8564 24.5092 20.6688 24.3072 17.825C24.0548 14.7624 26.091 12.3392 29.1031 12.1036Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M10.3238 26.5929C7.85016 26.7443 5.6121 24.8933 5.19141 22.3692C4.73707 19.6431 6.4703 16.9339 9.11222 16.3449C10.795 15.9747 12.3094 16.4459 13.5547 17.6575C14.9514 19.0037 15.574 20.6864 15.1701 22.6384C14.8167 24.2539 13.7398 25.3308 12.3263 26.0544C11.7036 26.3573 11.0306 26.5592 10.3238 26.5929Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M16.685 -4C16.8364 -3.71393 17.1057 -3.69711 17.3412 -3.66345C21.9856 -3.07449 26.63 -2.48553 31.2744 -1.89656C34.0004 -1.56001 36.7433 -1.22346 39.4694 -0.886914C39.6545 -0.870087 39.8396 -0.853251 40.0247 -0.836424C40.5295 -0.785941 40.8156 -0.499878 40.8324 0.0217743C40.8661 0.930459 40.8997 1.85597 40.9165 2.78149C41.0175 6.51719 41.3036 10.2361 41.5728 13.9549C41.7243 15.9574 41.7411 17.9935 41.8421 19.996C41.9935 23.0418 42.1618 26.1044 42.3301 29.1502C42.4479 31.1358 42.5825 33.1046 42.6834 35.0903C42.7171 35.6456 42.6834 36.2177 42.6498 36.773C42.633 37.1432 42.4815 37.261 42.1281 37.2273C40.2939 37.0422 38.4429 36.8572 36.6087 36.6889C34.8082 36.5374 32.9908 36.4196 31.1734 36.2682C29.2887 36.1167 27.4209 35.9485 25.553 35.7802C23.5506 35.6119 21.5649 35.4436 19.5625 35.2922C18.7547 35.2249 18.6538 35.1576 18.6706 34.2994C18.7043 31.994 18.4518 29.7055 18.3172 27.4001C18.2836 26.6765 18.2163 25.9698 18.1658 25.2462C18.149 25.0947 18.1321 24.9433 18.3172 24.9265C18.5023 24.9096 18.5528 25.0442 18.5696 25.2125C18.6201 25.9024 18.6538 26.5924 18.6874 27.2823C18.8221 29.655 18.9735 32.0108 19.1081 34.3835C19.125 34.7537 19.2091 34.8547 19.5793 34.8883C21.3125 35.0398 23.0289 35.1744 24.7622 35.309C27.4377 35.5278 30.1133 35.7634 32.7889 35.9821C35.0269 36.1672 37.265 36.3187 39.503 36.5038C40.2098 36.5543 40.9165 36.6216 41.6233 36.6721C42.1113 36.7057 42.1618 36.6889 42.145 36.1841C41.9935 33.0037 41.8589 29.8401 41.7074 26.6597C41.5896 24.2365 41.4719 21.8134 41.3372 19.3902C41.1858 16.4454 41.0343 13.5174 40.8661 10.5726C40.681 7.13979 40.4959 3.70699 40.3108 0.274187C40.2771 -0.331603 40.193 -0.449387 39.604 -0.516697C36.8106 -0.870075 34.0173 -1.22346 31.2239 -1.57684C28.4642 -1.93021 25.6877 -2.26676 22.928 -2.62013C21.0433 -2.85572 19.1754 -3.09132 17.2907 -3.3269C16.8869 -3.37738 16.7859 -3.29325 16.8196 -2.82208C16.9037 -1.32443 17.0047 0.190053 17.0888 1.6877C17.2739 4.78396 17.4759 7.89703 17.661 10.9933C17.7619 12.6424 17.8629 14.2747 17.9638 15.9238C17.9638 16.0079 17.8965 16.1088 17.8461 16.2098C17.7451 16.1593 17.5936 16.1425 17.56 16.0584C17.4927 15.9406 17.4758 15.7891 17.459 15.6377C17.3749 13.5174 17.3076 11.3972 17.1898 9.27689C17.0215 6.53401 16.8196 3.79113 16.6345 1.03142C16.5335 -0.398913 16.4494 -1.81243 16.3652 -3.24276C16.3821 -3.49518 16.4157 -3.78124 16.685 -4Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M2.85198 21.9824C1.96012 21.8815 1.1524 21.7805 0.327854 21.6964C-1.80924 21.4608 -3.94633 21.2084 -6.10025 20.9896C-8.84313 20.7035 -11.586 20.4175 -14.3457 20.1314C-14.4972 20.1146 -14.6654 20.1146 -14.8169 20.0641C-14.901 20.0304 -14.9683 19.9295 -15.0356 19.8622C-14.9515 19.8117 -14.8505 19.7275 -14.7664 19.7275C-14.1101 19.778 -13.4707 19.8453 -12.8312 19.9126C-10.1388 20.1987 -7.46327 20.5016 -4.77087 20.7877C-2.3982 21.0401 -0.042347 21.3093 2.33033 21.5617C2.48178 21.5786 2.63323 21.5617 2.78467 21.6122C2.86881 21.6291 2.93612 21.73 3.02025 21.7973C2.95294 21.8646 2.88563 21.9488 2.85198 21.9824Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M4.85503 13.7363C5.10744 13.8036 5.34303 13.8541 5.56179 13.9046C9.49942 14.8806 13.4539 15.8398 17.3915 16.8158C17.6944 16.8831 17.9973 16.9672 18.3002 17.0345C18.4348 17.0682 18.6031 17.1018 18.5358 17.2869C18.519 17.3542 18.317 17.4047 18.2329 17.3879C17.4252 17.2028 16.6006 17.0009 15.7929 16.7989C12.2086 15.9239 8.60756 15.032 5.02331 14.157C4.956 14.1402 4.88868 14.1402 4.8382 14.0897C4.77089 14.0392 4.7204 13.9551 4.66992 13.8878C4.7204 13.8373 4.78772 13.77 4.85503 13.7363Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M28.4973 9.64627C28.4468 9.71358 28.4132 9.81456 28.3459 9.84821C28.2954 9.86504 28.1944 9.81456 28.1439 9.76407C28.0766 9.69676 28.0261 9.5958 27.9756 9.51166C26.8145 7.03802 25.6534 4.54754 24.4924 2.0739C24.4419 1.97293 24.3746 1.88881 24.3409 1.77102C24.3241 1.70371 24.3577 1.56908 24.3914 1.53543C24.4587 1.50177 24.5597 1.53542 24.6438 1.56907C24.6943 1.5859 24.7111 1.67004 24.7279 1.72052C25.9227 4.24465 27.1174 6.76877 28.3122 9.29289C28.3795 9.39386 28.43 9.51165 28.4973 9.64627Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M17.5598 22.2002C18.4012 22.2843 19.1584 22.3685 19.9325 22.4526C20.7907 22.5367 21.6657 22.6377 22.5239 22.7387C22.6417 22.7555 22.81 22.7387 22.7932 22.9406C22.7763 23.1257 22.6585 23.1425 22.4903 23.1257C20.8748 22.9574 19.2762 22.806 17.6608 22.6545C17.6608 22.6545 17.6439 22.6545 17.6271 22.6545C17.4925 22.6377 17.3242 22.604 17.3579 22.4189C17.3747 22.318 17.5093 22.2507 17.5598 22.2002Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M22.9613 14.7636C22.8435 14.7131 22.7593 14.6795 22.692 14.629C22.1704 14.2924 21.6655 13.9391 21.1439 13.6025C20.6222 13.266 20.0838 12.9462 19.5621 12.6265C19.5116 12.5929 19.4275 12.5592 19.4107 12.5087C19.377 12.4414 19.3602 12.3405 19.3938 12.2731C19.4107 12.2395 19.5285 12.2227 19.5958 12.2227C19.6463 12.2227 19.6799 12.2731 19.7304 12.29C20.8073 12.9631 21.8675 13.6193 22.9444 14.2924C22.9949 14.3261 23.0454 14.3598 23.0959 14.3934C23.1464 14.4607 23.2305 14.5617 23.2137 14.5953C23.1295 14.6626 23.0286 14.7131 22.9613 14.7636Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M21.6151 3.20215C21.6487 3.2358 21.7329 3.28629 21.7833 3.3536C22.4396 4.41373 23.0959 5.49069 23.7522 6.56765C23.7858 6.63496 23.7522 6.76957 23.7353 6.85371C23.6512 6.82005 23.5166 6.80323 23.4661 6.73592C22.7762 5.67579 22.1031 4.61566 21.43 3.5387C21.3458 3.38725 21.4131 3.21898 21.6151 3.20215Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M24.3413 8.09879C24.375 8.04831 24.3918 7.94734 24.4254 7.93051C24.4928 7.89686 24.5937 7.89686 24.6274 7.93051C24.7115 7.99782 24.7788 8.09879 24.8461 8.18293C25.3846 9.07478 25.9231 9.94982 26.4784 10.8417C26.5625 10.9595 26.613 11.0941 26.4616 11.1614C26.3943 11.195 26.2428 11.1277 26.1923 11.0436C25.6202 10.1517 25.0649 9.25988 24.5096 8.36803C24.4254 8.30072 24.3918 8.19975 24.3413 8.09879Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M19.3768 17.3047C19.7638 17.4057 20.1172 17.473 20.4706 17.5739C21.1774 17.7422 21.9009 17.9273 22.6077 18.0956C22.6582 18.1124 22.7423 18.1124 22.776 18.1461C22.8433 18.2134 22.8938 18.2975 22.9442 18.3648C22.8433 18.4153 22.7423 18.5163 22.675 18.4995C22.1029 18.3648 21.5476 18.2134 20.9754 18.0788C20.4538 17.9441 19.949 17.8095 19.4273 17.6749C19.3432 17.6581 19.2758 17.5571 19.2422 17.473C19.2422 17.4393 19.3432 17.3552 19.3768 17.3047Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M0.58035 17.1855C0.98421 17.2697 1.33759 17.337 1.69097 17.4043C2.31359 17.5221 2.91938 17.6399 3.54199 17.7409C3.67661 17.7577 3.81123 17.7913 3.77757 17.9764C3.74392 18.1447 3.6093 18.1447 3.47468 18.1279C2.49869 17.9428 1.53952 17.7577 0.563527 17.5557C0.496217 17.5389 0.445728 17.4211 0.378418 17.3538C0.445728 17.3033 0.51304 17.236 0.58035 17.1855Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M20.6391 20.8874C20.4372 21.1903 20.2184 21.2239 19.9155 21.1566C19.3938 21.022 18.8554 20.9379 18.3337 20.8032C18.2496 20.7864 18.1655 20.6686 18.0981 20.6013C18.1991 20.5508 18.3169 20.433 18.401 20.4499C19.1414 20.5845 19.8819 20.7359 20.6391 20.8874Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M30.8868 8.97362C30.8532 9.0241 30.8027 9.09142 30.7354 9.17556C30.6512 9.10825 30.5334 9.04093 30.5166 8.95679C30.382 8.30052 30.2474 7.66108 30.1464 7.00481C30.1296 6.92067 30.2305 6.81971 30.281 6.71875C30.3483 6.78606 30.4661 6.83654 30.483 6.90385C30.6176 7.57695 30.7522 8.25004 30.8868 8.97362Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
<path d="M23.0117 21.5446C22.8098 21.5615 22.6079 21.5951 22.4228 21.5783C22.0694 21.5278 21.7329 21.4605 21.3795 21.3764C21.3122 21.3595 21.228 21.2586 21.2449 21.2081C21.2449 21.1576 21.3458 21.0566 21.3963 21.0566C21.9516 21.0903 22.5069 21.1913 23.0117 21.4605C23.0286 21.4942 23.0117 21.511 23.0117 21.5446Z" fill="black" stroke="black" stroke-width="0.5" stroke-miterlimit="10"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0">
|
||||
<rect width="32" height="32" rx="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 9.4 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 24 KiB |
@ -8,8 +8,8 @@ import { Dialog, DialogClose, DialogContent, DialogTrigger } from './Dialog';
|
||||
import { DocketHeader } from './DocketHeader';
|
||||
import { Spinner } from './Spinner';
|
||||
import { VatMeta } from './VatMeta';
|
||||
import useDocketState, { ChargeWithDesk } from '../state/docket';
|
||||
import { getAppHref } from '../state/util';
|
||||
import useDocketState, { ChargeWithDesk, useTreaty } from '../state/docket';
|
||||
import { getAppHref, getAppName } from '../state/util';
|
||||
import { addRecentApp } from '../nav/search/Home';
|
||||
import { TreatyMeta } from './TreatyMeta';
|
||||
|
||||
@ -52,6 +52,7 @@ export const AppInfo: FC<AppInfoProps> = ({ docket, vat, className }) => {
|
||||
const [ship, desk] = getRemoteDesk(docket, vat);
|
||||
const publisher = vat?.arak?.rail?.publisher ?? ship;
|
||||
const [copied, setCopied] = useState(false);
|
||||
const treaty = useTreaty(ship, desk);
|
||||
|
||||
const installApp = async () => {
|
||||
if (installStatus === 'installed') {
|
||||
@ -113,7 +114,7 @@ export const AppInfo: FC<AppInfoProps> = ({ docket, vat, className }) => {
|
||||
className="space-y-6"
|
||||
containerClass="w-full max-w-md"
|
||||
>
|
||||
<h2 className="h4">Install “{docket.title}”</h2>
|
||||
<h2 className="h4">Install “{getAppName(docket)}”</h2>
|
||||
<p className="text-base tracking-tight pr-6">
|
||||
This application will be able to view and interact with the contents of your
|
||||
Urbit. Only install if you trust the developer.
|
||||
@ -123,7 +124,7 @@ export const AppInfo: FC<AppInfoProps> = ({ docket, vat, className }) => {
|
||||
Cancel
|
||||
</DialogClose>
|
||||
<DialogClose as={Button} onClick={installApp}>
|
||||
Get “{docket.title}”
|
||||
Get “{getAppName(docket)}”
|
||||
</DialogClose>
|
||||
</div>
|
||||
</DialogContent>
|
||||
@ -135,18 +136,20 @@ export const AppInfo: FC<AppInfoProps> = ({ docket, vat, className }) => {
|
||||
</PillButton>
|
||||
</div>
|
||||
</DocketHeader>
|
||||
<div className="space-y-6">
|
||||
{vat ? (
|
||||
<>
|
||||
<hr className="-mx-5 sm:-mx-8 border-gray-50" />
|
||||
<VatMeta vat={vat} />
|
||||
</>
|
||||
) : null}
|
||||
{'chad' in docket ? null : (
|
||||
{!treaty ? null : (
|
||||
<>
|
||||
<hr className="-mx-5 sm:-mx-8 border-gray-50" />
|
||||
<TreatyMeta treaty={docket} />
|
||||
<TreatyMeta treaty={treaty} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ import classNames from 'classnames';
|
||||
import React, { HTMLProps, ReactNode } from 'react';
|
||||
import { Link, LinkProps } from 'react-router-dom';
|
||||
import { DocketWithDesk } from '../state/docket';
|
||||
import { getAppHref } from '../state/util';
|
||||
import { getAppHref, getAppName } from '../state/util';
|
||||
import { DocketImage } from './DocketImage';
|
||||
|
||||
type Sizes = 'xs' | 'small' | 'default';
|
||||
@ -57,7 +57,7 @@ export const AppLink = <T extends DocketWithDesk>({
|
||||
<>
|
||||
<DocketImage color={app.color} image={app.image} size={size} />
|
||||
<div className="flex-1 text-black">
|
||||
<p>{app.title}</p>
|
||||
<p>{getAppName(app)}</p>
|
||||
{app.info && size === 'default' && <p className="font-normal">{app.info}</p>}
|
||||
</div>
|
||||
</>
|
||||
|
@ -4,6 +4,7 @@ import { MatchItem } from '../nav/Nav';
|
||||
import { useRecentsStore } from '../nav/search/Home';
|
||||
import { AppLink, AppLinkProps } from './AppLink';
|
||||
import { DocketWithDesk } from '../state/docket';
|
||||
import { getAppName } from '../state/util';
|
||||
|
||||
type AppListProps<T extends DocketWithDesk> = {
|
||||
apps: T[];
|
||||
@ -45,7 +46,7 @@ export const AppList = <T extends DocketWithDesk>({
|
||||
aria-labelledby={labelledBy}
|
||||
>
|
||||
{apps.map((app) => (
|
||||
<li key={app.title} id={app.title} role="option" aria-selected={selected(app)}>
|
||||
<li key={getAppName(app)} id={getAppName(app)} role="option" aria-selected={selected(app)}>
|
||||
<AppLink
|
||||
{...props}
|
||||
app={app}
|
||||
|
@ -1,21 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Docket } from '@urbit/api/docket';
|
||||
import { DocketImage } from './DocketImage';
|
||||
import { getAppName } from '../state/util';
|
||||
import { DocketWithDesk } from '../state/docket';
|
||||
|
||||
interface DocketHeaderProps {
|
||||
docket: Docket;
|
||||
docket: DocketWithDesk;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export function DocketHeader(props: DocketHeaderProps) {
|
||||
const { docket, children } = props;
|
||||
const { info, title, image, color } = docket;
|
||||
const { info, image, color } = docket;
|
||||
|
||||
return (
|
||||
<header className="grid grid-cols-[5rem,1fr] md:grid-cols-[8rem,1fr] auto-rows-min grid-flow-row-dense mb-5 sm:mb-8 gap-x-6 gap-y-4">
|
||||
<DocketImage color={color} image={image} className="row-span-1 md:row-span-2" />
|
||||
<div className="col-start-2">
|
||||
<h1 className="h2">{title}</h1>
|
||||
<h1 className="h2">{getAppName(docket)}</h1>
|
||||
{info && <p className="h4 mt-2 text-gray-500">{info}</p>}
|
||||
</div>
|
||||
{children}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Docket } from '@urbit/api/docket';
|
||||
import cn from 'classnames';
|
||||
import { useTileColor } from '../tiles/useTileColor';
|
||||
@ -19,13 +19,20 @@ const sizeMap: Record<DocketImageSizes, string> = {
|
||||
|
||||
export function DocketImage({ color, image, className = '', size = 'full' }: DocketImageProps) {
|
||||
const { tileColor } = useTileColor(color);
|
||||
const [imageError, setImageError] = useState(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn('flex-none relative bg-gray-200 overflow-hidden', sizeMap[size], className)}
|
||||
style={{ backgroundColor: tileColor }}
|
||||
>
|
||||
{image && (
|
||||
<img className="absolute top-0 left-0 h-full w-full object-contain" src={image} alt="" />
|
||||
{image && !imageError && (
|
||||
<img
|
||||
className="absolute top-0 left-0 h-full w-full object-cover"
|
||||
src={image}
|
||||
alt=""
|
||||
onError={() => setImageError(true)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -16,8 +16,10 @@ export const ShipName = ({ name, ...props }: ShipNameProps) => {
|
||||
<span>{first}</span>
|
||||
{parts.length > 1 && (
|
||||
<>
|
||||
{parts.map((piece) => (
|
||||
<span aria-hidden={separator.test(piece)}>{piece}</span>
|
||||
{parts.map((piece, index) => (
|
||||
<span key={`${piece}-${index}`} aria-hidden={separator.test(piece)}>
|
||||
{piece}
|
||||
</span>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { Vat } from '@urbit/api/hood';
|
||||
|
||||
import { Attribute } from './Attribute';
|
||||
@ -12,12 +11,6 @@ export function VatMeta(props: { vat: Vat }) {
|
||||
const pluralUpdates = next?.length !== 1;
|
||||
return (
|
||||
<div className="mt-5 sm:mt-8 space-y-5 sm:space-y-8">
|
||||
<Attribute title="Developer Desk" attr="desk">
|
||||
{ship}/{foreignDesk}
|
||||
</Attribute>
|
||||
<Attribute title="Last Software Update" attr="case">
|
||||
{moment(cass.da).format('YYYY.MM.DD')}
|
||||
</Attribute>
|
||||
<Attribute title="Desk Hash" attr="hash">
|
||||
{hash}
|
||||
</Attribute>
|
||||
|
11
pkg/grid/src/components/icons/Interface.tsx
Normal file
11
pkg/grid/src/components/icons/Interface.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
export const Interface = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
||||
<path
|
||||
d="M10.2629 19.2638C10.2308 19.2612 10.1984 19.2651 10.1678 19.2752C10.1372 19.2852 10.1089 19.3012 10.0845 19.3223C10.0601 19.3433 10.04 19.369 10.0255 19.3978C10.011 19.4267 10.0023 19.4581 10 19.4903C10 22.5145 12.8617 25 16.3777 25H16.6223C20.1383 25 23 22.5512 23 19.4903C22.9977 19.4581 22.9891 19.4267 22.9746 19.3978C22.9601 19.369 22.9401 19.3433 22.9157 19.3223C22.8912 19.3012 22.8628 19.2852 22.8322 19.2752C22.8016 19.2651 22.7692 19.2612 22.7371 19.2638H16.763V17.7517C19.7531 17.6353 22.1256 15.5845 22.1989 12.9643V12.7317L21.777 7.86476C21.7352 7.61399 21.6021 7.38762 21.4034 7.22934C21.2046 7.07107 20.9543 6.99211 20.7008 7.00769H20.6458C20.3817 6.99791 20.1209 7.06726 19.8965 7.20687C19.6721 7.34647 19.4944 7.54997 19.3862 7.7913L18.7747 9.54217C18.7576 9.5815 18.7294 9.61496 18.6935 9.63846C18.6577 9.66197 18.6158 9.67448 18.5729 9.67448C18.5301 9.67448 18.4881 9.66197 18.4523 9.63846C18.4164 9.61496 18.3882 9.5815 18.3711 9.54217L17.7596 7.78517C17.6442 7.55011 17.4653 7.35215 17.2432 7.21371C17.0211 7.07526 16.7647 7.00187 16.5031 7.00187C16.2414 7.00187 15.985 7.07526 15.7629 7.21371C15.5408 7.35215 15.362 7.55011 15.2465 7.78517L14.635 9.54217C14.618 9.58128 14.5896 9.6144 14.5537 9.63731C14.5177 9.66021 14.4758 9.67185 14.4332 9.67073C14.3897 9.67226 14.3467 9.66086 14.3097 9.63798C14.2727 9.6151 14.2433 9.58177 14.2252 9.54217L13.6138 7.77906C13.5084 7.54379 13.3365 7.34468 13.119 7.20646C12.9016 7.06824 12.6483 6.99699 12.3908 7.00157H12.3298C12.0757 6.98756 11.8254 7.0679 11.6268 7.22718C11.4282 7.38645 11.2953 7.61347 11.2536 7.86476L10.8317 12.9582C10.8287 12.9764 10.8287 12.995 10.8317 13.0133C10.9295 15.6029 13.2775 17.6292 16.2676 17.7455V19.2576L10.2629 19.2638Z"
|
||||
className="stroke-current"
|
||||
strokeMiterlimit="10"
|
||||
/>
|
||||
</svg>
|
||||
);
|
11
pkg/grid/src/components/icons/Notifications.tsx
Normal file
11
pkg/grid/src/components/icons/Notifications.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
export const Notifications = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
||||
<path
|
||||
d="M22.484 18.3687C22.2804 18.4174 22.0769 18.4601 21.9025 18.5149C20.0649 18.9716 19.8962 19.2518 20.2218 21.2006C20.3381 21.8826 20.4428 22.5647 20.5359 23.2529C20.6114 23.5034 20.6135 23.7719 20.542 24.0237C20.4705 24.2756 20.3286 24.4992 20.1347 24.6658C19.5997 25.0251 19.0879 24.7389 18.6402 24.4161C17.9249 23.8984 17.2271 23.3564 16.5584 22.7779C16.428 22.6392 16.2719 22.5299 16.0997 22.4569C15.9274 22.3838 15.7427 22.3485 15.5569 22.353C15.3711 22.3576 15.1882 22.402 15.0194 22.4834C14.8506 22.5649 14.6995 22.6817 14.5755 22.8266C13.8951 23.4356 13.1915 24.0446 12.4762 24.6232C12.3064 24.8171 12.0787 24.9449 11.8305 24.9858C11.5823 25.0268 11.3283 24.9783 11.1098 24.8485C10.9052 24.6924 10.759 24.4666 10.6964 24.2098C10.6337 23.953 10.6586 23.6814 10.7666 23.4417C11.0225 22.4835 11.3074 21.5355 11.6214 20.5977C11.771 20.2589 11.7871 19.8721 11.6663 19.5211C11.5455 19.17 11.2975 18.8829 10.976 18.7219C10.1968 18.2286 9.42927 17.7232 8.67914 17.1872C8.45772 17.0624 8.27581 16.8726 8.15598 16.6411C8.03615 16.4095 7.98352 16.1464 8.0045 15.884C8.08591 15.275 8.58604 15.0618 9.05705 14.9339C9.73741 14.7634 10.4236 14.6173 11.1098 14.4711C12.8194 14.1179 13.0694 13.7342 12.7844 11.8889C12.6361 11.1242 12.5275 10.3517 12.4589 9.57472C12.3891 8.27146 13.0869 7.8147 14.1743 8.4846C14.9445 8.98903 15.6791 9.55076 16.3724 10.1655C16.5106 10.3113 16.6759 10.426 16.8581 10.5023C17.0402 10.5787 17.2354 10.6151 17.4316 10.6094C17.6278 10.6037 17.8208 10.556 17.9986 10.4691C18.1765 10.3823 18.3354 10.2582 18.4657 10.1046C19.107 9.49923 19.7786 8.93003 20.4777 8.39935C20.9022 8.08267 21.4255 7.79035 21.9547 8.20447C22.4839 8.61859 22.327 9.15451 22.199 9.6539C21.9864 10.4894 21.7321 11.3127 21.4372 12.1203C21.3314 12.3196 21.267 12.5401 21.2484 12.7673C21.2298 12.9945 21.2575 13.2232 21.3295 13.4384C21.4014 13.6536 21.5162 13.8504 21.6661 14.0158C21.8159 14.1812 21.9976 14.3115 22.199 14.398C22.8503 14.7695 23.4725 15.2019 24.0889 15.616C24.5715 15.9632 25.0773 16.3651 24.9901 17.0594C24.8854 17.8693 24.1703 17.9363 23.5946 18.1251C23.2291 18.2283 22.8583 18.3096 22.484 18.3687V18.3687Z"
|
||||
className="stroke-current"
|
||||
strokeMiterlimit="10"
|
||||
/>
|
||||
</svg>
|
||||
);
|
14
pkg/grid/src/components/icons/System.tsx
Normal file
14
pkg/grid/src/components/icons/System.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
export const System = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
||||
<path
|
||||
d="M9.09149 13.2275V9.83173c0-.43776.08753-.65664.62518-.66289 2.25063 0 4.50133-.08129 6.75203-.11256 2.2506-.03127 4.3763 0 6.5957-.05628.4939 0 .6689.13133.6252.62536-.0438.96304 0 1.93864 0 2.90794 0 .3127.075.4565.4501.5253.5066.0783.987.2769 1.401.5792.4141.3023.7497.6994.9787 1.1581.229.4588.3447.9657.3375 1.4784-.0073.5127-.1372 1.0162-.379 1.4683-.2095.4663-.5372.8697-.9506 1.1703-.4135.3006-.8983.4878-1.4064.5432-.1375 0-.2813.444-.2938.6816-.05 1.0882-.0563 2.1763-.0688 3.2707 0 .3189-.1313.4377-.4689.4377-4.4951 0-8.9902 0-13.48527.0438-.55016 0-.62518-.2939-.62518-.6816 0-.9506-.05001-1.8761 0-2.8517.04376-.6254-.28744-.838-.79384-.9193-1.38791-.2314-2.32572-1.676-2.38199-3.0205-.03052-.6682.16336-1.3274.55085-1.8725.3875-.5451.94626-.9449 1.58723-1.1355.1563-.0438.30633-.1251.46263-.1626.16181-.0189.32487-.0252.48766-.0187Z"
|
||||
className="stroke-current"
|
||||
/>
|
||||
<path
|
||||
d="M16.2934 19.4812h-.05v.0563H14.9117l-.0016.0001c-.0961.0032-.2028.0176-.2892.0657-.09.0501-.1547.1351-.1654.2679-.0106.1304.0339.2312.1139.298.0779.0651.1843.0937.2923.0937H17.7289c.0572.0054.115-.0006.1699-.0175.0558-.0172.1075-.0454.1522-.0828.0447-.0375.0816-.0836.1082-.1355.0267-.052.0427-.1087.0471-.1669l.0001-.0028c.0017-.0881-.0152-.1591-.049-.2149-.0342-.0562-.0829-.0929-.1374-.1165-.1034-.0448-.234-.0448-.3394-.0448H16.2934ZM14.0053 14.2844h.0018c.0969-.0035.1891-.0055.2778-.0075.2274-.0049.4316-.0094.6313-.0364.124-.0055.2417-.0562.3307-.1427.0896-.0871.1439-.2043.1524-.3291l.0003.0001-.0002-.0053c-.0023-.0631-.0179-.1249-.0457-.1816-.0277-.0566-.0671-.1068-.1155-.1473-.0484-.0404-.1047-.0703-.1654-.0875a.449567.449567 0 0 0-.1835-.0132c-.5885.0065-1.1767.0565-1.7566.1064-.049.0029-.097.0153-.1412.0367a.372835.372835 0 0 0-.1171.0883c-.0328.0369-.0581.0798-.0743.1265-.0161.0463-.0229.0953-.0202.1443.002.0975.0407.1908.1083.2611.0669.0696.1573.1117.2535.1181.3105.0691.626.0691.8618.0691h.0018ZM17.5314 13.8357c.0035.1284.0527.2282.1316.2952.0774.0657.1791.0965.2843.0971.2807.0311.5886.0625.9094.0625v.0001l.0035-.0002c.0818-.0057.1676-.0097.2558-.0138.1959-.0091.4034-.0187.6032-.049.1144-.0104.2213-.062.3006-.1452.0797-.0836.1264-.1934.131-.3089v-.0008c.0035-.1469-.0549-.2558-.1449-.3266-.0877-.0691-.202-.0996-.3101-.0998-.6085-.0344-1.219-.0028-1.8208.0941-.0966.0096-.1861.0556-.25.1289-.0642.0735-.0976.1689-.0936.2664Zm0 0v-.0003l.0499-.0014-.0499.0021v-.0004ZM13.9928 15.4725v.0004l.0059-.0008c.1305-.0155.2786-.038.394-.1095.0588-.0365.1096-.0859.1453-.1532.0357-.0672.0549-.1494.0549-.2497 0-.1011-.022-.1847-.0626-.2524-.0406-.0677-.0981-.1166-.1642-.1514-.1301-.0685-.2968-.0839-.4484-.0839-.155 0-.315.0304-.4321.1103-.0593.0404-.108.0938-.1384.1621-.0303.0683-.0411.1485-.0292.2405.0235.1814.1023.3066.2253.3845.1203.0761.2768.1031.4495.1031ZM18.7441 15.4727v.0005l.0069-.0009c.1326-.0185.2796-.0412.3927-.1128.0578-.0367.1072-.0863.1417-.1542.0344-.0674.0527-.1502.0527-.2516 0-.1024-.0215-.186-.0617-.2532-.0404-.0673-.0976-.1147-.1635-.1479-.1293-.0651-.2961-.0773-.449-.0804-.1578-.0032-.3156.0237-.4305.1035-.1191.0828-.1847.2173-.1642.4084.0201.1879.099.314.2236.3906.1213.0745.2795.098.4513.098ZM15.7842 17.8231l-.0001.0004.006.0004c.0478.003.0957-.0039.1407-.0201.045-.0163.0864-.0416.1213-.0744.0348-.0328.0626-.0725.0815-.1164.0185-.043.0282-.0892.0285-.1359.0048-.0383.0016-.0771-.0093-.1141-.0113-.0381-.0304-.0734-.0563-.1036-.0258-.0302-.0578-.0545-.0937-.0715-.0344-.0162-.0716-.0252-.1095-.0266-.0465-.0098-.0946-.0096-.141.0008-.048.0107-.0931.032-.1319.0623-.0389.0304-.0703.069-.0923.113a.333125.333125 0 0 0-.0348.1395c-.01.0975.0127.1778.0678.2379.054.0588.1332.0917.2231.1083ZM17.3058 17.4694l.0003.0001-.3123-.296.0033-.0499h-.0005c-.1014-.0067-.1971.0132-.2688.067-.073.0549-.1147.1401-.1152.2495-.0037.0429.0012.0861.0147.1271.0137.0417.0359.0801.0651.1128.0293.0327.065.0591.1048.0774.039.0179.0812.0277.1241.0289.1044.0133.1935-.0112.261-.0701.0668-.0584.1066-.1456.1235-.2468Z"
|
||||
className="stroke-current"
|
||||
/>
|
||||
</svg>
|
||||
);
|
8
pkg/grid/src/env.d.ts
vendored
Normal file
8
pkg/grid/src/env.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
interface ImportMetaEnv extends Readonly<Record<string, string | boolean | undefined>> {
|
||||
readonly VITE_LAST_WIPE: string;
|
||||
readonly VITE_STORAGE_VERSION: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
3
pkg/grid/src/global.d.ts
vendored
Normal file
3
pkg/grid/src/global.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
declare module 'urbit-ob' {
|
||||
export function isValidPatp(patp: string): boolean;
|
||||
}
|
@ -148,7 +148,7 @@ export const Nav: FunctionComponent<NavProps> = ({ menu }) => {
|
||||
<DialogContent
|
||||
onInteractOutside={preventClose}
|
||||
onOpenAutoFocus={onOpen}
|
||||
className="fixed bottom-0 sm:top-0 sm:bottom-auto scroll-left-50 flex flex-col justify-end sm:justify-start scroll-full-width h-full max-w-[882px] px-4 sm:pb-4 text-gray-400 -translate-x-1/2 outline-none"
|
||||
className="fixed bottom-0 sm:top-0 sm:bottom-auto scroll-left-50 flex flex-col justify-end sm:justify-start scroll-full-width h-full sm:h-auto max-w-[882px] px-4 sm:pb-4 text-gray-400 -translate-x-1/2 outline-none"
|
||||
role="combobox"
|
||||
aria-controls="leap-items"
|
||||
aria-owns="leap-items"
|
||||
|
@ -4,8 +4,6 @@ import { ErrorBoundary } from 'react-error-boundary';
|
||||
import classNames from 'classnames';
|
||||
import { NotificationPrefs } from './preferences/NotificationPrefs';
|
||||
import { SystemUpdatePrefs } from './preferences/SystemUpdatePrefs';
|
||||
import notificationsSVG from '../assets/notifications.svg';
|
||||
import systemUpdatesSVG from '../assets/system-updates.svg';
|
||||
import { InterfacePrefs } from './preferences/InterfacePrefs';
|
||||
import { useCharges } from '../state/docket';
|
||||
import { AppPrefs } from './preferences/AppPrefs';
|
||||
@ -13,6 +11,10 @@ import { DocketImage } from '../components/DocketImage';
|
||||
import { ErrorAlert } from '../components/ErrorAlert';
|
||||
import { useMedia } from '../logic/useMedia';
|
||||
import { LeftArrow } from '../components/icons/LeftArrow';
|
||||
import { System } from '../components/icons/System';
|
||||
import { Interface } from '../components/icons/Interface';
|
||||
import { Notifications } from '../components/icons/Notifications';
|
||||
import { getAppName } from '../state/util';
|
||||
|
||||
interface SystemPreferencesSectionProps {
|
||||
url: string;
|
||||
@ -45,6 +47,7 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
|
||||
`${match.url}/:submenu/:desk?`
|
||||
);
|
||||
const charges = useCharges();
|
||||
const filteredCharges = Object.values(charges).filter((charge) => charge.desk !== window.desk);
|
||||
const isMobile = useMedia('(max-width: 639px)');
|
||||
const settingsPath = isMobile ? `${match.url}/:submenu` : '/';
|
||||
|
||||
@ -76,7 +79,7 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
|
||||
>
|
||||
<div className="sm:flex h-full overflow-y-auto">
|
||||
<Route exact={isMobile} path={match.url}>
|
||||
<aside className="flex-none self-start w-full sm:w-auto min-w-60 py-4 sm:py-8 font-semibold text-black sm:text-gray-400 border-r-2 border-gray-50">
|
||||
<aside className="flex-none self-start w-full sm:w-auto min-w-60 py-4 sm:py-8 font-semibold text-black sm:text-gray-600 border-r-2 border-gray-50">
|
||||
<nav className="px-2 sm:px-6">
|
||||
<h2 className="sm:hidden h3 mb-4 px-2">System Preferences</h2>
|
||||
<ul className="space-y-1">
|
||||
@ -84,18 +87,18 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
|
||||
url={subUrl('notifications')}
|
||||
active={matchSub('notifications')}
|
||||
>
|
||||
<img className="w-8 h-8 mr-3" src={notificationsSVG} alt="" />
|
||||
<Notifications className="w-8 h-8 mr-3 bg-gray-100 rounded-md" />
|
||||
Notifications
|
||||
</SystemPreferencesSection>
|
||||
<SystemPreferencesSection
|
||||
url={subUrl('system-updates')}
|
||||
active={matchSub('system-updates')}
|
||||
>
|
||||
<img className="w-8 h-8 mr-3" src={systemUpdatesSVG} alt="" />
|
||||
<System className="w-8 h-8 mr-3 bg-gray-100 rounded-md" />
|
||||
System Updates
|
||||
</SystemPreferencesSection>
|
||||
<SystemPreferencesSection url={subUrl('interface')} active={matchSub('interface')}>
|
||||
<img className="w-8 h-8 mr-3" src={systemUpdatesSVG} alt="" />
|
||||
<Interface className="w-8 h-8 mr-3 bg-gray-100 rounded-md" />
|
||||
Interface Settings
|
||||
</SystemPreferencesSection>
|
||||
</ul>
|
||||
@ -103,14 +106,14 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
|
||||
<hr className="my-4 border-t-2 border-gray-50" />
|
||||
<nav className="px-2 sm:px-6">
|
||||
<ul className="space-y-1">
|
||||
{Object.values(charges).map((charge) => (
|
||||
{filteredCharges.map((charge) => (
|
||||
<SystemPreferencesSection
|
||||
key={charge.desk}
|
||||
url={subUrl(`apps/${charge.desk}`)}
|
||||
active={matchSub('apps', charge.desk)}
|
||||
>
|
||||
<DocketImage size="small" className="mr-3" {...charge} />
|
||||
{charge.title}
|
||||
{getAppName(charge)}
|
||||
</SystemPreferencesSection>
|
||||
))}
|
||||
</ul>
|
||||
|
@ -4,6 +4,7 @@ import { Setting } from '../../components/Setting';
|
||||
import { ShipName } from '../../components/ShipName';
|
||||
import { useCharge } from '../../state/docket';
|
||||
import useKilnState, { useVat } from '../../state/kiln';
|
||||
import { getAppName } from '../../state/util';
|
||||
|
||||
export const AppPrefs = ({ match }: RouteComponentProps<{ desk: string }>) => {
|
||||
const { desk } = match.params;
|
||||
@ -18,11 +19,11 @@ export const AppPrefs = ({ match }: RouteComponentProps<{ desk: string }>) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="h3 mb-7">{charge?.title} Settings</h2>
|
||||
<h2 className="h3 mb-7">{getAppName(charge)} Settings</h2>
|
||||
<div className="space-y-3">
|
||||
{tracking ? (
|
||||
<Setting on={otasEnabled} toggle={toggleUpdates} name="Automatic Updates">
|
||||
<p>Automatically download and apply updates to keep {charge?.title} up to date.</p>
|
||||
<p>Automatically download and apply updates to keep {getAppName(charge)} up to date.</p>
|
||||
{otaSource && (
|
||||
<p>
|
||||
OTA Source: <ShipName name={otaSource} className="font-semibold font-mono" />
|
||||
|
@ -4,7 +4,7 @@ import { useProtocolHandling, setLocalState } from '../../state/local';
|
||||
|
||||
export function InterfacePrefs() {
|
||||
const protocolHandling = useProtocolHandling();
|
||||
const secure = window.location.protocol === 'https:';
|
||||
const secure = window.location.protocol === 'https:' || window.location.hostname === 'localhost';
|
||||
const linkHandlingAllowed = secure && 'registerProtocolHandler' in window.navigator;
|
||||
const toggleProtoHandling = async () => {
|
||||
if (!protocolHandling && window?.navigator?.registerProtocolHandler) {
|
||||
|
@ -24,7 +24,7 @@ async function toggleMentions() {
|
||||
export const NotificationPrefs = () => {
|
||||
const doNotDisturb = useSettingsState(selDnd);
|
||||
const mentions = useHarkStore(selMentions);
|
||||
const secure = window.location.protocol === 'https:';
|
||||
const secure = window.location.protocol === 'https:' || window.location.hostname === 'localhost';
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -13,7 +13,7 @@ export const SystemUpdatePrefs = () => {
|
||||
);
|
||||
const base = useVat('base');
|
||||
const otasEnabled = base && !(base.arak?.rail?.paused ?? true);
|
||||
const otaSource = base && base.arak.rail!.ship!;
|
||||
const otaSource = base && base.arak.rail?.ship;
|
||||
|
||||
const toggleBase = useCallback((on: boolean) => toggleOTAs('base', on), [toggleOTAs]);
|
||||
|
||||
|
@ -3,10 +3,11 @@ import { RouteComponentProps } from 'react-router-dom';
|
||||
import fuzzy from 'fuzzy';
|
||||
import { Treaty } from '@urbit/api';
|
||||
import { ShipName } from '../../components/ShipName';
|
||||
import useDocketState, { useAllyTreaties } from '../../state/docket';
|
||||
import useDocketState, { useAllyTreaties, useAllies } from '../../state/docket';
|
||||
import { useLeapStore } from '../Nav';
|
||||
import { AppList } from '../../components/AppList';
|
||||
import { addRecentDev } from './Home';
|
||||
import { Spinner } from '../../components/Spinner';
|
||||
|
||||
type AppsProps = RouteComponentProps<{ ship: string }>;
|
||||
|
||||
@ -17,7 +18,16 @@ export const Apps = ({ match }: AppsProps) => {
|
||||
selectedMatch: state.selectedMatch
|
||||
}));
|
||||
const provider = match?.params.ship;
|
||||
const treaties = useAllyTreaties(provider);
|
||||
const { treaties, status } = useAllyTreaties(provider);
|
||||
const allies = useAllies();
|
||||
const isAllied = provider in allies;
|
||||
|
||||
useEffect(() => {
|
||||
if (Object.keys(allies).length > 0 && !isAllied) {
|
||||
useDocketState.getState().addAlly(provider);
|
||||
}
|
||||
}, [allies, isAllied, provider]);
|
||||
|
||||
const results = useMemo(() => {
|
||||
if (!treaties) {
|
||||
return undefined;
|
||||
@ -44,8 +54,6 @@ export const Apps = ({ match }: AppsProps) => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const { fetchAllyTreaties } = useDocketState.getState();
|
||||
fetchAllyTreaties(provider);
|
||||
select(
|
||||
<>
|
||||
Apps by <ShipName name={provider} className="font-mono" />
|
||||
@ -75,23 +83,36 @@ export const Apps = ({ match }: AppsProps) => {
|
||||
|
||||
return (
|
||||
<div className="dialog-inner-container md:px-6 md:py-8 h4 text-gray-400">
|
||||
<div id="developed-by">
|
||||
<h2 className="mb-3">
|
||||
Software developed by <ShipName name={provider} className="font-mono" />
|
||||
</h2>
|
||||
<p>
|
||||
{count} result{count === 1 ? '' : 's'}
|
||||
</p>
|
||||
</div>
|
||||
{results && (
|
||||
<AppList
|
||||
apps={results}
|
||||
labelledBy="developed-by"
|
||||
matchAgainst={selectedMatch}
|
||||
to={getAppPath}
|
||||
/>
|
||||
{status === 'loading' && (
|
||||
<span className="mb-3">
|
||||
<Spinner className="w-7 h-7 mr-3" /> Finding software...
|
||||
</span>
|
||||
)}
|
||||
<p>That's it!</p>
|
||||
{results && results.length > 0 && (
|
||||
<>
|
||||
<div id="developed-by">
|
||||
<h2 className="mb-3">
|
||||
Software developed by <ShipName name={provider} className="font-mono" />
|
||||
</h2>
|
||||
<p>
|
||||
{count} result{count === 1 ? '' : 's'}
|
||||
</p>
|
||||
</div>
|
||||
<AppList
|
||||
apps={results}
|
||||
labelledBy="developed-by"
|
||||
matchAgainst={selectedMatch}
|
||||
to={getAppPath}
|
||||
/>
|
||||
<p>That's it!</p>
|
||||
</>
|
||||
)}
|
||||
{status === 'error' ||
|
||||
((status === 'success' || status === 'initial') && results?.length === 0 && (
|
||||
<h2>
|
||||
Unable to find software developed by <ShipName name={provider} className="font-mono" />
|
||||
</h2>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -11,7 +11,12 @@ import { AppLink } from '../../components/AppLink';
|
||||
import { ShipName } from '../../components/ShipName';
|
||||
import { ProviderLink } from '../../components/ProviderLink';
|
||||
import useDocketState, { ChargesWithDesks, useCharges } from '../../state/docket';
|
||||
import { getAppHref } from '../../state/util';
|
||||
import {
|
||||
clearStorageMigration,
|
||||
createStorageKey,
|
||||
getAppHref,
|
||||
storageVersion
|
||||
} from '../../state/util';
|
||||
import useContactState from '../../state/contact';
|
||||
|
||||
export interface RecentsStore {
|
||||
@ -61,8 +66,9 @@ export const useRecentsStore = create<RecentsStore>(
|
||||
}),
|
||||
{
|
||||
whitelist: ['recentApps', 'recentDevs'],
|
||||
name: 'recents-store',
|
||||
version: import.meta.env.VITE_SHORTHASH as any
|
||||
name: createStorageKey('recents-store'),
|
||||
version: storageVersion,
|
||||
migrate: clearStorageMigration
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
import fuzzy from 'fuzzy';
|
||||
import { Provider } from '@urbit/api';
|
||||
import { Provider, deSig } from '@urbit/api';
|
||||
import * as ob from 'urbit-ob';
|
||||
import { MatchItem, useLeapStore } from '../Nav';
|
||||
import { useAllies, useCharges } from '../../state/docket';
|
||||
import { ProviderList } from '../../components/ProviderList';
|
||||
@ -53,19 +54,34 @@ export const Providers = ({ match }: ProvidersProps) => {
|
||||
: [],
|
||||
[charges, search]
|
||||
);
|
||||
const results = useMemo(
|
||||
() =>
|
||||
allies
|
||||
? fuzzy
|
||||
.filter(
|
||||
search,
|
||||
Object.entries(allies).map(([ship]) => ship)
|
||||
)
|
||||
.sort(fuzzySort(search))
|
||||
.map((el) => ({ shipName: el.original, ...contacts[el.original] }))
|
||||
: [],
|
||||
[allies, search, contacts]
|
||||
);
|
||||
|
||||
const patp = `~${deSig(search) || ''}`;
|
||||
const isValidPatp = ob.isValidPatp(patp);
|
||||
|
||||
const results = useMemo(() => {
|
||||
if (!allies) {
|
||||
return [];
|
||||
}
|
||||
const exact =
|
||||
isValidPatp && !Object.keys(allies).includes(patp)
|
||||
? [
|
||||
{
|
||||
shipName: patp,
|
||||
...contacts[patp]
|
||||
}
|
||||
]
|
||||
: [];
|
||||
return [
|
||||
...exact,
|
||||
...fuzzy
|
||||
.filter(
|
||||
search,
|
||||
Object.entries(allies).map(([ship]) => ship)
|
||||
)
|
||||
.sort(fuzzySort(search))
|
||||
.map((el) => ({ shipName: el.original, ...contacts[el.original] }))
|
||||
];
|
||||
}, [allies, search, contacts]);
|
||||
|
||||
const count = results?.length;
|
||||
|
||||
@ -87,11 +103,22 @@ export const Providers = ({ match }: ProvidersProps) => {
|
||||
}))
|
||||
: [];
|
||||
|
||||
const newProviderMatches = isValidPatp
|
||||
? [
|
||||
{
|
||||
url: `/leap/search/${patp}/apps`,
|
||||
value: patp,
|
||||
display: patp,
|
||||
openInNewTab: false
|
||||
}
|
||||
]
|
||||
: [];
|
||||
|
||||
useLeapStore.setState({
|
||||
matches: ([] as MatchItem[]).concat(appMatches, providerMatches)
|
||||
matches: ([] as MatchItem[]).concat(appMatches, providerMatches, newProviderMatches)
|
||||
});
|
||||
}
|
||||
}, [results]);
|
||||
}, [results, patp, isValidPatp]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -4,6 +4,7 @@ import { AppInfo } from '../../components/AppInfo';
|
||||
import { Spinner } from '../../components/Spinner';
|
||||
import useDocketState, { useCharge, useTreaty } from '../../state/docket';
|
||||
import { useVat } from '../../state/kiln';
|
||||
import { getAppName } from '../../state/util';
|
||||
import { useLeapStore } from '../Nav';
|
||||
|
||||
export const TreatyInfo = () => {
|
||||
@ -12,6 +13,7 @@ export const TreatyInfo = () => {
|
||||
const treaty = useTreaty(host, desk);
|
||||
const vat = useVat(desk);
|
||||
const charge = useCharge(desk);
|
||||
const name = getAppName(treaty);
|
||||
|
||||
useEffect(() => {
|
||||
if (!charge) {
|
||||
@ -20,9 +22,9 @@ export const TreatyInfo = () => {
|
||||
}, [host, desk]);
|
||||
|
||||
useEffect(() => {
|
||||
select(<>{treaty?.title}</>);
|
||||
select(<>{name}</>);
|
||||
useLeapStore.setState({ matches: [] });
|
||||
}, [treaty?.title]);
|
||||
}, [name]);
|
||||
|
||||
if (!treaty) {
|
||||
// TODO: maybe replace spinner with skeletons
|
||||
|
@ -16,7 +16,7 @@ const api = useMockData
|
||||
scry: async () => {}
|
||||
} as unknown as Urbit)
|
||||
: new Urbit('', '');
|
||||
if (useMockData) {
|
||||
if (import.meta.env.DEV || useMockData) {
|
||||
api.verbose = true;
|
||||
}
|
||||
api.ship = useMockData ? 'dopzod' : window.ship;
|
||||
|
@ -7,7 +7,7 @@ import { persist } from 'zustand/middleware';
|
||||
import Urbit, { SubscriptionRequestInterface } from '@urbit/http-api';
|
||||
import { Poke } from '@urbit/api';
|
||||
import api from './api';
|
||||
import { useMockData } from './util';
|
||||
import { clearStorageMigration, createStorageKey, storageVersion, useMockData } from './util';
|
||||
|
||||
setAutoFreeze(false);
|
||||
enablePatches();
|
||||
@ -73,10 +73,10 @@ export const optReduceState = <S extends Record<string, unknown>, U>(
|
||||
/* eslint-disable-next-line import/no-mutable-exports */
|
||||
export let stateStorageKeys: string[] = [];
|
||||
|
||||
export const stateStorageKey = (stateName: string) => {
|
||||
stateName = `Grid${stateName}State-${import.meta.env.VITE_SHORTHASH as any}`;
|
||||
stateStorageKeys = [...new Set([...stateStorageKeys, stateName])];
|
||||
return stateName;
|
||||
export const stateStorageKey = (stateName: string): string => {
|
||||
const key = createStorageKey(`${stateName}State`);
|
||||
stateStorageKeys = [...new Set([...stateStorageKeys, key])];
|
||||
return key;
|
||||
};
|
||||
|
||||
(window as any).clearStates = () => {
|
||||
@ -149,7 +149,9 @@ export const createState = <T extends Record<string, unknown>>(
|
||||
}),
|
||||
{
|
||||
blacklist,
|
||||
name: stateStorageKey(name)
|
||||
name: stateStorageKey(name),
|
||||
version: storageVersion,
|
||||
migrate: clearStorageMigration
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import create from 'zustand';
|
||||
import create, { SetState } from 'zustand';
|
||||
import produce from 'immer';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { omit, pick } from 'lodash';
|
||||
@ -15,15 +15,19 @@ import {
|
||||
Treaties,
|
||||
chadIsRunning,
|
||||
AllyUpdateIni,
|
||||
AllyUpdateNew,
|
||||
TreatyUpdateIni,
|
||||
TreatyUpdate,
|
||||
docketInstall,
|
||||
ChargeUpdate,
|
||||
kilnRevive,
|
||||
kilnSuspend
|
||||
kilnSuspend,
|
||||
allyShip
|
||||
} from '@urbit/api';
|
||||
import api from './api';
|
||||
import { mockAllies, mockCharges, mockTreaties } from './mock-data';
|
||||
import { fakeRequest, normalizeUrbitColor, useMockData } from './util';
|
||||
import { useAsyncCall } from '../logic/useAsyncCall';
|
||||
|
||||
export interface ChargeWithDesk extends Charge {
|
||||
desk: string;
|
||||
@ -50,6 +54,9 @@ interface DocketState {
|
||||
toggleDocket: (desk: string) => Promise<void>;
|
||||
installDocket: (ship: string, desk: string) => Promise<number | void>;
|
||||
uninstallDocket: (desk: string) => Promise<number | void>;
|
||||
//
|
||||
addAlly: (ship: string) => Promise<number>;
|
||||
set: SetState<DocketState>;
|
||||
}
|
||||
|
||||
const useDocketState = create<DocketState>((set, get) => ({
|
||||
@ -151,6 +158,13 @@ const useDocketState = create<DocketState>((set, get) => ({
|
||||
treaties: useMockData ? normalizeDockets(mockTreaties) : {},
|
||||
charges: {},
|
||||
allies: useMockData ? mockAllies : {},
|
||||
addAlly: async (ship) => {
|
||||
set((draft) => {
|
||||
draft.allies[ship] = [];
|
||||
});
|
||||
|
||||
return api.poke(allyShip(ship));
|
||||
},
|
||||
set
|
||||
}));
|
||||
|
||||
@ -199,6 +213,38 @@ api.subscribe({
|
||||
}
|
||||
});
|
||||
|
||||
api.subscribe({
|
||||
app: 'treaty',
|
||||
path: '/treaties',
|
||||
event: (data: TreatyUpdate) => {
|
||||
useDocketState.getState().set((draft) => {
|
||||
if ('add' in data) {
|
||||
const { ship, desk } = data.add;
|
||||
const treaty = normalizeDocket(data.add, desk);
|
||||
draft.treaties[`${ship}/${desk}`] = treaty;
|
||||
}
|
||||
|
||||
if ('ini' in data) {
|
||||
const treaties = normalizeDockets(data.ini);
|
||||
draft.treaties = { ...draft.treaties, ...treaties };
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
api.subscribe({
|
||||
app: 'treaty',
|
||||
path: '/allies',
|
||||
event: (data: AllyUpdateNew) => {
|
||||
useDocketState.getState().set((draft) => {
|
||||
if ('new' in data) {
|
||||
const { ship, alliance } = data.new;
|
||||
draft.allies[ship] = alliance;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const selCharges = (s: DocketState) => {
|
||||
return s.charges;
|
||||
};
|
||||
@ -222,11 +268,18 @@ export function useAllies() {
|
||||
}
|
||||
|
||||
export function useAllyTreaties(ship: string) {
|
||||
useEffect(() => {
|
||||
useDocketState.getState().fetchAllyTreaties(ship);
|
||||
}, [ship]);
|
||||
const allies = useAllies();
|
||||
const { call: fetchTreaties, status } = useAsyncCall(() =>
|
||||
useDocketState.getState().fetchAllyTreaties(ship)
|
||||
);
|
||||
|
||||
return useDocketState(
|
||||
useEffect(() => {
|
||||
if (ship in allies) {
|
||||
fetchTreaties();
|
||||
}
|
||||
}, [ship, allies]);
|
||||
|
||||
const treaties = useDocketState(
|
||||
useCallback(
|
||||
(s) => {
|
||||
const charter = s.allies[ship];
|
||||
@ -235,6 +288,11 @@ export function useAllyTreaties(ship: string) {
|
||||
[ship]
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
treaties,
|
||||
status
|
||||
};
|
||||
}
|
||||
|
||||
export function useTreaty(host: string, desk: string) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import create from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import produce from 'immer';
|
||||
import { clearStorageMigration, createStorageKey, storageVersion } from './util';
|
||||
|
||||
interface LocalState {
|
||||
protocolHandling: boolean;
|
||||
@ -16,7 +17,9 @@ export const useLocalState = create<LocalState>(
|
||||
protocolHandling: false
|
||||
}),
|
||||
{
|
||||
name: 'grid-local'
|
||||
name: createStorageKey('local'),
|
||||
version: storageVersion,
|
||||
migrate: clearStorageMigration
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DocketHref } from '@urbit/api/docket';
|
||||
import { Docket, DocketHref, Treaty } from '@urbit/api/docket';
|
||||
import { hsla, parseToHsla } from 'color2k';
|
||||
import _ from 'lodash';
|
||||
|
||||
@ -16,6 +16,14 @@ export function getAppHref(href: DocketHref) {
|
||||
return 'site' in href ? href.site : `/apps/${href.glob.base}/`;
|
||||
}
|
||||
|
||||
export function getAppName(app: (Docket & { desk: string }) | Treaty | undefined): string {
|
||||
if (!app) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return app.title || app.desk;
|
||||
}
|
||||
|
||||
export function disableDefault<T extends Event>(e: T): void {
|
||||
e.preventDefault();
|
||||
}
|
||||
@ -50,3 +58,14 @@ export function getDarkColor(color: string): string {
|
||||
const hslaColor = parseToHsla(color);
|
||||
return hsla(hslaColor[0], hslaColor[1], 1 - hslaColor[2], 1);
|
||||
}
|
||||
|
||||
export function createStorageKey(name: string): string {
|
||||
return `~${window.ship}/${window.desk}/${name}`;
|
||||
}
|
||||
|
||||
// for purging storage with version updates
|
||||
export function clearStorageMigration<T>() {
|
||||
return {} as T;
|
||||
}
|
||||
|
||||
export const storageVersion = parseInt(import.meta.env.VITE_STORAGE_VERSION, 10);
|
||||
|
12
pkg/grid/src/storage-wipe.ts
Normal file
12
pkg/grid/src/storage-wipe.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { createStorageKey } from './state/util';
|
||||
|
||||
const key = createStorageKey(`storage-wipe-${import.meta.env.VITE_LAST_WIPE}`);
|
||||
const wiped = localStorage.getItem(key);
|
||||
|
||||
// Loaded before everything, this clears local storage just once.
|
||||
// Change VITE_LAST_WIPE in .env to date of wipe
|
||||
|
||||
if (!wiped) {
|
||||
localStorage.clear();
|
||||
localStorage.setItem(key, 'true');
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
@import "tailwindcss/base";
|
||||
@import "./base.css";
|
||||
@import 'tailwindcss/base';
|
||||
@import './base.css';
|
||||
|
||||
@import "tailwindcss/components";
|
||||
@import "./components.css";
|
||||
@import 'tailwindcss/components';
|
||||
@import './components.css';
|
||||
|
||||
@import "tailwindcss/utilities";
|
||||
@import "./utilities.css";
|
||||
@import 'tailwindcss/utilities';
|
||||
@import './utilities.css';
|
||||
|
||||
@import "./grids.css";
|
||||
@import './grids.css';
|
||||
|
@ -4,6 +4,7 @@ import { Button } from '../components/Button';
|
||||
import { Dialog, DialogClose, DialogContent } from '../components/Dialog';
|
||||
import { useRecentsStore } from '../nav/search/Home';
|
||||
import useDocketState, { useCharges } from '../state/docket';
|
||||
import { getAppName } from '../state/util';
|
||||
|
||||
export const RemoveApp = () => {
|
||||
const history = useHistory();
|
||||
@ -21,16 +22,19 @@ export const RemoveApp = () => {
|
||||
return (
|
||||
<Dialog open onOpenChange={(open) => !open && history.push('/')}>
|
||||
<DialogContent showClose={false} className="space-y-6" containerClass="w-full max-w-md">
|
||||
<h1 className="h4">Remove “{docket?.title || ''}”?</h1>
|
||||
<h1 className="h4">Uninstall “{getAppName(docket)}”?</h1>
|
||||
<p className="text-base tracking-tight pr-6">
|
||||
This will remove the software's tile from your home screen.
|
||||
The app tile will be removed from Landscape, all processes will be stopped and their data archived, and the app will stop receiving updates.
|
||||
</p>
|
||||
<p className="text-base tracking-tight pr-6">
|
||||
If the app is reinstalled, the archived data will be restored and you'll be able to pick up where you left off.
|
||||
</p>
|
||||
<div className="flex space-x-6">
|
||||
<DialogClose as={Button} variant="secondary">
|
||||
Cancel
|
||||
</DialogClose>
|
||||
<DialogClose as={Button} onClick={handleRemoveApp}>
|
||||
Remove “{docket?.title}”
|
||||
Uninstall
|
||||
</DialogClose>
|
||||
</div>
|
||||
</DialogContent>
|
||||
|
@ -4,6 +4,7 @@ import { Button } from '../components/Button';
|
||||
import { Dialog, DialogClose, DialogContent } from '../components/Dialog';
|
||||
import { useRecentsStore } from '../nav/search/Home';
|
||||
import useDocketState, { useCharges } from '../state/docket';
|
||||
import { getAppName } from '../state/util';
|
||||
|
||||
export const SuspendApp = () => {
|
||||
const history = useHistory();
|
||||
@ -24,17 +25,19 @@ export const SuspendApp = () => {
|
||||
return (
|
||||
<Dialog open onOpenChange={(open) => !open && history.push('/')}>
|
||||
<DialogContent showClose={false} className="space-y-6" containerClass="w-full max-w-md">
|
||||
<h1 className="h4">Suspend “{charge?.title || ''}”</h1>
|
||||
<h1 className="h4">Suspend “{getAppName(charge)}”</h1>
|
||||
<p className="text-base tracking-tight pr-6">
|
||||
Suspending an app will turn off automatic updates. You cannot use an app when it is
|
||||
suspended, but you can resume it at any time.
|
||||
All processes will be stopped and data archived. The app will continue to receive updates from its publisher.
|
||||
</p>
|
||||
<p className="text-base tracking-tight pr-6">
|
||||
When unsuspended, archived data will be loaded and all processes will resume running, so you can pick up where you left off.
|
||||
</p>
|
||||
<div className="flex space-x-6">
|
||||
<DialogClose as={Button} variant="secondary">
|
||||
Cancel
|
||||
</DialogClose>
|
||||
<DialogClose as={Button} onClick={handleSuspendApp}>
|
||||
Suspend “{charge?.title}”
|
||||
Suspend
|
||||
</DialogClose>
|
||||
</div>
|
||||
</DialogContent>
|
||||
|
@ -64,14 +64,16 @@ export const Tile: FunctionComponent<TileProps> = ({ charge, desk }) => {
|
||||
lightText={lightText}
|
||||
className="absolute z-10 top-3 right-3 sm:top-5 sm:right-5 opacity-0 pointer-coarse:opacity-100 hover-none:opacity-100 focus:opacity-100 group-hover:opacity-100"
|
||||
/>
|
||||
<div
|
||||
className="h4 absolute z-10 bottom-[8%] left-[5%] sm:bottom-7 sm:left-5 py-1 px-3 rounded-lg"
|
||||
style={{ backgroundColor }}
|
||||
>
|
||||
<h3 className="mix-blend-hard-light">{title}</h3>
|
||||
</div>
|
||||
{title && (
|
||||
<div
|
||||
className="h4 absolute z-10 bottom-[8%] left-[5%] sm:bottom-7 sm:left-5 py-1 px-3 rounded-lg"
|
||||
style={{ backgroundColor }}
|
||||
>
|
||||
<h3 className="mix-blend-hard-light">{title}</h3>
|
||||
</div>
|
||||
)}
|
||||
{image && !loading && (
|
||||
<img className="absolute top-0 left-0 h-full w-full object-contain" src={image} alt="" />
|
||||
<img className="absolute top-0 left-0 h-full w-full object-cover" src={image} alt="" />
|
||||
)}
|
||||
</div>
|
||||
</a>
|
||||
|
@ -85,7 +85,7 @@ export const TileMenu = ({ desk, chad, menuColor, lightText, className }: TileMe
|
||||
)}
|
||||
{suspended && <Item onSelect={() => toggleDocket(desk)}>Resume App</Item>}
|
||||
<Item as={Link} to={`/app/${desk}/remove`} onSelect={linkOnSelect}>
|
||||
Remove App
|
||||
Uninstall App
|
||||
</Item>
|
||||
</DropdownMenu.Group>
|
||||
<DropdownMenu.Arrow className="w-4 h-[10px] fill-current" style={{ color: menuColor }} />
|
||||
|
@ -7,13 +7,7 @@ import { execSync } from 'child_process';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default ({ mode }) => {
|
||||
if (mode !== 'mock') {
|
||||
// using current commit until release
|
||||
const GIT_DESC = execSync('git rev-parse --short HEAD', { encoding: 'utf8' }).trim();
|
||||
process.env.VITE_SHORTHASH = GIT_DESC;
|
||||
} else {
|
||||
process.env.VITE_SHORTHASH = '1';
|
||||
}
|
||||
process.env.VITE_STORAGE_VERSION = Date.now().toString();
|
||||
|
||||
Object.assign(process.env, loadEnv(mode, process.cwd()));
|
||||
const SHIP_URL = process.env.SHIP_URL || process.env.VITE_SHIP_URL || 'http://localhost:8080';
|
||||
@ -36,6 +30,8 @@ export default ({ mode }) => {
|
||||
}
|
||||
},
|
||||
plugins:
|
||||
mode === 'mock' ? [] : [urbitPlugin({ base: 'grid', target: SHIP_URL }), reactRefresh()]
|
||||
mode === 'mock'
|
||||
? []
|
||||
: [urbitPlugin({ base: 'grid', target: SHIP_URL, secure: false }), reactRefresh()]
|
||||
});
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: urbit-king
|
||||
version: 1.6
|
||||
version: 1.7
|
||||
license: MIT
|
||||
license-file: LICENSE
|
||||
data-files:
|
||||
|
@ -109,11 +109,8 @@ module.exports = {
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.LANDSCAPE_SHORTHASH': JSON.stringify(GIT_DESC),
|
||||
'process.env.TUTORIAL_HOST': JSON.stringify('~difmex-passed'),
|
||||
'process.env.TUTORIAL_GROUP': JSON.stringify('beginner-island'),
|
||||
'process.env.TUTORIAL_CHAT': JSON.stringify('introduce-yourself-7010'),
|
||||
'process.env.TUTORIAL_BOOK': JSON.stringify('guides-9684'),
|
||||
'process.env.TUTORIAL_LINKS': JSON.stringify('community-articles-2143')
|
||||
'process.env.LANDSCAPE_STORAGE_VERSION': JSON.stringify(Date.now()),
|
||||
'process.env.LANDSCAPE_LAST_WIPE': JSON.stringify('2021-10-20'),
|
||||
}),
|
||||
|
||||
// new CleanWebpackPlugin(),
|
||||
|
@ -73,11 +73,8 @@ module.exports = {
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.LANDSCAPE_STREAM': JSON.stringify(process.env.LANDSCAPE_STREAM),
|
||||
'process.env.LANDSCAPE_SHORTHASH': JSON.stringify(GIT_DESC),
|
||||
'process.env.TUTORIAL_HOST': JSON.stringify('~difmex-passed'),
|
||||
'process.env.TUTORIAL_GROUP': JSON.stringify('beginner-island'),
|
||||
'process.env.TUTORIAL_CHAT': JSON.stringify('introduce-yourself-7010'),
|
||||
'process.env.TUTORIAL_BOOK': JSON.stringify('guides-9684'),
|
||||
'process.env.TUTORIAL_LINKS': JSON.stringify('community-articles-2143')
|
||||
'process.env.LANDSCAPE_STORAGE_VERSION': Date.now().toString(),
|
||||
'process.env.LANDSCAPE_LAST_WIPE': '2021-10-20',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
title: 'Groups',
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import './register-sw';
|
||||
import './storage-wipe';
|
||||
import App from './views/App';
|
||||
import './wdyr';
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user