From b6e4566e61b49ae6a60e24aa911dcf1dd074edb1 Mon Sep 17 00:00:00 2001
From: Logan Allen
Date: Mon, 13 Apr 2020 17:37:51 -0400
Subject: [PATCH 1/8] contacts: fix group deletion and do some quality of life
fixes
---
pkg/arvo/app/contact-hook.hoon | 10 ++-
pkg/arvo/sur/contact-hook.hoon | 3 +
.../src/js/components/lib/contact-card.js | 1 +
pkg/interface/groups/src/js/subscription.js | 63 ++++++++++---------
4 files changed, 47 insertions(+), 30 deletions(-)
diff --git a/pkg/arvo/app/contact-hook.hoon b/pkg/arvo/app/contact-hook.hoon
index bf66c27cd..956f894b7 100644
--- a/pkg/arvo/app/contact-hook.hoon
+++ b/pkg/arvo/app/contact-hook.hoon
@@ -77,6 +77,7 @@
^- (quip card _this)
?+ path (on-watch:def path)
[%contacts *] [(watch-contacts:cc t.path) this]
+ [%synced *] [(watch-synced:cc t.path) this]
==
::
++ on-agent
@@ -202,6 +203,12 @@
!>([%contacts pax contacts])
== ==
::
+++ watch-synced
+ |= pax=path
+ ^- (list card)
+ ?> (team:title our.bol src.bol)
+ [%give %fact ~ %contact-hook-update !>([%initial synced])]~
+::
++ watch-ack
|= [wir=wire saw=(unit tang)]
^- (quip card _state)
@@ -353,7 +360,8 @@
|= =path
^- (quip card _state)
?. (~(has by synced) path)
- [~ state]
+ :_ state
+ [(contact-poke [%delete path])]~
:_ state(synced (~(del by synced) path))
:~ [%pass [%contacts path] %agent [our.bol %contact-store] %leave ~]
[(contact-poke [%delete path])]
diff --git a/pkg/arvo/sur/contact-hook.hoon b/pkg/arvo/sur/contact-hook.hoon
index 0b196e5dd..5926ec5a5 100644
--- a/pkg/arvo/sur/contact-hook.hoon
+++ b/pkg/arvo/sur/contact-hook.hoon
@@ -12,4 +12,7 @@
::
[%remove =path]
==
+::
++$ synced (map path ship)
++$ contact-hook-update [%initial =synced]
--
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 d02e5ddb4..dff7b4aa4 100644
--- a/pkg/interface/groups/src/js/components/lib/contact-card.js
+++ b/pkg/interface/groups/src/js/components/lib/contact-card.js
@@ -323,6 +323,7 @@ export class ContactCard extends Component {
this.setState({awaiting: false});
props.history.push(`/~groups${destination}`);
});
+ api.contactView.delete(props.path);
}))
}
diff --git a/pkg/interface/groups/src/js/subscription.js b/pkg/interface/groups/src/js/subscription.js
index 081c6c386..aa0d23730 100644
--- a/pkg/interface/groups/src/js/subscription.js
+++ b/pkg/interface/groups/src/js/subscription.js
@@ -5,48 +5,53 @@ import urbitOb from 'urbit-ob';
export class Subscription {
+
+ constructor() {
+ this.firstRoundSubscriptionComplete = false;
+ }
+
start() {
if (api.authTokens) {
- this.initializeContacts();
+ this.firstRoundSubscription();
} else {
console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
}
}
- initializeContacts() {
- api.bind('/primary', 'PUT', api.authTokens.ship, 'contact-view',
+ subscribe(path, app) {
+ api.bind(path, 'PUT', api.authTokens.ship, app,
this.handleEvent.bind(this),
- this.handleError.bind(this),
- this.handleQuitAndResubscribe.bind(this));
- api.bind('/primary', 'PUT', api.authTokens.ship, 'invite-view',
- this.handleEvent.bind(this),
- this.handleError.bind(this),
- this.handleQuitAndResubscribe.bind(this));
- api.bind('/all', 'PUT', api.authTokens.ship, 'group-store',
- this.handleEvent.bind(this),
- this.handleError.bind(this),
- this.handleQuitAndResubscribe.bind(this));
- api.bind('/all', 'PUT', api.authTokens.ship, 'metadata-store',
- this.handleEvent.bind(this),
- this.handleError.bind(this),
- this.handleQuitAndResubscribe.bind(this));
+ (err) => {
+ console.log(err);
+ this.subscribe(path, app);
+ },
+ () => {
+ this.subscribe(path, app);
+ });
+ }
+
+ firstRoundSubscription() {
+ this.subscribe('/primary', 'contact-view');
+ }
+
+ secondRoundSubscriptions() {
+ this.subscribe('/synced', 'contact-hook');
+ this.subscribe('/primary', 'invite-view');
+ this.subscribe('/all', 'group-store');
+ this.subscribe('/all', 'metadata-store');
+ }
+
+ handleEvent(diff) {
+ if (!this.firstRoundSubscriptionComplete) {
+ this.firstRoundSubscriptionComplete = true;
+ this.secondRoundSubscriptions();
+ }
+ store.handleEvent(diff);
}
handleEvent(diff) {
store.handleEvent(diff);
}
-
- handleError(err) {
- console.error(err);
- }
-
- handleQuitSilently(quit) {
- // no-op
- }
-
- handleQuitAndResubscribe(quit) {
- // TODO: resubscribe
- }
}
export let subscription = new Subscription();
From bfcaf6468ea34d11822d07186ce31a0912f3c90c Mon Sep 17 00:00:00 2001
From: Logan Allen
Date: Tue, 14 Apr 2020 21:57:21 +0000
Subject: [PATCH 2/8] contact-hook: tested it, got /synced path working, and
subscriptions loading
---
pkg/arvo/app/contact-hook.hoon | 17 +++++++++++++----
pkg/arvo/lib/contact-json.hoon | 13 ++++++++++++-
pkg/arvo/mar/contact/hook-update.hoon | 13 +++++++++++++
pkg/interface/groups/src/js/subscription.js | 3 ---
4 files changed, 38 insertions(+), 8 deletions(-)
create mode 100644 pkg/arvo/mar/contact/hook-update.hoon
diff --git a/pkg/arvo/app/contact-hook.hoon b/pkg/arvo/app/contact-hook.hoon
index 956f894b7..ad7b53c8c 100644
--- a/pkg/arvo/app/contact-hook.hoon
+++ b/pkg/arvo/app/contact-hook.hoon
@@ -138,6 +138,7 @@
^- (list card)
:: local
?: (team:title our.bol src.bol)
+ ?. (~(has by synced) path) ~
=/ shp ?:(=(path /~/default) our.bol (~(got by synced) path))
=/ appl ?:(=(shp our.bol) %contact-store %contact-hook)
[%pass / %agent [shp appl] %poke %contact-action !>(act)]~
@@ -161,7 +162,9 @@
[~ state]
=. synced (~(put by synced) path.act our.bol)
:_ state
- [%pass contact-path %agent [our.bol %contact-store] %watch contact-path]~
+ :~ [%pass contact-path %agent [our.bol %contact-store] %watch contact-path]
+ [%give %fact ~ %contact-hook-update !>([%initial synced])]
+ ==
::
%add-synced
?> (team:title our.bol src.bol)
@@ -169,7 +172,9 @@
=. synced (~(put by synced) path.act ship.act)
=/ contact-path [%contacts path.act]
:_ state
- [%pass contact-path %agent [ship.act %contact-hook] %watch contact-path]~
+ :~ [%pass contact-path %agent [ship.act %contact-hook] %watch contact-path]
+ [%give %fact ~ %contact-hook-update !>([%initial synced])]
+ ==
::
%remove
=/ ship (~(get by synced) path.act)
@@ -180,13 +185,17 @@
%- zing
:~ (pull-wire [%contacts path.act])
[%give %kick ~[[%contacts path.act]] ~]~
+ [%give %fact ~ %contact-hook-update !>([%initial synced])]~
==
?. |(=(u.ship src.bol) (team:title our.bol src.bol))
:: if neither ship = source or source = us, do nothing
[~ state]
:: delete a foreign ship's path
- :- (pull-wire [%contacts path.act])
- state(synced (~(del by synced) path.act))
+ :_ state(synced (~(del by synced) path.act))
+ %- zing
+ :~ (pull-wire [%contacts path.act])
+ [%give %fact ~ %contact-hook-update !>([%initial synced])]~
+ ==
==
::
++ watch-contacts
diff --git a/pkg/arvo/lib/contact-json.hoon b/pkg/arvo/lib/contact-json.hoon
index c212e2708..cca3aa70e 100644
--- a/pkg/arvo/lib/contact-json.hoon
+++ b/pkg/arvo/lib/contact-json.hoon
@@ -1,10 +1,21 @@
-/- *contact-view
+/- *contact-view, *contact-hook
|%
++ nu :: parse number as hex
|= jon/json
?> ?=({$s *} jon)
(rash p.jon hex)
::
+++ hook-update-to-json
+ |= upd=contact-hook-update
+ =, enjs:format
+ ^- json
+ %+ frond %contact-hook-update
+ %- pairs
+ %+ turn ~(tap by synced.upd)
+ |= [pax=^path shp=^ship]
+ ^- [cord json]
+ [(spat pax) s+(scot %p shp)]
+::
++ rolodex-to-json
|= rolo=rolodex
=, enjs:format
diff --git a/pkg/arvo/mar/contact/hook-update.hoon b/pkg/arvo/mar/contact/hook-update.hoon
new file mode 100644
index 000000000..a1bdebd7b
--- /dev/null
+++ b/pkg/arvo/mar/contact/hook-update.hoon
@@ -0,0 +1,13 @@
+/+ *contact-json
+|_ upd=contact-hook-update
+++ grow
+ |%
+ ++ json (hook-update-to-json upd)
+ --
+::
+++ grab
+ |%
+ ++ noun contact-hook-update
+ --
+::
+--
diff --git a/pkg/interface/groups/src/js/subscription.js b/pkg/interface/groups/src/js/subscription.js
index aa0d23730..c7dc1b748 100644
--- a/pkg/interface/groups/src/js/subscription.js
+++ b/pkg/interface/groups/src/js/subscription.js
@@ -49,9 +49,6 @@ export class Subscription {
store.handleEvent(diff);
}
- handleEvent(diff) {
- store.handleEvent(diff);
- }
}
export let subscription = new Subscription();
From 0145981542e93927fa880e0e087b49ca26df2318 Mon Sep 17 00:00:00 2001
From: Logan Allen
Date: Tue, 14 Apr 2020 18:16:44 -0400
Subject: [PATCH 3/8] contact-js: made channel handle onChannelError
---
pkg/interface/groups/src/js/store.js | 25 ++++++++++++++-------
pkg/interface/groups/src/js/subscription.js | 13 +++++++++++
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/pkg/interface/groups/src/js/store.js b/pkg/interface/groups/src/js/store.js
index f1ebad44c..47ac07316 100644
--- a/pkg/interface/groups/src/js/store.js
+++ b/pkg/interface/groups/src/js/store.js
@@ -9,14 +9,7 @@ import { LocalReducer } from '/reducers/local.js';
class Store {
constructor() {
- this.state = {
- contacts: {},
- groups: {},
- associations: {},
- permissions: {},
- invites: {},
- selectedGroups: []
- };
+ this.state = this.initialState();
this.initialReducer = new InitialReducer();
this.groupUpdateReducer = new GroupUpdateReducer();
@@ -28,6 +21,17 @@ class Store {
this.setState = () => {};
}
+ initialState() {
+ return {
+ contacts: {},
+ groups: {},
+ associations: {},
+ permissions: {},
+ invites: {},
+ selectedGroups: []
+ };
+ }
+
setStateHandler(setState) {
this.setState = setState;
}
@@ -35,6 +39,11 @@ class Store {
handleEvent(data) {
let json = data.data;
+ if ('clear' in json && json.clear) {
+ this.setState(this.initialState());
+ return;
+ }
+
console.log(json);
this.initialReducer.reduce(json, this.state);
this.groupUpdateReducer.reduce(json, this.state);
diff --git a/pkg/interface/groups/src/js/subscription.js b/pkg/interface/groups/src/js/subscription.js
index c7dc1b748..269fc2fe0 100644
--- a/pkg/interface/groups/src/js/subscription.js
+++ b/pkg/interface/groups/src/js/subscription.js
@@ -13,11 +13,24 @@ export class Subscription {
start() {
if (api.authTokens) {
this.firstRoundSubscription();
+ window.urb.setOnChannelError(this.onChannelError.bind(this));
} else {
console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
}
}
+ onChannelError(err) {
+ console.error('event source error: ', err);
+ console.log('initiating new channel');
+ this.firstRoundSubscriptionComplete = false;
+ setTimeout(2000, () => {
+ store.handleEvent({
+ data: { clear : true}
+ });
+ this.start();
+ });
+ }
+
subscribe(path, app) {
api.bind(path, 'PUT', api.authTokens.ship, app,
this.handleEvent.bind(this),
From de077ffb4759d31a9eab33d50bba97b046a6ad78 Mon Sep 17 00:00:00 2001
From: Matilde Park
Date: Tue, 21 Apr 2020 14:30:28 -0400
Subject: [PATCH 4/8] chat: set code toggle only at start of input
---
pkg/interface/chat/src/js/components/lib/chat-input.js | 6 ++++--
1 file changed, 4 insertions(+), 2 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 55214b1e2..3a10e4f17 100644
--- a/pkg/interface/chat/src/js/components/lib/chat-input.js
+++ b/pkg/interface/chat/src/js/components/lib/chat-input.js
@@ -380,7 +380,7 @@ export class ChatInput extends Component {
message = [];
}
- // perf:
+ // perf:
//setTimeout(this.closure, 2000);
this.editor.setValue('');
@@ -454,7 +454,9 @@ export class ChatInput extends Component {
? this.completePatp(state.selectedSuggestion)
: this.messageSubmit(),
'Shift-3': (cm) =>
- this.toggleCode()
+ cm.getValue().length === 0
+ ? this.toggleCode()
+ : CodeMirror.Pass
}
};
From 0e357373c0ebb5410111faaf5ff95b7b3d278822 Mon Sep 17 00:00:00 2001
From: Matilde Park
Date: Tue, 21 Apr 2020 14:31:32 -0400
Subject: [PATCH 5/8] chat: lint chat-input.js
---
.../chat/src/js/components/lib/chat-input.js | 190 ++++++++----------
1 file changed, 81 insertions(+), 109 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 3a10e4f17..ce04de716 100644
--- a/pkg/interface/chat/src/js/components/lib/chat-input.js
+++ b/pkg/interface/chat/src/js/components/lib/chat-input.js
@@ -1,9 +1,8 @@
import React, { Component } from 'react';
import _ from 'lodash';
import moment from 'moment';
-import Mousetrap from 'mousetrap';
import cn from 'classnames';
-import { UnControlled as CodeEditor } from 'react-codemirror2'
+import { UnControlled as CodeEditor } from 'react-codemirror2';
import CodeMirror from 'codemirror';
import 'codemirror/mode/markdown/markdown';
@@ -11,54 +10,34 @@ import 'codemirror/addon/display/placeholder';
import { Sigil } from '/components/lib/icons/sigil';
-import { uuid, uxToHex, hexToRgba } from '/lib/util';
+import { uxToHex, hexToRgba } from '/lib/util';
const MARKDOWN_CONFIG = {
- name: "markdown",
+ name: 'markdown',
tokenTypeOverrides: {
- header: "presentation",
- quote: "presentation",
- list1: "presentation",
- list2: "presentation",
- list3: "presentation",
- hr: "presentation",
- image: "presentation",
- imageAltText: "presentation",
- imageMarker: "presentation",
- formatting: "presentation",
- linkInline: "presentation",
- linkEmail: "presentation",
- linkText: "presentation",
- linkHref: "presentation",
+ header: 'presentation',
+ quote: 'presentation',
+ list1: 'presentation',
+ list2: 'presentation',
+ list3: 'presentation',
+ hr: 'presentation',
+ image: 'presentation',
+ imageAltText: 'presentation',
+ imageMarker: 'presentation',
+ formatting: 'presentation',
+ linkInline: 'presentation',
+ linkEmail: 'presentation',
+ linkText: 'presentation',
+ linkHref: 'presentation'
}
-}
-
-// line height
-const INPUT_LINE_HEIGHT = 28;
-
-const INPUT_TOP_PADDING = 3;
-
-
-function getAdvance(a, b) {
- let res = '';
- if(!a) {
- return b;
- }
- for (let i = 0; i < Math.min(a.length, b.length); i++) {
- if (a[i] !== b[i]) {
- return res;
- }
- res = res.concat(a[i]);
- }
- return res;
-}
+};
function ChatInputSuggestion({ ship, contacts, selected, onSelect }) {
- let contact = contacts[ship];
- let color = "#000000";
- let sigilClass = "v-mid mix-blend-diff"
+ const contact = contacts[ship];
+ let color = '#000000';
+ let sigilClass = 'v-mid mix-blend-diff';
let nickname;
- let nameStyle = {};
+ const nameStyle = {};
const isSelected = ship === selected;
if (contact) {
const hex = uxToHex(contact.color);
@@ -66,7 +45,7 @@ function ChatInputSuggestion({ ship, contacts, selected, onSelect }) {
nameStyle.color = hexToRgba(hex, .7);
nameStyle.textShadow = '0px 0px 0px #000';
nameStyle.filter = 'contrast(1.3) saturate(1.5)';
- sigilClass = "v-mid";
+ sigilClass = 'v-mid';
nickname = contact.nickname;
}
@@ -77,7 +56,7 @@ function ChatInputSuggestion({ ship, contacts, selected, onSelect }) {
'f8 pv1 ph3 pointer hover-bg-gray1-d hover-bg-gray4 relative flex items-center',
{
'white-d bg-gray0-d bg-white': !isSelected,
- 'black-d bg-gray1-d bg-gray4': isSelected,
+ 'black-d bg-gray1-d bg-gray4': isSelected
}
)}
key={ship}
@@ -99,7 +78,6 @@ function ChatInputSuggestion({ ship, contacts, selected, onSelect }) {
);
-
}
function ChatInputSuggestions({ suggestions, onSelect, selected, contacts }) {
@@ -112,14 +90,16 @@ function ChatInputSuggestions({ suggestions, onSelect, selected, contacts }) {
className={
'absolute black white-d bg-white bg-gray0-d ' +
'w7 pv3 z-1 mt1 ba b--gray1-d b--gray4'
- }>
+ }
+ >
{suggestions.map(ship =>
()
+ ship={ship}
+ />)
)}
);
@@ -150,9 +130,8 @@ export class ChatInput extends Component {
this.editor = null;
-
// perf testing:
- /*let closure = () => {
+ /* let closure = () => {
let x = 0;
for (var i = 0; i < 30; i++) {
x++;
@@ -174,21 +153,21 @@ export class ChatInput extends Component {
past: function(input) {
return input === 'just now'
? input
- : input + ' ago'
+ : input + ' ago';
},
s : 'just now',
- future: "in %s",
+ future: 'in %s',
ss : '%d sec',
- m: "a minute",
- mm: "%d min",
- h: "an hr",
- hh: "%d hrs",
- d: "a day",
- dd: "%d days",
- M: "a month",
- MM: "%d months",
- y: "a year",
- yy: "%d years"
+ m: 'a minute',
+ mm: '%d min',
+ h: 'an hr',
+ hh: '%d hrs',
+ d: 'a day',
+ dd: '%d days',
+ M: 'a month',
+ MM: '%d months',
+ y: 'a year',
+ yy: '%d years'
}
});
}
@@ -206,36 +185,33 @@ export class ChatInput extends Component {
this.setState({ selectedSuggestion: patpSuggestions[idx] });
}
-
patpAutocomplete(message, fresh = false) {
const match = /~([a-zA-Z\-]*)$/.exec(message);
if (!match ) {
- this.setState({ patpSuggestions: [] })
+ this.setState({ patpSuggestions: [] });
return;
}
-
const needle = match[1].toLowerCase();
- const matchString = hay => {
+ const matchString = (hay) => {
hay = hay.toLowerCase();
return hay.startsWith(needle)
|| _.some(_.words(hay), s => s.startsWith(needle));
};
-
const contacts = _.chain(this.props.contacts)
.defaultTo({})
- .map((details, ship) => ({...details, ship }))
+ .map((details, ship) => ({ ...details, ship }))
.filter(({ nickname, ship }) => matchString(nickname) || matchString(ship))
.map('ship')
- .value()
+ .value();
const suggestions = _.chain(this.props.envelopes)
.defaultTo([])
- .map("author")
+ .map('author')
.uniq()
.reverse()
.filter(matchString)
@@ -244,7 +220,7 @@ export class ChatInput extends Component {
.take(5)
.value();
- let newState = {
+ const newState = {
patpSuggestions: suggestions,
selectedSuggestion: suggestions[0]
};
@@ -255,7 +231,7 @@ export class ChatInput extends Component {
clearSuggestions() {
this.setState({
patpSuggestions: []
- })
+ });
}
completePatp(suggestion) {
@@ -276,15 +252,12 @@ export class ChatInput extends Component {
}
messageChange(editor, data, value) {
-
const { patpSuggestions } = this.state;
if(patpSuggestions.length !== 0) {
this.patpAutocomplete(value, false);
}
-
}
-
getLetterType(letter) {
if (letter.startsWith('/me')) {
letter = letter.slice(3);
@@ -296,22 +269,21 @@ export class ChatInput extends Component {
return {
me: letter
- }
+ };
} else if (this.isUrl(letter)) {
return {
url: letter
- }
+ };
} else {
return {
text: letter
- }
+ };
}
}
isUrl(string) {
try {
- let websiteTest = new RegExp(''
- + /((\w+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+)/.source
+ const websiteTest = new RegExp(String(/((\w+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+)/.source)
);
return websiteTest.test(string);
} catch (e) {
@@ -341,10 +313,10 @@ export class ChatInput extends Component {
return;
}
let message = [];
- editorMessage.split(" ").map((each) => {
+ editorMessage.split(' ').map((each) => {
if (this.isUrl(each)) {
if (message.length > 0) {
- message = message.join(" ");
+ message = message.join(' ');
message = this.getLetterType(message);
props.api.chat.message(
props.station,
@@ -354,22 +326,20 @@ export class ChatInput extends Component {
);
message = [];
}
- let URL = this.getLetterType(each);
+ const URL = this.getLetterType(each);
props.api.chat.message(
props.station,
`~${window.ship}`,
Date.now(),
URL
);
- }
- else {
+ } else {
return message.push(each);
}
- })
-
+ });
if (message.length > 0) {
- message = message.join(" ");
+ message = message.join(' ');
message = this.getLetterType(message);
props.api.chat.message(
props.station,
@@ -381,10 +351,9 @@ export class ChatInput extends Component {
}
// perf:
- //setTimeout(this.closure, 2000);
+ // setTimeout(this.closure, 2000);
this.editor.setValue('');
-
}
toggleCode() {
@@ -395,7 +364,7 @@ export class ChatInput extends Component {
} else {
this.setState({ code: true });
this.editor.setOption('mode', null);
- this.editor.setOption('placeholder', "Code...");
+ this.editor.setOption('placeholder', 'Code...');
}
const value = this.editor.getValue();
@@ -404,17 +373,16 @@ export class ChatInput extends Component {
this.editor.setValue(' ');
this.editor.setValue('');
}
-
}
render() {
const { props, state } = this;
- let color = !!props.ownerContact
+ const color = props.ownerContact
? uxToHex(props.ownerContact.color) : '000000';
- let sigilClass = !!props.ownerContact
- ? "" : "mix-blend-diff";
+ const sigilClass = props.ownerContact
+ ? '' : 'mix-blend-diff';
const completeActive = this.state.patpSuggestions.length !== 0;
@@ -427,43 +395,43 @@ export class ChatInput extends Component {
lineWrapping: true,
scrollbarStyle: 'native',
cursorHeight: 0.85,
- placeholder: state.code ? "Code..." : props.placeholder,
+ placeholder: state.code ? 'Code...' : props.placeholder,
extraKeys: {
- Tab: (cm) =>
+ Tab: cm =>
completeActive
? this.nextAutocompleteSuggestion()
: this.patpAutocomplete(cm.getValue(), true),
- 'Shift-Tab': (cm) =>
+ 'Shift-Tab': cm =>
completeActive
? this.nextAutocompleteSuggestion(true)
: CodeMirror.Pass,
- 'Up': (cm) =>
+ 'Up': cm =>
completeActive
? this.nextAutocompleteSuggestion(true)
: CodeMirror.Pass,
- 'Escape': (cm) =>
+ 'Escape': cm =>
completeActive
? this.clearSuggestions(true)
: CodeMirror.Pass,
- 'Down': (cm) =>
+ 'Down': cm =>
completeActive
? this.nextAutocompleteSuggestion()
: CodeMirror.Pass,
- 'Enter': (cm) =>
+ 'Enter': cm =>
completeActive
? this.completePatp(state.selectedSuggestion)
: this.messageSubmit(),
- 'Shift-3': (cm) =>
+ 'Shift-3': cm =>
cm.getValue().length === 0
? this.toggleCode()
: CodeMirror.Pass
}
};
-
return (
+ style={{ flexGrow: 1 }}
+ >
{state.patpSuggestions.length !== 0 && (
+ }}
+ >
+ />
+ style={{ flexGrow: 1, maxHeight: '224px', width: 'calc(100% - 48px)' }}
+ >
{ this.editor = editor; }}
+ editorDidMount={(editor) => {
+ this.editor = editor;
+}}
onChange={(e, d, v) => this.messageChange(e, d, v)}
/>
From 6d4a694aeb4d89c9d6d07196a8d2415f1b571a5d Mon Sep 17 00:00:00 2001
From: Logan Allen
Date: Tue, 21 Apr 2020 14:58:37 -0400
Subject: [PATCH 6/8] t groups + contacts: make removes completely clean up
state
---
pkg/arvo/app/contact-hook.hoon | 64 +++++++++----------
pkg/arvo/app/contact-store.hoon | 2 +-
pkg/arvo/app/contact-view.hoon | 4 +-
pkg/arvo/app/group-hook.hoon | 50 ++++++---------
pkg/interface/groups/src/js/api.js | 11 +---
.../src/js/components/lib/contact-card.js | 3 +-
6 files changed, 58 insertions(+), 76 deletions(-)
diff --git a/pkg/arvo/app/contact-hook.hoon b/pkg/arvo/app/contact-hook.hoon
index ad7b53c8c..e34b2ad8b 100644
--- a/pkg/arvo/app/contact-hook.hoon
+++ b/pkg/arvo/app/contact-hook.hoon
@@ -19,7 +19,7 @@
+$ state-zero [%0 state-base]
+$ state-one [%1 state-base]
+$ state-base
- $: synced=(map path ship)
+ $: =synced
invite-created=_|
==
--
@@ -125,31 +125,29 @@
++ poke-contact-action
|= act=contact-action
^- (quip card _state)
- |^
:_ state
?+ -.act !!
%edit (handle-contact-action path.act ship.act act)
%add (handle-contact-action path.act ship.act act)
%remove (handle-contact-action path.act ship.act act)
==
- ::
- ++ handle-contact-action
- |= [=path =ship act=contact-action]
- ^- (list card)
- :: local
- ?: (team:title our.bol src.bol)
- ?. (~(has by synced) path) ~
- =/ shp ?:(=(path /~/default) our.bol (~(got by synced) path))
- =/ appl ?:(=(shp our.bol) %contact-store %contact-hook)
- [%pass / %agent [shp appl] %poke %contact-action !>(act)]~
- :: foreign
- =/ shp (~(got by synced) path)
- ?. |(=(shp our.bol) =(src.bol ship)) ~
- :: scry group to check if ship is a member
- =/ =group (need (group-scry path))
- ?. (~(has in group) shp) ~
- [%pass / %agent [our.bol %contact-store] %poke %contact-action !>(act)]~
- --
+::
+++ handle-contact-action
+ |= [=path =ship act=contact-action]
+ ^- (list card)
+ :: local
+ ?: (team:title our.bol src.bol)
+ ?. (~(has by synced) path) ~
+ =/ shp ?:(=(path /~/default) our.bol (~(got by synced) path))
+ =/ appl ?:(=(shp our.bol) %contact-store %contact-hook)
+ [%pass / %agent [shp appl] %poke %contact-action !>(act)]~
+ :: foreign
+ =/ shp (~(got by synced) path)
+ ?. |(=(shp our.bol) =(src.bol ship)) ~
+ :: scry group to check if ship is a member
+ =/ =group (need (group-scry path))
+ ?. (~(has in group) shp) ~
+ [%pass / %agent [our.bol %contact-store] %poke %contact-action !>(act)]~
::
++ poke-hook-action
|= act=contact-hook-action
@@ -163,7 +161,7 @@
=. synced (~(put by synced) path.act our.bol)
:_ state
:~ [%pass contact-path %agent [our.bol %contact-store] %watch contact-path]
- [%give %fact ~ %contact-hook-update !>([%initial synced])]
+ [%give %fact [/synced]~ %contact-hook-update !>([%initial synced])]
==
::
%add-synced
@@ -173,7 +171,7 @@
=/ contact-path [%contacts path.act]
:_ state
:~ [%pass contact-path %agent [ship.act %contact-hook] %watch contact-path]
- [%give %fact ~ %contact-hook-update !>([%initial synced])]
+ [%give %fact [/synced]~ %contact-hook-update !>([%initial synced])]
==
::
%remove
@@ -185,16 +183,19 @@
%- zing
:~ (pull-wire [%contacts path.act])
[%give %kick ~[[%contacts path.act]] ~]~
- [%give %fact ~ %contact-hook-update !>([%initial synced])]~
+ [%give %fact [/synced]~ %contact-hook-update !>([%initial synced])]~
==
?. |(=(u.ship src.bol) (team:title our.bol src.bol))
:: if neither ship = source or source = us, do nothing
[~ state]
:: delete a foreign ship's path
+ =/ cards
+ (handle-contact-action path.act our.bol [%remove path.act our.bol])
:_ state(synced (~(del by synced) path.act))
%- zing
:~ (pull-wire [%contacts path.act])
- [%give %fact ~ %contact-hook-update !>([%initial synced])]~
+ [%give %fact [/synced]~ %contact-hook-update !>([%initial synced])]~
+ cards
==
==
::
@@ -207,10 +208,7 @@
=/ =group (need (group-scry pax))
?> (~(has in group) src.bol)
=/ contacts (need (contacts-scry pax))
- :~ :*
- %give %fact ~ %contact-update
- !>([%contacts pax contacts])
- == ==
+ [%give %fact ~ %contact-update !>([%contacts pax contacts])]~
::
++ watch-synced
|= pax=path
@@ -324,13 +322,15 @@
==
::
%add
- =/ owner (~(got by synced) path.fact)
- ?> |(=(owner src.bol) =(src.bol ship.fact))
+ =/ owner (~(get by synced) path.fact)
+ ?~ owner ~
+ ?> |(=(u.owner src.bol) =(src.bol ship.fact))
~[(contact-poke [%add path.fact ship.fact contact.fact])]
::
%remove
- =/ owner (~(got by synced) path.fact)
- ?> |(=(owner src.bol) =(src.bol ship.fact))
+ =/ owner (~(get by synced) path.fact)
+ ?~ owner ~
+ ?> |(=(u.owner src.bol) =(src.bol ship.fact))
%+ welp
:~ (group-poke [%remove [ship.fact ~ ~] path.fact])
(contact-poke [%remove path.fact ship.fact])
diff --git a/pkg/arvo/app/contact-store.hoon b/pkg/arvo/app/contact-store.hoon
index 7792e7918..398ef15b0 100644
--- a/pkg/arvo/app/contact-store.hoon
+++ b/pkg/arvo/app/contact-store.hoon
@@ -142,7 +142,7 @@
|= [=path =ship]
^- (quip card _state)
=/ contacts (~(got by rolodex) path)
- ?> (~(has by contacts) ship)
+ ?. (~(has by contacts) ship) [~ state]
=. contacts (~(del by contacts) ship)
:- (send-diff path [%remove path ship])
state(rolodex (~(put by rolodex) path contacts))
diff --git a/pkg/arvo/app/contact-view.hoon b/pkg/arvo/app/contact-view.hoon
index 9c85c135d..1bfd5a69a 100644
--- a/pkg/arvo/app/contact-view.hoon
+++ b/pkg/arvo/app/contact-view.hoon
@@ -147,9 +147,9 @@
::
%delete
%+ weld
- :~ (group-poke [%unbundle path.act])
+ :~ (contact-hook-poke [%remove path.act])
+ (group-poke [%unbundle path.act])
(contact-poke [%delete path.act])
- (contact-hook-poke [%remove path.act])
==
(delete-metadata path.act)
::
diff --git a/pkg/arvo/app/group-hook.hoon b/pkg/arvo/app/group-hook.hoon
index 47ccc1d42..7cfc83188 100644
--- a/pkg/arvo/app/group-hook.hoon
+++ b/pkg/arvo/app/group-hook.hoon
@@ -38,18 +38,12 @@
^- (quip card _this)
=/ old !<(state-zero vase)
:_ this(state old)
- %+ murn
- ~(tap by synced.old)
+ %+ murn ~(tap by synced.old)
|= [=path =ship]
^- (unit card)
- =/ =wire
- [(scot %p ship) %group path]
- =/ =term
- ?: =(our.bowl ship)
- %group-store
- %group-hook
- ?: (~(has by wex.bowl) [wire ship term])
- ~
+ =/ =wire [(scot %p ship) %group path]
+ =/ =term ?:(=(our.bowl ship) %group-store %group-hook)
+ ?: (~(has by wex.bowl) [wire ship term]) ~
`[%pass wire %agent [ship term] %watch [%group path]]
::
++ on-leave on-leave:def
@@ -173,10 +167,9 @@
%remove [(update-subscribers [%group pax.diff] diff) state]
::
%unbundle
- :_ state(synced (~(del by synced.state) pax.diff))
- %+ snoc
- (update-subscribers [%group pax.diff] diff)
- [%give %kick [%group pax.diff]~ ~]
+ =/ ship (~(get by synced.state) pax.diff)
+ ?~ ship [~ state]
+ (poke-group-hook-action [%remove pax.diff])
==
::
++ handle-foreign
@@ -185,7 +178,6 @@
?- -.diff
%keys [~ state]
%bundle [~ state]
- ::
%path
:_ state
?~ pax.diff ~
@@ -219,23 +211,24 @@
[(group-poke pax.diff diff)]~
::
%remove
- :_ state
- ?~ pax.diff ~
+ ?~ pax.diff [~ state]
=/ ship (~(get by synced.state) pax.diff)
- ?~ ship ~
- ?. =(src.bol u.ship) ~
- [(group-poke pax.diff diff)]~
+ ?~ ship [~ state]
+ ?. =(src.bol u.ship) [~ state]
+ ?. (~(has in members.diff) our.bol) [~ state]
+ =/ changes (poke-group-hook-action [%remove pax.diff])
+ :_ +.changes
+ %+ welp -.changes
+ :~ (group-poke pax.diff diff)
+ (group-poke pax.diff [%unbundle pax.diff])
+ ==
::
%unbundle
- ?~ pax.diff
- [~ state]
+ ?~ pax.diff [~ state]
=/ ship (~(get by synced.state) pax.diff)
- ?~ ship
- [~ state]
- ?. =(src.bol u.ship)
- [~ state]
- :_ state(synced (~(del by synced.state) pax.diff))
- [(group-poke pax.diff diff)]~
+ ?~ ship [~ state]
+ ?. =(src.bol u.ship) [~ state]
+ (poke-group-hook-action [%remove pax.diff])
==
::
++ group-poke
@@ -262,5 +255,4 @@
?: =(u.shp our.bol)
[%pass wir %agent [our.bol %group-store] %leave ~]~
[%pass wir %agent [u.shp %group-hook] %leave ~]~
-::
--
diff --git a/pkg/interface/groups/src/js/api.js b/pkg/interface/groups/src/js/api.js
index 6e56ca9ac..70a6a69b9 100644
--- a/pkg/interface/groups/src/js/api.js
+++ b/pkg/interface/groups/src/js/api.js
@@ -11,8 +11,7 @@ class UrbitApi {
this.bindPaths = [];
this.contactHook = {
- edit: this.contactEdit.bind(this),
- remove: this.contactRemove.bind(this)
+ edit: this.contactEdit.bind(this)
};
this.contactView = {
@@ -108,14 +107,6 @@ class UrbitApi {
return this.action("contact-hook", "contact-action", data);
}
- contactRemove(path, ship) {
- return this.contactHookAction({
- remove: {
- path, ship
- }
- });
- }
-
contactEdit(path, ship, editField) {
/* editField can be...
{nickname: ''}
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 dff7b4aa4..de3189918 100644
--- a/pkg/interface/groups/src/js/components/lib/contact-card.js
+++ b/pkg/interface/groups/src/js/components/lib/contact-card.js
@@ -317,13 +317,12 @@ export class ContactCard extends Component {
);
this.setState({awaiting: true, type: "Removing from group"}, (() => {
- api.contactHook.remove(props.path, `~${props.ship}`).then(() => {
+ api.contactView.delete(props.path).then(() => {
let destination = (props.ship === window.ship)
? "" : props.path;
this.setState({awaiting: false});
props.history.push(`/~groups${destination}`);
});
- api.contactView.delete(props.path);
}))
}
From bcde27a7ff40531285fa699e7f00091bde565e7c Mon Sep 17 00:00:00 2001
From: Matilde Park
Date: Tue, 21 Apr 2020 15:05:48 -0400
Subject: [PATCH 7/8] publish: change line-height on numbered lists
---
pkg/interface/publish/src/css/custom.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pkg/interface/publish/src/css/custom.css b/pkg/interface/publish/src/css/custom.css
index 5b068397e..ec574dd6f 100644
--- a/pkg/interface/publish/src/css/custom.css
+++ b/pkg/interface/publish/src/css/custom.css
@@ -265,7 +265,7 @@ a {
.md code, .md pre {
font-family: "Source Code Pro", mono;
}
-.md ul>li {
+.md ul>li, .md ol>li {
line-height: 1.5;
}
.md a {
From 707bedc2b4138bf03ef822fe5a481acfc218fc2a Mon Sep 17 00:00:00 2001
From: Matilde Park
Date: Tue, 21 Apr 2020 19:36:30 -0400
Subject: [PATCH 8/8] publish: set font size for ordered lists
---
pkg/interface/publish/src/css/custom.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pkg/interface/publish/src/css/custom.css b/pkg/interface/publish/src/css/custom.css
index ec574dd6f..5f225ebef 100644
--- a/pkg/interface/publish/src/css/custom.css
+++ b/pkg/interface/publish/src/css/custom.css
@@ -242,7 +242,7 @@ a {
display: none;
}
-.md h1, .md h2, .md h3, .md h4, .md h5, .md p, .md a, .md ul, .md blockquote,.md code,.md pre {
+.md h1, .md h2, .md h3, .md h4, .md h5, .md p, .md a, .md ul, .md ol, .md blockquote,.md code,.md pre {
font-size: 14px;
margin-bottom: 16px;
}