From d29ea5703e877362a344e202bb12f99945e0f952 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 16:51:53 -0400 Subject: [PATCH 01/35] channel-js: fixed long-standing issue with subscription errors not being propagated --- pkg/arvo/app/launch/js/channel.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/arvo/app/launch/js/channel.js b/pkg/arvo/app/launch/js/channel.js index ab17b1781..d37e67172 100644 --- a/pkg/arvo/app/launch/js/channel.js +++ b/pkg/arvo/app/launch/js/channel.js @@ -178,8 +178,11 @@ class Channel { this.lastEventId = e.lastEventId; let obj = JSON.parse(e.data); - if (obj.response == "poke") { - let funcs = this.outstandingPokes.get(obj.id); + let pokeFuncs = this.outstandingPokes.get(obj.id); + let subFuncs = this.outstandingSubscriptions.get(obj.id); + + if (obj.response == "poke" && !!pokeFuncs) { + let funcs = pokeFuncs; if (obj.hasOwnProperty("ok")) { funcs["success"](); } else if (obj.hasOwnProperty("err")) { @@ -189,19 +192,20 @@ class Channel { } this.outstandingPokes.delete(obj.id); - } else if (obj.response == "subscribe") { + } else if (obj.response == "subscribe" || + (obj.response == "poke" && !!subFuncs)) { + let funcs = subFuncs; // on a response to a subscribe, we only notify the caller on err // - let funcs = this.outstandingSubscriptions.get(obj.id); if (obj.hasOwnProperty("err")) { funcs["err"](obj.err); this.outstandingSubscriptions.delete(obj.id); } } else if (obj.response == "diff") { - let funcs = this.outstandingSubscriptions.get(obj.id); + let funcs = subFuncs; funcs["event"](obj.json); } else if (obj.response == "quit") { - let funcs = this.outstandingSubscriptions.get(obj.id); + let funcs = subFuncs; funcs["quit"](obj); this.outstandingSubscriptions.delete(obj.id); } else { From e657a5514cec9d3e0a7724f139e4892400de7417 Mon Sep 17 00:00:00 2001 From: Matilde Park Date: Fri, 24 Apr 2020 09:38:38 -0400 Subject: [PATCH 02/35] chat: toggle code at start of input --- pkg/interface/chat/src/js/components/lib/chat-input.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/interface/chat/src/js/components/lib/chat-input.js b/pkg/interface/chat/src/js/components/lib/chat-input.js index 6a61b57f1..2343c9cc1 100644 --- a/pkg/interface/chat/src/js/components/lib/chat-input.js +++ b/pkg/interface/chat/src/js/components/lib/chat-input.js @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import _ from 'lodash'; import moment from 'moment'; import { UnControlled as CodeEditor } from 'react-codemirror2'; +import CodeMirror from 'codemirror'; import 'codemirror/mode/markdown/markdown'; import 'codemirror/addon/display/placeholder'; @@ -306,7 +307,9 @@ export class ChatInput extends Component { 'Enter': cm => this.messageSubmit(), 'Shift-3': cm => - this.toggleCode() + cm.getValue().length === 0 + ? this.toggleCode() + : CodeMirror.Pass } }; @@ -340,8 +343,8 @@ export class ChatInput extends Component { { - this.editor = editor; -}} + this.editor = editor; + }} onChange={(e, d, v) => this.messageChange(e, d, v)} /> From daf32fd0f9a078205d3370f4edb1e3972502f235 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 16:53:00 -0400 Subject: [PATCH 03/35] s3-store: initial commit --- pkg/arvo/app/s3-store.hoon | 71 +++++++++++++++++++++ pkg/arvo/lib/hood/drum.hoon | 23 ++++++- pkg/arvo/lib/s3-json.hoon | 22 +++++++ pkg/arvo/mar/s3/action.hoon | 8 +++ pkg/arvo/mar/s3/update.hoon | 12 ++++ pkg/arvo/sur/s3.hoon | 14 ++++ pkg/interface/groups/src/js/subscription.js | 29 ++++++--- 7 files changed, 166 insertions(+), 13 deletions(-) create mode 100644 pkg/arvo/app/s3-store.hoon create mode 100644 pkg/arvo/lib/s3-json.hoon create mode 100644 pkg/arvo/mar/s3/action.hoon create mode 100644 pkg/arvo/mar/s3/update.hoon create mode 100644 pkg/arvo/sur/s3.hoon diff --git a/pkg/arvo/app/s3-store.hoon b/pkg/arvo/app/s3-store.hoon new file mode 100644 index 000000000..8562686a7 --- /dev/null +++ b/pkg/arvo/app/s3-store.hoon @@ -0,0 +1,71 @@ +/- *s3 +/+ default-agent, verb, dbug +~% %s3-top ..is ~ +|% ++$ card card:agent:gall ++$ versioned-state + $% state-zero + == +:: ++$ state-zero [%0 =credentials] +-- +:: +=| state-zero +=* state - +:: +%- agent:dbug +%+ verb | +^- agent:gall +~% %s3-agent-core ..card ~ +|_ =bowl:gall ++* this . + def ~(. (default-agent this %|) bowl) +:: +++ on-init on-init:def +++ on-save !>(state) +++ on-load + |= old-vase=vase + [~ this(state !<(state-zero old-vase))] +:: +++ on-poke + ~/ %s3-poke + |= [=mark =vase] + ^- (quip card _this) + |^ + ?> (team:title our.bowl src.bowl) + =^ cards state + ?+ mark (on-poke:def mark vase) + %s3-action (poke-action !<(action vase)) + == + [cards this] + :: + ++ poke-action + |= act=action + ^- (quip card _state) + [~ state] + -- +:: +++ on-watch + ~/ %s3-watch + |= =path + ^- (quip card _this) + |^ + ?> (team:title our.bowl src.bowl) + =/ cards=(list card) + ?+ path (on-watch:def path) + [%all ~] (give %s3-update !>([%credentials credentials])) + == + [cards this] + :: + ++ give + |= =cage + ^- (list card) + [%give %fact ~ cage]~ + -- +:: +++ on-leave on-leave:def +++ on-peek on-peek:def +++ on-agent on-agent:def +++ on-arvo on-arvo:def +++ on-fail on-fail:def +-- diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index c76094338..ad7b700ff 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -118,6 +118,7 @@ %link-view %metadata-store %metadata-hook + %s3-store == :: ++ deft-fish :: default connects @@ -223,7 +224,7 @@ == :: ++ on-load - |= ver=?(%1 %2) + |= ver=?(%1 %2 %3) ?- ver %1 =< se-abet =< se-view @@ -237,7 +238,8 @@ =< (se-born %home %link-store) =< (se-born %home %link-proxy-hook) =< (se-born %home %link-listen-hook) - (se-born %home %link-view) + =< (se-born %home %link-view) + (se-born %home %s3-store) :: %2 =< se-abet =< se-view @@ -250,7 +252,22 @@ =< (se-born %home %link-store) =< (se-born %home %link-proxy-hook) =< (se-born %home %link-listen-hook) - (se-born %home %link-view) + =< (se-born %home %link-view) + (se-born %home %s3-store) + + %3 + =< se-abet =< se-view + =< (se-emit %pass /kiln %arvo %g %sear ~wisrut-nocsub) + =< (se-born %home %metadata-store) + =< (se-born %home %metadata-hook) + =< (se-born %home %contact-store) + =< (se-born %home %contact-hook) + =< (se-born %home %contact-view) + =< (se-born %home %link-store) + =< (se-born %home %link-proxy-hook) + =< (se-born %home %link-listen-hook) + =< (se-born %home %link-view) + (se-born %home %s3-store) == :: ++ reap-phat :: ack connect diff --git a/pkg/arvo/lib/s3-json.hoon b/pkg/arvo/lib/s3-json.hoon new file mode 100644 index 000000000..a38ff2ecf --- /dev/null +++ b/pkg/arvo/lib/s3-json.hoon @@ -0,0 +1,22 @@ +/- *s3 +|% +++ json-to-action + |= =json + ^- action + |^ (parse-json json) + ++ parse-json (of:dejs:format [%set-api-key so:dejs:format]~) + -- +:: +++ update-to-json + |= upd=update + ^- json + %+ frond:enjs:format %s3-update + %- pairs:enjs:format + :~ ?- -.upd + %credentials + [%credentials (pairs:enjs:format [%api-key s+api-key.credentials.upd]~)] + %set-api-key + [%set-api-key (pairs:enjs:format [%api-key s+api-key.upd]~)] + == + == +-- diff --git a/pkg/arvo/mar/s3/action.hoon b/pkg/arvo/mar/s3/action.hoon new file mode 100644 index 000000000..950ec703d --- /dev/null +++ b/pkg/arvo/mar/s3/action.hoon @@ -0,0 +1,8 @@ +/+ *s3-json +|_ act=action +++ grab + |% + ++ noun action + ++ json |=(jon=^json (json-to-action jon)) + -- +-- diff --git a/pkg/arvo/mar/s3/update.hoon b/pkg/arvo/mar/s3/update.hoon new file mode 100644 index 000000000..afcdceb91 --- /dev/null +++ b/pkg/arvo/mar/s3/update.hoon @@ -0,0 +1,12 @@ +/+ *s3-json +|_ upd=update +++ grow + |% + ++ json (update-to-json upd) + -- +:: +++ grab + |% + ++ noun update + -- +-- diff --git a/pkg/arvo/sur/s3.hoon b/pkg/arvo/sur/s3.hoon new file mode 100644 index 000000000..4b90c1c7a --- /dev/null +++ b/pkg/arvo/sur/s3.hoon @@ -0,0 +1,14 @@ +|% ++$ credentials + $: api-key=@t + == +:: ++$ action + $% [%set-api-key api-key=@t] + == +:: ++$ update + $% [%credentials =credentials] + action + == +-- diff --git a/pkg/interface/groups/src/js/subscription.js b/pkg/interface/groups/src/js/subscription.js index 269fc2fe0..ce0e2af34 100644 --- a/pkg/interface/groups/src/js/subscription.js +++ b/pkg/interface/groups/src/js/subscription.js @@ -7,12 +7,13 @@ import urbitOb from 'urbit-ob'; export class Subscription { constructor() { - this.firstRoundSubscriptionComplete = false; + this.firstRoundComplete = false; + this.secondRoundComplete = false; } start() { if (api.authTokens) { - this.firstRoundSubscription(); + this.firstRound(); window.urb.setOnChannelError(this.onChannelError.bind(this)); } else { console.error("~~~ ERROR: Must set api.authTokens before operation ~~~"); @@ -22,7 +23,8 @@ export class Subscription { onChannelError(err) { console.error('event source error: ', err); console.log('initiating new channel'); - this.firstRoundSubscriptionComplete = false; + this.firstRoundComplete = false; + this.secondRoundComplete = false; setTimeout(2000, () => { store.handleEvent({ data: { clear : true} @@ -43,21 +45,28 @@ export class Subscription { }); } - firstRoundSubscription() { + firstRound() { this.subscribe('/primary', 'contact-view'); } - secondRoundSubscriptions() { - this.subscribe('/synced', 'contact-hook'); - this.subscribe('/primary', 'invite-view'); + secondRound() { this.subscribe('/all', 'group-store'); this.subscribe('/all', 'metadata-store'); } + thirdRound() { + this.subscribe('/synced', 'contact-hook'); + this.subscribe('/primary', 'invite-view'); + this.subscribe('/all', 's3-store'); + } + handleEvent(diff) { - if (!this.firstRoundSubscriptionComplete) { - this.firstRoundSubscriptionComplete = true; - this.secondRoundSubscriptions(); + if (!this.firstRoundComplete) { + this.firstRoundComplete = true; + this.secondRound(); + } else if (!this.secondRoundComplete) { + this.secondRoundComplete = true; + this.thirdRound(); } store.handleEvent(diff); } From ab3a759ce2d3234c4031944a2489817596c3fc04 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 17:30:59 -0400 Subject: [PATCH 04/35] s3-store: poke functionality, updated credentials, added generators --- pkg/arvo/app/s3-store.hoon | 12 ++++- pkg/arvo/gen/s3-store/set-access-key-id.hoon | 10 ++++ pkg/arvo/gen/s3-store/set-api-key.hoon | 10 ++++ pkg/arvo/gen/s3-store/set-endpoint.hoon | 10 ++++ .../gen/s3-store/set-secret-access-key.hoon | 10 ++++ pkg/arvo/lib/s3-json.hoon | 21 ++++++-- pkg/arvo/sur/s3.hoon | 8 ++- pkg/interface/groups/src/js/lib/s3.js | 51 +++++++++++++++++++ 8 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 pkg/arvo/gen/s3-store/set-access-key-id.hoon create mode 100644 pkg/arvo/gen/s3-store/set-api-key.hoon create mode 100644 pkg/arvo/gen/s3-store/set-endpoint.hoon create mode 100644 pkg/arvo/gen/s3-store/set-secret-access-key.hoon create mode 100644 pkg/interface/groups/src/js/lib/s3.js diff --git a/pkg/arvo/app/s3-store.hoon b/pkg/arvo/app/s3-store.hoon index 8562686a7..589ab0387 100644 --- a/pkg/arvo/app/s3-store.hoon +++ b/pkg/arvo/app/s3-store.hoon @@ -42,7 +42,17 @@ ++ poke-action |= act=action ^- (quip card _state) - [~ state] + :- [%give %fact [/all]~ %s3-update !>(act)]~ + ?- -.act + %set-endpoint + state(endpoint.credentials endpoint.act) + :: + %set-access-key-id + state(access-key-id.credentials access-key-id.act) + :: + %set-secret-access-key + state(secret-access-key.credentials secret-access-key.act) + == -- :: ++ on-watch diff --git a/pkg/arvo/gen/s3-store/set-access-key-id.hoon b/pkg/arvo/gen/s3-store/set-access-key-id.hoon new file mode 100644 index 000000000..337912d66 --- /dev/null +++ b/pkg/arvo/gen/s3-store/set-access-key-id.hoon @@ -0,0 +1,10 @@ +:: s3-store|set-access-key-id: set S3 access key ID +:: +/- *s3 +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[access-key-id=@t ~] ~] + == +:- %s3-action +^- action +[%set-access-key-id access-key-id] diff --git a/pkg/arvo/gen/s3-store/set-api-key.hoon b/pkg/arvo/gen/s3-store/set-api-key.hoon new file mode 100644 index 000000000..b12c000c4 --- /dev/null +++ b/pkg/arvo/gen/s3-store/set-api-key.hoon @@ -0,0 +1,10 @@ +:: s3-store|set-api-key: set S3 bucket api-key +:: +/- *s3 +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[api-key=@t ~] ~] + == +:- %s3-action +^- action +[%set-api-key api-key] diff --git a/pkg/arvo/gen/s3-store/set-endpoint.hoon b/pkg/arvo/gen/s3-store/set-endpoint.hoon new file mode 100644 index 000000000..1635a6980 --- /dev/null +++ b/pkg/arvo/gen/s3-store/set-endpoint.hoon @@ -0,0 +1,10 @@ +:: s3-store|set-endpoint: set S3 endpoint +:: +/- *s3 +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[endpoint=@t ~] ~] + == +:- %s3-action +^- action +[%set-endpoint endpoint] diff --git a/pkg/arvo/gen/s3-store/set-secret-access-key.hoon b/pkg/arvo/gen/s3-store/set-secret-access-key.hoon new file mode 100644 index 000000000..d86bfe6d3 --- /dev/null +++ b/pkg/arvo/gen/s3-store/set-secret-access-key.hoon @@ -0,0 +1,10 @@ +:: s3-store|set-secret-access-key: set S3 secret access key +:: +/- *s3 +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[secret-access-key=@t ~] ~] + == +:- %s3-action +^- action +[%set-secret-access-key secret-access-key] diff --git a/pkg/arvo/lib/s3-json.hoon b/pkg/arvo/lib/s3-json.hoon index a38ff2ecf..48bbfe11f 100644 --- a/pkg/arvo/lib/s3-json.hoon +++ b/pkg/arvo/lib/s3-json.hoon @@ -4,7 +4,12 @@ |= =json ^- action |^ (parse-json json) - ++ parse-json (of:dejs:format [%set-api-key so:dejs:format]~) + ++ parse-json + %- of:dejs:format + :~ [%set-endoint so:dejs:format] + [%set-access-key-id so:dejs:format] + [%set-secret-access-key so:dejs:format] + == -- :: ++ update-to-json @@ -13,10 +18,18 @@ %+ frond:enjs:format %s3-update %- pairs:enjs:format :~ ?- -.upd + %set-endpoint [%set-endpoint s+endpoint.upd] + %set-access-key-id [%set-access-key-id s+access-key-id.upd] + %set-secret-access-key + [%set-secret-access-key s+secret-access-key.upd] + :: %credentials - [%credentials (pairs:enjs:format [%api-key s+api-key.credentials.upd]~)] - %set-api-key - [%set-api-key (pairs:enjs:format [%api-key s+api-key.upd]~)] + :- %credentials + %- pairs:enjs:format + :~ [%endpoint s+endpoint.credentials.upd] + [%access-key-id s+access-key-id.credentials.upd] + [%secret-access-key s+secret-access-key.credentials.upd] + == == == -- diff --git a/pkg/arvo/sur/s3.hoon b/pkg/arvo/sur/s3.hoon index 4b90c1c7a..9178cd6b6 100644 --- a/pkg/arvo/sur/s3.hoon +++ b/pkg/arvo/sur/s3.hoon @@ -1,10 +1,14 @@ |% +$ credentials - $: api-key=@t + $: endpoint=@t + access-key-id=@t + secret-access-key=@t == :: +$ action - $% [%set-api-key api-key=@t] + $% [%set-endpoint endpoint=@t] + [%set-access-key-id access-key-id=@t] + [%set-secret-access-key secret-access-key=@t] == :: +$ update diff --git a/pkg/interface/groups/src/js/lib/s3.js b/pkg/interface/groups/src/js/lib/s3.js new file mode 100644 index 000000000..a6493e02c --- /dev/null +++ b/pkg/interface/groups/src/js/lib/s3.js @@ -0,0 +1,51 @@ +const AWS = require('aws-sdk') + +export function configureClient() { + // Configure client for use with Spaces + const spacesEndpoint = new AWS.Endpoint('nyc3.digitaloceanspaces.com'); + return new AWS.S3({ + endpoint: spacesEndpoint, + credentials: new AWS.Credentials({ + accessKeyId: 'ACCESS_KEY', + secretAccessKey: 'SECRET_KEY' + }) + }); +} + +export function createBucket() { + // Create a new Space + var params = { + Bucket: "my-new-space-with-a-unique-name" + }; + + s3.createBucket(params, function(err, data) { + if (err) console.log(err, err.stack); + else console.log(data); + }); +} + +export function listBuckets() { + // List all Spaces in the region + s3.listBuckets({}, function(err, data) { + if (err) console.log(err, err.stack); + else { + data['Buckets'].forEach(function(space) { + console.log(space['Name']); + })}; + }); +} + +export function putObject(body, bucket, key) { + // Add a file to a Space + var params = { + Body: "The contents of the file", + Bucket: "my-new-space-with-a-unique-name", + Key: "file.ext", + }; + + s3.putObject(params, function(err, data) { + if (err) console.log(err, err.stack); + else console.log(data); + }); +} + From 38f65474e3912302183e636a3951e4bc2cc76fb8 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 18:07:05 -0400 Subject: [PATCH 05/35] s3: made S3 upload API coherent --- pkg/interface/groups/src/js/lib/s3.js | 130 +++++++++++++++++--------- 1 file changed, 84 insertions(+), 46 deletions(-) diff --git a/pkg/interface/groups/src/js/lib/s3.js b/pkg/interface/groups/src/js/lib/s3.js index a6493e02c..f1dd1f5f8 100644 --- a/pkg/interface/groups/src/js/lib/s3.js +++ b/pkg/interface/groups/src/js/lib/s3.js @@ -1,51 +1,89 @@ const AWS = require('aws-sdk') -export function configureClient() { - // Configure client for use with Spaces - const spacesEndpoint = new AWS.Endpoint('nyc3.digitaloceanspaces.com'); - return new AWS.S3({ - endpoint: spacesEndpoint, - credentials: new AWS.Credentials({ - accessKeyId: 'ACCESS_KEY', - secretAccessKey: 'SECRET_KEY' - }) - }); +class S3 { + constructor() { + this.endpoint = new AWS.Endpoint(""); + this.accessKeyId = ""; + this.secretAccesskey = ""; + + this.s3 = null; + } + + setCredentials(endpoint, accessKeyId, secretAccessKey) { + this.endpoint = new AWS.Endpoint(endpoint); + this.accessKeyId = accessKeyId; + this.secretAccessKey = secretAccessKey; + + this.s3 = + new AWS.S3({ + endpoint: this.endpoint, + credentials: new AWS.Credentials({ + accessKeyId: this.accessKeyId, + secretAccessKey: this.secretAccessKey + }) + }); + } + + createBucket(name) { + let params = { + Bucket: name, + ACL: "public-read" + }; + + return new Promise((resolve, reject) => { + if (!this.s3) { + reject({ error: 'S3 not initialized!' }); + return; + } + this.s3.createBucket(params, (error, data) => { + if (error) { + reject({ error }); + } else { + resolve({ data }); + } + }); + }); + } + + listBuckets() { + return new Promise((resolve, reject) => { + if (!this.s3) { + reject({ error: 'S3 not initialized!' }); + return; + } + this.s3.listBuckets({}, (error, data) => { + if (error) { + reject({ error }); + } else { + resolve({ data }); + } + }); + }); + } + + putObject(body, bucket, filename) { + let params = { + Body: body, + Bucket: bucket, + Key: filename, + }; + + return new Promise((resolve, reject) => { + if (!this.s3) { + reject({ error: 'S3 not initialized!' }); + return; + } + this.s3.putObject(params, (error, data) => { + if (error) { + reject({ error }); + } else { + resolve({ data }); + } + }); + }); + + } } -export function createBucket() { - // Create a new Space - var params = { - Bucket: "my-new-space-with-a-unique-name" - }; - - s3.createBucket(params, function(err, data) { - if (err) console.log(err, err.stack); - else console.log(data); - }); -} - -export function listBuckets() { - // List all Spaces in the region - s3.listBuckets({}, function(err, data) { - if (err) console.log(err, err.stack); - else { - data['Buckets'].forEach(function(space) { - console.log(space['Name']); - })}; - }); -} - -export function putObject(body, bucket, key) { - // Add a file to a Space - var params = { - Body: "The contents of the file", - Bucket: "my-new-space-with-a-unique-name", - Key: "file.ext", - }; - - s3.putObject(params, function(err, data) { - if (err) console.log(err, err.stack); - else console.log(data); - }); -} +export let s3 = new S3(); From 877ae661698cac93bc19ca039ea8fe347064847b Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 18:13:29 -0400 Subject: [PATCH 06/35] s3.js: switched from putObject to upload for better handling of large files --- pkg/interface/groups/src/js/lib/s3.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pkg/interface/groups/src/js/lib/s3.js b/pkg/interface/groups/src/js/lib/s3.js index f1dd1f5f8..327f6a079 100644 --- a/pkg/interface/groups/src/js/lib/s3.js +++ b/pkg/interface/groups/src/js/lib/s3.js @@ -61,19 +61,18 @@ class S3 { }); } - putObject(body, bucket, filename) { + upload(bucket, filename, buffer) { let params = { - Body: body, - Bucket: bucket, - Key: filename, + Bucket: bucket, + Key: filename, + Body: buffer }; - return new Promise((resolve, reject) => { if (!this.s3) { reject({ error: 'S3 not initialized!' }); return; } - this.s3.putObject(params, (error, data) => { + this.s3.upload(params, (error, data) => { if (error) { reject({ error }); } else { @@ -81,7 +80,6 @@ class S3 { } }); }); - } } From bec650957c82453c88bf27266f09ef2863e63bb7 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 19:33:55 -0400 Subject: [PATCH 07/35] s3: added configuration settings for setting current bucket and adding / removing buckets from list --- pkg/arvo/app/s3-store.hoon | 27 +++++++++++++++++++++------ pkg/arvo/lib/s3-json.hoon | 33 ++++++++++++++++++++++++--------- pkg/arvo/sur/s3.hoon | 9 +++++++++ 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/pkg/arvo/app/s3-store.hoon b/pkg/arvo/app/s3-store.hoon index 589ab0387..c9262ad9d 100644 --- a/pkg/arvo/app/s3-store.hoon +++ b/pkg/arvo/app/s3-store.hoon @@ -1,5 +1,5 @@ /- *s3 -/+ default-agent, verb, dbug +/+ s3-json, default-agent, verb, dbug ~% %s3-top ..is ~ |% +$ card card:agent:gall @@ -7,7 +7,7 @@ $% state-zero == :: -+$ state-zero [%0 =credentials] ++$ state-zero [%0 =credentials =configuration] -- :: =| state-zero @@ -52,6 +52,18 @@ :: %set-secret-access-key state(secret-access-key.credentials secret-access-key.act) + :: + %set-current-bucket + %_ state + current-bucket.configuration bucket.act + buckets.configuration (~(put in buckets.configuration) bucket.act) + == + :: + %add-bucket + state(buckets.configuration (~(put in buckets.configuration) bucket.act)) + :: + %remove-bucket + state(buckets.configuration (~(del in buckets.configuration) bucket.act)) == -- :: @@ -62,15 +74,18 @@ |^ ?> (team:title our.bowl src.bowl) =/ cards=(list card) - ?+ path (on-watch:def path) - [%all ~] (give %s3-update !>([%credentials credentials])) + ?+ path (on-watch:def path) + [%all ~] + :~ (give %s3-update !>([%credentials credentials])) + (give %s3-update !>([%configuration configuration])) + == == [cards this] :: ++ give |= =cage - ^- (list card) - [%give %fact ~ cage]~ + ^- card + [%give %fact ~ cage] -- :: ++ on-leave on-leave:def diff --git a/pkg/arvo/lib/s3-json.hoon b/pkg/arvo/lib/s3-json.hoon index 48bbfe11f..4df2a11d6 100644 --- a/pkg/arvo/lib/s3-json.hoon +++ b/pkg/arvo/lib/s3-json.hoon @@ -3,33 +3,48 @@ ++ json-to-action |= =json ^- action + =, format |^ (parse-json json) ++ parse-json - %- of:dejs:format - :~ [%set-endoint so:dejs:format] - [%set-access-key-id so:dejs:format] - [%set-secret-access-key so:dejs:format] + %- of:dejs + :~ [%set-endpoint so:dejs] + [%set-access-key-id so:dejs] + [%set-secret-access-key so:dejs] + [%add-bucket so:dejs] + [%remove-bucket so:dejs] + [%set-current-bucket so:dejs] == -- :: ++ update-to-json |= upd=update ^- json - %+ frond:enjs:format %s3-update - %- pairs:enjs:format + =, format + %+ frond:enjs %s3-update + %- pairs:enjs :~ ?- -.upd - %set-endpoint [%set-endpoint s+endpoint.upd] - %set-access-key-id [%set-access-key-id s+access-key-id.upd] + %set-current-bucket [%set-current-bucket s+bucket.upd] + %add-bucket [%add-bucket s+bucket.upd] + %remove-bucket [%remove-bucket s+bucket.upd] + %set-endpoint [%set-endpoint s+endpoint.upd] + %set-access-key-id [%set-access-key-id s+access-key-id.upd] %set-secret-access-key [%set-secret-access-key s+secret-access-key.upd] :: %credentials :- %credentials - %- pairs:enjs:format + %- pairs:enjs :~ [%endpoint s+endpoint.credentials.upd] [%access-key-id s+access-key-id.credentials.upd] [%secret-access-key s+secret-access-key.credentials.upd] == + :: + %configuration + :- %configuration + %- pairs:enjs + :~ [%buckets a+(turn ~(tap in buckets.configuration.upd) |=(a=@t s+a))] + [%current-bucket s+current-bucket.configuration.upd] + == == == -- diff --git a/pkg/arvo/sur/s3.hoon b/pkg/arvo/sur/s3.hoon index 9178cd6b6..4f0ca04cb 100644 --- a/pkg/arvo/sur/s3.hoon +++ b/pkg/arvo/sur/s3.hoon @@ -5,14 +5,23 @@ secret-access-key=@t == :: ++$ configuration + $: buckets=(set @t) + current-bucket=@t + == +:: +$ action $% [%set-endpoint endpoint=@t] [%set-access-key-id access-key-id=@t] [%set-secret-access-key secret-access-key=@t] + [%add-bucket bucket=@t] + [%remove-bucket bucket=@t] + [%set-current-bucket bucket=@t] == :: +$ update $% [%credentials =credentials] + [%configuration =configuration] action == -- From 285f0bd5e3120ef5d77aa776099dc0841e0761e5 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 19:49:14 -0400 Subject: [PATCH 08/35] s3: integrated with store and reducers --- pkg/arvo/lib/s3-json.hoon | 18 ++--- pkg/interface/groups/src/js/reducers/s3.js | 81 ++++++++++++++++++++++ pkg/interface/groups/src/js/store.js | 4 ++ 3 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 pkg/interface/groups/src/js/reducers/s3.js diff --git a/pkg/arvo/lib/s3-json.hoon b/pkg/arvo/lib/s3-json.hoon index 4df2a11d6..e4a531daa 100644 --- a/pkg/arvo/lib/s3-json.hoon +++ b/pkg/arvo/lib/s3-json.hoon @@ -23,27 +23,27 @@ %+ frond:enjs %s3-update %- pairs:enjs :~ ?- -.upd - %set-current-bucket [%set-current-bucket s+bucket.upd] - %add-bucket [%add-bucket s+bucket.upd] - %remove-bucket [%remove-bucket s+bucket.upd] - %set-endpoint [%set-endpoint s+endpoint.upd] - %set-access-key-id [%set-access-key-id s+access-key-id.upd] + %set-current-bucket [%'setCurrentBucket' s+bucket.upd] + %add-bucket [%'addBucket' s+bucket.upd] + %remove-bucket [%'removeBucket' s+bucket.upd] + %set-endpoint [%'setEndpoint' s+endpoint.upd] + %set-access-key-id [%'setAccessKeyId' s+access-key-id.upd] %set-secret-access-key - [%set-secret-access-key s+secret-access-key.upd] + [%'setSecretAccessKey' s+secret-access-key.upd] :: %credentials :- %credentials %- pairs:enjs :~ [%endpoint s+endpoint.credentials.upd] - [%access-key-id s+access-key-id.credentials.upd] - [%secret-access-key s+secret-access-key.credentials.upd] + [%'accessKeyId' s+access-key-id.credentials.upd] + [%'secretAccessKey' s+secret-access-key.credentials.upd] == :: %configuration :- %configuration %- pairs:enjs :~ [%buckets a+(turn ~(tap in buckets.configuration.upd) |=(a=@t s+a))] - [%current-bucket s+current-bucket.configuration.upd] + [%'currentBucket' s+current-bucket.configuration.upd] == == == diff --git a/pkg/interface/groups/src/js/reducers/s3.js b/pkg/interface/groups/src/js/reducers/s3.js new file mode 100644 index 000000000..2d476bb1d --- /dev/null +++ b/pkg/interface/groups/src/js/reducers/s3.js @@ -0,0 +1,81 @@ +import _ from 'lodash'; + + +export class S3Reducer { + reduce(json, state) { + let data = _.get(json, 's3-update', false); + if (data) { + this.credentials(data, state); + this.configuration(data, state); + this.currentBucket(data, state); + this.addBucket(data, state); + this.removeBucket(data, state); + this.endpoint(data, state); + this.accessKeyId(data, state); + this.secretAccessKey(data, state); + } + } + + credentials(json, state) { + let data = _.get(json, 'credentials', false); + if (data) { + state.s3.credentials = data; + } + } + + configuration(json, state) { + let data = _.get(json, 'configuration', false); + if (data) { + state.s3.configuration = { + buckets: new Set(data.buckets), + currentBucket: data.currentBucket + }; + } + } + + currentBucket(json, state) { + let data = _.get(json, 'setCurrentBucket', false); + if (data) { + state.s3.configuration.currentBucket = data; + } + } + + addBucket(json, state) { + let data = _.get(json, 'addBucket', false); + if (data) { + state.s3.configuration.buckets = + state.s3.configuration.buckets.add(data); + } + } + + removeBucket(json, state) { + let data = _.get(json, 'removeBucket', false); + if (data) { + state.s3.configuration.buckets = + state.s3.configuration.buckets.delete(data); + } + } + + endpoint(json, state) { + let data = _.get(json, 'setEndpoint', false); + if (data) { + state.s3.credentials.endpoint = data; + } + } + + accessKeyId(json, state) { + let data = _.get(json, 'setAccessKeyId', false); + if (data) { + state.s3.credentials.accessKeyId = data; + } + } + + secretAccessKey(json, state) { + let data = _.get(json, 'setSecretAccessKey', false); + if (data) { + state.s3.credentials.secretAccessKey = data; + } + } + +} + diff --git a/pkg/interface/groups/src/js/store.js b/pkg/interface/groups/src/js/store.js index 47ac07316..ce52fb0b0 100644 --- a/pkg/interface/groups/src/js/store.js +++ b/pkg/interface/groups/src/js/store.js @@ -4,6 +4,7 @@ import { GroupUpdateReducer } from '/reducers/group-update'; import { InviteUpdateReducer } from '/reducers/invite-update'; import { PermissionUpdateReducer } from '/reducers/permission-update'; import { MetadataReducer } from '/reducers/metadata-update.js'; +import { S3Reducer } from '/reducers/s3.js'; import { LocalReducer } from '/reducers/local.js'; @@ -17,6 +18,7 @@ class Store { this.contactUpdateReducer = new ContactUpdateReducer(); this.inviteUpdateReducer = new InviteUpdateReducer(); this.metadataReducer = new MetadataReducer(); + this.s3Reducer = new S3Reducer(); this.localReducer = new LocalReducer(); this.setState = () => {}; } @@ -28,6 +30,7 @@ class Store { associations: {}, permissions: {}, invites: {}, + s3: {}, selectedGroups: [] }; } @@ -51,6 +54,7 @@ class Store { this.contactUpdateReducer.reduce(json, this.state); this.inviteUpdateReducer.reduce(json, this.state); this.metadataReducer.reduce(json, this.state); + this.s3Reducer.reduce(json, this.state); this.localReducer.reduce(json, this.state); this.setState(this.state); From 9c6cb61d619c347fba7a41041c24c4e64709c70a Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 20:47:01 -0400 Subject: [PATCH 09/35] s3: got tests passing and added the rest of the generators --- pkg/arvo/gen/s3-store/add-bucket.hoon | 10 ++++++++++ pkg/arvo/gen/s3-store/remove-bucket.hoon | 10 ++++++++++ pkg/arvo/gen/s3-store/set-api-key.hoon | 10 ---------- pkg/arvo/gen/s3-store/set-current-bucket.hoon | 10 ++++++++++ 4 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 pkg/arvo/gen/s3-store/add-bucket.hoon create mode 100644 pkg/arvo/gen/s3-store/remove-bucket.hoon delete mode 100644 pkg/arvo/gen/s3-store/set-api-key.hoon create mode 100644 pkg/arvo/gen/s3-store/set-current-bucket.hoon diff --git a/pkg/arvo/gen/s3-store/add-bucket.hoon b/pkg/arvo/gen/s3-store/add-bucket.hoon new file mode 100644 index 000000000..e585fe262 --- /dev/null +++ b/pkg/arvo/gen/s3-store/add-bucket.hoon @@ -0,0 +1,10 @@ +:: s3-store|add-bucket: add new bucket to S3 store +:: +/- *s3 +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[bucket=@t ~] ~] + == +:- %s3-action +^- action +[%add-bucket bucket] diff --git a/pkg/arvo/gen/s3-store/remove-bucket.hoon b/pkg/arvo/gen/s3-store/remove-bucket.hoon new file mode 100644 index 000000000..845dbcf66 --- /dev/null +++ b/pkg/arvo/gen/s3-store/remove-bucket.hoon @@ -0,0 +1,10 @@ +:: s3-store|remove-bucket: remove bucket from S3 store +:: +/- *s3 +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[bucket=@t ~] ~] + == +:- %s3-action +^- action +[%remove-bucket bucket] diff --git a/pkg/arvo/gen/s3-store/set-api-key.hoon b/pkg/arvo/gen/s3-store/set-api-key.hoon deleted file mode 100644 index b12c000c4..000000000 --- a/pkg/arvo/gen/s3-store/set-api-key.hoon +++ /dev/null @@ -1,10 +0,0 @@ -:: s3-store|set-api-key: set S3 bucket api-key -:: -/- *s3 -:- %say -|= $: [now=@da eny=@uvJ =beak] - [[api-key=@t ~] ~] - == -:- %s3-action -^- action -[%set-api-key api-key] diff --git a/pkg/arvo/gen/s3-store/set-current-bucket.hoon b/pkg/arvo/gen/s3-store/set-current-bucket.hoon new file mode 100644 index 000000000..15b93d665 --- /dev/null +++ b/pkg/arvo/gen/s3-store/set-current-bucket.hoon @@ -0,0 +1,10 @@ +:: s3-store|set-current-bucket: set current bucket for S3 +:: +/- *s3 +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[bucket=@t ~] ~] + == +:- %s3-action +^- action +[%set-current-bucket bucket] From ff313fb720a17e218eb60b95471121e187a2ecd7 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 22:59:39 -0400 Subject: [PATCH 10/35] groups-js: initial s3 work --- pkg/arvo/app/contacts/index.html | 1 + .../src/js/components/lib/contact-card.js | 2 ++ .../groups/src/js/components/lib/s3-upload.js | 30 +++++++++++++++++++ .../groups/src/js/components/root.js | 5 ++++ pkg/interface/groups/src/js/lib/s3.js | 21 +++++++------ 5 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 pkg/interface/groups/src/js/components/lib/s3-upload.js diff --git a/pkg/arvo/app/contacts/index.html b/pkg/arvo/app/contacts/index.html index 04fdf3f0a..56039233e 100644 --- a/pkg/arvo/app/contacts/index.html +++ b/pkg/arvo/app/contacts/index.html @@ -13,5 +13,6 @@ + diff --git a/pkg/interface/groups/src/js/components/lib/contact-card.js b/pkg/interface/groups/src/js/components/lib/contact-card.js index 67c9dea2d..fd3c227ef 100644 --- a/pkg/interface/groups/src/js/components/lib/contact-card.js +++ b/pkg/interface/groups/src/js/components/lib/contact-card.js @@ -6,6 +6,7 @@ import { Link } from 'react-router-dom'; import { EditElement } from '/components/lib/edit-element'; import { Spinner } from './icons/icon-spinner'; import { uxToHex } from '/lib/util'; +import { S3Upload } from '/components/lib/s3-upload'; export class ContactCard extends Component { constructor(props) { @@ -424,6 +425,7 @@ export class ContactCard extends Component {
{avatar} +
; + } +} + diff --git a/pkg/interface/groups/src/js/components/root.js b/pkg/interface/groups/src/js/components/root.js index 010868e35..18b27e140 100644 --- a/pkg/interface/groups/src/js/components/root.js +++ b/pkg/interface/groups/src/js/components/root.js @@ -33,7 +33,9 @@ export class Root extends Component { let defaultContacts = (!!state.contacts && '/~/default' in state.contacts) ? state.contacts['/~/default'] : {}; + let groups = !!state.groups ? state.groups : {}; + let s3Credentials = !!state.s3 ? state.s3 : {}; let invites = (!!state.invites && '/contacts' in state.invites) ? @@ -211,6 +213,7 @@ export class Root extends Component { ship={window.ship} share={true} rootIdentity={rootIdentity} + s3Credentials={s3Credentials} /> ); @@ -259,6 +262,7 @@ export class Root extends Component { path={groupPath} ship={props.match.params.contact} rootIdentity={rootIdentity} + s3Credentials={s3Credentials} /> ); @@ -283,6 +287,7 @@ export class Root extends Component { path="/~/default" contact={me} ship={window.ship} + s3Credentials={s3Credentials} /> ); diff --git a/pkg/interface/groups/src/js/lib/s3.js b/pkg/interface/groups/src/js/lib/s3.js index 327f6a079..0051dab77 100644 --- a/pkg/interface/groups/src/js/lib/s3.js +++ b/pkg/interface/groups/src/js/lib/s3.js @@ -1,23 +1,24 @@ -const AWS = require('aws-sdk') - -class S3 { +export default class S3Client { constructor() { - this.endpoint = new AWS.Endpoint(""); + this.s3 = null; + this.AWS = window.AWS; + + this.endpoint = new this.AWS.Endpoint(""); this.accessKeyId = ""; this.secretAccesskey = ""; - - this.s3 = null; } setCredentials(endpoint, accessKeyId, secretAccessKey) { - this.endpoint = new AWS.Endpoint(endpoint); + this.AWS = window.AWS; + + this.endpoint = new this.AWS.Endpoint(endpoint); this.accessKeyId = accessKeyId; this.secretAccessKey = secretAccessKey; this.s3 = - new AWS.S3({ + new this.AWS.S3({ endpoint: this.endpoint, - credentials: new AWS.Credentials({ + credentials: new this.AWS.Credentials({ accessKeyId: this.accessKeyId, secretAccessKey: this.secretAccessKey }) @@ -83,5 +84,3 @@ class S3 { } } -export let s3 = new S3(); - From ce1f7c957b8831b1aafed1367d6cd535ed16fd9b Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Thu, 23 Apr 2020 23:55:44 -0400 Subject: [PATCH 11/35] s3-js: got upload working successfully, required CORS * and Headers * and public-read ACL --- pkg/interface/groups/src/js/lib/s3.js | 40 ++------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/pkg/interface/groups/src/js/lib/s3.js b/pkg/interface/groups/src/js/lib/s3.js index 0051dab77..8070a87bc 100644 --- a/pkg/interface/groups/src/js/lib/s3.js +++ b/pkg/interface/groups/src/js/lib/s3.js @@ -25,48 +25,12 @@ export default class S3Client { }); } - createBucket(name) { - let params = { - Bucket: name, - ACL: "public-read" - }; - - return new Promise((resolve, reject) => { - if (!this.s3) { - reject({ error: 'S3 not initialized!' }); - return; - } - this.s3.createBucket(params, (error, data) => { - if (error) { - reject({ error }); - } else { - resolve({ data }); - } - }); - }); - } - - listBuckets() { - return new Promise((resolve, reject) => { - if (!this.s3) { - reject({ error: 'S3 not initialized!' }); - return; - } - this.s3.listBuckets({}, (error, data) => { - if (error) { - reject({ error }); - } else { - resolve({ data }); - } - }); - }); - } - upload(bucket, filename, buffer) { let params = { Bucket: bucket, Key: filename, - Body: buffer + Body: buffer, + ACL: 'public-read' }; return new Promise((resolve, reject) => { if (!this.s3) { From 2e3947e3c0a9c729f2e5796196f2b3ee0ffe457c Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Sat, 25 Apr 2020 02:40:15 +1000 Subject: [PATCH 12/35] drum: account for app dependencies on boot Changes drum's boot order to be deterministic regardless of the ship you're on. Fixes #2681 --- pkg/arvo/lib/hood/drum.hoon | 65 ++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index c76094338..7399ae2b4 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -155,6 +155,7 @@ =+ (~(gut by bin) ost *source) =* dev - |_ {moz/(list card:agent:gall) biz/(list dill-blit:dill)} ++* this . ++ diff-sole-effect-phat :: app event |= {way/wire fec/sole-effect} =< se-abet =< se-view @@ -329,19 +330,59 @@ [%give %fact ~[/drum] %dill-blit !>(dill-blit)] :: ++ se-adit :: update servers - ^+ . - :: ensure dojo connects after talk - =* dojo-on-top |=([a=* b=*] |(=(%dojo a) &(!=(%dojo b) (aor a b)))) - %+ roll (sort ~(tap in ray) dojo-on-top) - =< .(con +>) - |: $:{wel/well:gall con/_..se-adit} ^+ con - =. +>.$ con - =+ hig=(~(get by fur) q.wel) - ?: &(?=(^ hig) |(?=(~ u.hig) =(p.wel syd.u.u.hig))) +>.$ - =. +>.$ (se-text "activated app {(trip p.wel)}/{(trip q.wel)}") - %- se-emit(fur (~(put by fur) q.wel ~)) + ^+ this + |^ + =/ servers=(list well:gall) + (sort ~(tap in ray) sort-by-priorities) + |- + ?~ servers + this + =/ wel=well:gall + i.servers =/ =wire [%drum p.wel q.wel ~] - [%pass wire %arvo %g %conf [our.hid q.wel] our.hid p.wel] + =/ hig=(unit (unit server)) + (~(get by fur) q.wel) + ?: &(?=(^ hig) |(?=(~ u.hig) =(p.wel syd.u.u.hig))) + this + =. fur + (~(put by fur) q.wel ~) + =. this + (se-text "activated app {(trip p.wel)}/{(trip q.wel)}") + =. this + %- se-emit + [%pass wire %arvo %g %conf [our.hid q.wel] our.hid p.wel] + $(servers t.servers) + :: + ++ priorities + ^- (list (set @)) + :~ + (sy ~[%dojo]) :: ensure dojo connects first + %- sy + :~ %permission-store + %chat-store + %contact-store + %group-store + %link-store + %invite-store + %metadata-store + == + (sy ~[%chat-hook]) :: ensure chat-cli can sub to invites + == + ++ sort-by-priorities + =/ priorities priorities + |= [[desk a=term] [desk b=term]] + ^- ? + ?~ priorities + (aor a b) + =* priority i.priorities + ?: &((~(has in priority) a) (~(has in priority) b)) + (aor a b) + ?: (~(has in priority) a) + %.y + ?: (~(has in priority) b) + %.n + $(priorities t.priorities) + -- :: ++ se-adze :: update connections ^+ . From 37cd90a42bde4cd3d0723ab3b0fd6a32b225866c Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Sat, 25 Apr 2020 07:21:41 +1000 Subject: [PATCH 13/35] drum: sort cli connections Sorts cli connections so that the user always boots into %dojo regardless of their @p Fixes: #2248 --- pkg/arvo/lib/hood/drum.hoon | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 7399ae2b4..b1cedb0c9 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -386,7 +386,10 @@ :: ++ se-adze :: update connections ^+ . - %+ roll ~(tap in eel) + %+ roll + %+ sort + ~(tap in eel) + |=([[@ a=term] [@ b=term]] (aor a b)) =< .(con +>) |: $:{gil/gill:gall con/_.} ^+ con =. +>.$ con From 7beb57555154666e9494180db8595e87c5eeffc8 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Mon, 27 Apr 2020 14:47:55 -0400 Subject: [PATCH 14/35] groups: fixed error states and visual styling around image upload --- pkg/arvo/app/contacts/img/ImageUpload.png | Bin 0 -> 865 bytes .../src/js/components/lib/contact-card.js | 73 +++++++++------- .../src/js/components/lib/edit-element.js | 4 +- .../groups/src/js/components/lib/s3-upload.js | 80 ++++++++++++++++-- .../groups/src/js/components/root.js | 8 +- pkg/interface/groups/src/js/lib/s3.js | 19 +++-- 6 files changed, 135 insertions(+), 49 deletions(-) create mode 100644 pkg/arvo/app/contacts/img/ImageUpload.png diff --git a/pkg/arvo/app/contacts/img/ImageUpload.png b/pkg/arvo/app/contacts/img/ImageUpload.png new file mode 100644 index 0000000000000000000000000000000000000000..42656588777784f95a59315c0667928df91caf8d GIT binary patch literal 865 zcmV-n1D^beP)5QZP$qyRdII>?nk2XP5>kaTdq3hb-E*TJO&=PIyM z0q(%pLGnW|185;eT7fwGo!K#iVYU0}Ygb4sT;#y_>Nji1QgN>21iVz&A~IkL{Qcyz zMX1mWI3{4+RC4T+a0@jrwFCf+@Mj6EtN)hV|H1mO#`@ItGY8n=I=^(MC1kiH>;Mj( zo9mejoC0gyvA|*F>s;1N0E64woqq9|ky;5;bu(>pFz+d2NuoI)hOGk1;<|>0*0JVJ)jCEpb*~alZ~e3N(d%kOxAeNwOs`* z8-3z{vB6Smam76jXu^kp-y@zqdFY=MJ_Njvc=p9Ze;+dJ0KCVJLl+t`J$Ag=V>7-{ zv(MN;P|BaW-Tz6<+6TG2sT0umCH5N070Mri z5z160AS8K-UHdhn5isQZ0UOa3*l^bbloN_51pE;6T+qo3wV_Uc!R_-UpZvo}69vn0 z9y*{LdoCRof#|6M(0~1 z;4RSk#S(DAt}kd{Q3RCeCseI6z9=dV#Tod(?kV_#-G>l;f5B7)oUr=}PL+HxaCT>E z#O${l(#s4d83T5tw-8dpA)xP5v~R7ae&E6(pcHQUI{!GGA6_tYW|;@~;PJVC42>`NOTq00000NkvXXu0mjf{2P%c literal 0 HcmV?d00001 diff --git a/pkg/interface/groups/src/js/components/lib/contact-card.js b/pkg/interface/groups/src/js/components/lib/contact-card.js index fd3c227ef..ab34170e0 100644 --- a/pkg/interface/groups/src/js/components/lib/contact-card.js +++ b/pkg/interface/groups/src/js/components/lib/contact-card.js @@ -118,8 +118,7 @@ export class ContactCard extends Component { (state.avatarToSet === '') || ( Boolean(props.contact.avatar) && - 'url' in props.contact.avatar && - state.avatarToSet === props.contact.avatar.url + state.avatarToSet === props.contact.avatar ) ) { return false; @@ -130,6 +129,7 @@ export class ContactCard extends Component { awaiting: true, type: 'Saving to group' }, (() => { + console.log(state.avatarToSet); api.contactEdit(props.path, ship, { avatar: { url: state.avatarToSet @@ -305,7 +305,7 @@ export class ContactCard extends Component { email: props.rootIdentity.email, phone: props.rootIdentity.phone, website: props.rootIdentity.website, - avatar: { url: props.rootIdentity.avatar }, + avatar: !!props.rootIdentity.avatar ? { url: props.rootIdentity.avatar } : null, notes: props.rootIdentity.notes, color: uxToHex(props.rootIdentity.color) } : { @@ -313,7 +313,7 @@ export class ContactCard extends Component { email: props.contact.email, phone: props.contact.phone, website: props.contact.website, - avatar: { url: props.contact.avatar }, + avatar: !!props.contact.avatar ? { url: props.contact.avatar } : null, notes: props.contact.notes, color: props.contact.color }; @@ -364,6 +364,18 @@ export class ContactCard extends Component { })); } + uploadSuccess(url) { + this.setState({ + avatarToSet: url + }, () => { + this.setField('avatar'); + }); + } + + uploadError(error) { + // no-op for now + } + renderEditCard() { const { props, state } = this; // if this is our first edit in a new group, propagate from root identity @@ -395,37 +407,40 @@ export class ContactCard extends Component { const hasAvatar = 'avatar' in props.contact && props.contact.avatar !== null; + const s3Upload = (!props.share) ? ( + + + + ) : (); + const avatar = (hasAvatar) - ? - - this.setField('removeAvatar')} - onSaveClick={() => this.setField('avatar')} - showButtons={!props.share} - /> - - : - this.setField('removeAvatar')} - onSaveClick={() => this.setField('avatar')} - showButtons={!props.share} - /> - ; + ? + : ; return (
{avatar} - + + {s3Upload} + this.setField('removeAvatar')} + onSaveClick={() => this.setField('avatar')} + showButtons={!props.share} + /> + +

{props.title}