@@ -114,8 +150,8 @@ export class ChatInput extends Component {
diff --git a/apps/chat/src/js/reducers/chat.js b/apps/chat/src/js/reducers/config.js
similarity index 77%
rename from apps/chat/src/js/reducers/chat.js
rename to apps/chat/src/js/reducers/config.js
index b427f82678..7e3397c2d6 100644
--- a/apps/chat/src/js/reducers/chat.js
+++ b/apps/chat/src/js/reducers/config.js
@@ -1,11 +1,10 @@
import _ from 'lodash';
-export class ChatReducer {
+export class ConfigReducer {
reduce(json, state) {
let data = _.get(json, 'chat', false);
if (data) {
- state.messages = data.messages;
state.inbox = data.inbox;
state.configs = data.configs;
state.circles = data.circles;
diff --git a/apps/chat/src/js/reducers/initial.js b/apps/chat/src/js/reducers/initial.js
new file mode 100644
index 0000000000..769dab1201
--- /dev/null
+++ b/apps/chat/src/js/reducers/initial.js
@@ -0,0 +1,15 @@
+import _ from 'lodash';
+
+
+export class InitialReducer {
+ reduce(json, state) {
+ let data = _.get(json, 'initial', false);
+ if (data) {
+ state.messages = data.messages;
+ state.inbox = data.inbox;
+ state.configs = data.configs;
+ state.circles = data.circles;
+ }
+ }
+}
+
diff --git a/apps/chat/src/js/reducers/update.js b/apps/chat/src/js/reducers/update.js
index 60a3f8e66a..42c47ef361 100644
--- a/apps/chat/src/js/reducers/update.js
+++ b/apps/chat/src/js/reducers/update.js
@@ -7,6 +7,7 @@ export class UpdateReducer {
if (data) {
this.reduceInbox(_.get(data, 'inbox', false), state);
this.reduceMessage(_.get(data, 'message', false), state);
+ this.reduceMessages(_.get(data, 'messages', false), state);
this.reduceConfig(_.get(data, 'config', false), state);
this.reduceCircles(_.get(data, 'circles', false), state);
}
@@ -26,6 +27,22 @@ export class UpdateReducer {
}
}
+ reduceMessages(messages, state) {
+ if (messages.circle in state.messages) {
+ let station = state.messages[messages.circle];
+ if (
+ station.length > 0 &&
+ station[station.length - 1].num === station.length - 1 &&
+ messages.start === station.length
+ ) {
+ state.messages[messages.circle] =
+ state.messages[messages.circle].concat(messages.envelopes);
+ } else {
+ console.error('%messages has indices inconsistent with localStorage');
+ }
+ }
+ }
+
reduceConfig(config, state) {
if (config) {
state.configs[config.circle] = config.config;
diff --git a/apps/chat/src/js/store.js b/apps/chat/src/js/store.js
index eb86f5acce..e677888d9e 100644
--- a/apps/chat/src/js/store.js
+++ b/apps/chat/src/js/store.js
@@ -1,20 +1,34 @@
import _ from 'lodash';
-import { ChatReducer } from '/reducers/chat';
+import { InitialReducer } from '/reducers/initial';
+import { ConfigReducer } from '/reducers/config';
import { UpdateReducer } from '/reducers/update';
class Store {
constructor() {
- this.state = {
- inbox: {},
- messages: [],
- configs: {},
- circles: []
- };
+ let state = localStorage.getItem('store');
- this.chatReducer = new ChatReducer();
+ if (!state) {
+ this.state = {
+ inbox: {},
+ messages: [],
+ configs: {},
+ circles: [],
+ local: false
+ };
+ } else {
+ this.state = JSON.parse(state);
+ // TODO: wtf???
+ delete this.state.messages[undefined];
+ console.log(this.state);
+ this.state.local = true;
+ }
+
+ this.initialReducer = new InitialReducer();
+ this.configReducer = new ConfigReducer();
this.updateReducer = new UpdateReducer();
this.setState = () => {};
+
}
setStateHandler(setState) {
@@ -22,14 +36,17 @@ class Store {
}
handleEvent(data) {
+ console.log(data);
let json = data.data;
- this.chatReducer.reduce(json, this.state);
+ this.initialReducer.reduce(json, this.state);
+ this.configReducer.reduce(json, this.state);
this.updateReducer.reduce(json, this.state);
this.setState(this.state);
+ localStorage.setItem('store', JSON.stringify(this.state));
}
}
export let store = new Store();
-
+window.store = store;
diff --git a/apps/chat/src/js/subscription.js b/apps/chat/src/js/subscription.js
index 33c27ac729..43a8c44694 100644
--- a/apps/chat/src/js/subscription.js
+++ b/apps/chat/src/js/subscription.js
@@ -7,33 +7,32 @@ export class Subscription {
start() {
if (api.authTokens) {
this.initializeChat();
- //this.setCleanupTasks();
} else {
console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
}
}
- /*setCleanupTasks() {
- window.addEventListener("beforeunload", e => {
- api.bindPaths.forEach(p => {
- this.wipeSubscription(p);
- });
- });
- }
-
- wipeSubscription(path) {
- api.hall({
- wipe: {
- sub: [{
- hos: api.authTokens.ship,
- pax: path
- }]
- }
- });
- }*/
-
initializeChat() {
- api.bind('/primary', 'PUT', api.authTokens.ship, 'chat',
+ if (store.state.local) {
+ let path = [];
+ let msg = Object.keys(store.state.messages);
+ for (let i = 0; i < msg.length; i++) {
+ let cir = msg[i];
+ let len = store.state.messages[cir].length;
+ path.push(`${cir}/${len}`);
+ }
+ path = path.join('/');
+
+ api.bind(`/primary/${path}`, 'PUT', api.authTokens.ship, 'chat',
+ this.handleEvent.bind(this),
+ this.handleError.bind(this));
+ } else {
+ api.bind('/primary', 'PUT', api.authTokens.ship, 'chat',
+ this.handleEvent.bind(this),
+ this.handleError.bind(this));
+ }
+
+ api.bind('/updates', 'PUT', api.authTokens.ship, 'chat',
this.handleEvent.bind(this),
this.handleError.bind(this));
}
diff --git a/apps/chat/urbit/app/chat.hoon b/apps/chat/urbit/app/chat.hoon
index 81b6697af4..ec272761b0 100644
--- a/apps/chat/urbit/app/chat.hoon
+++ b/apps/chat/urbit/app/chat.hoon
@@ -44,9 +44,9 @@
|= old=(unit state)
^- (quip move _this)
?~ old
- =/ inboxpat /circle/inbox/config/group
+ =/ inboxpat /circle/inbox/config-l/config-r/group-r/group-l
=/ circlespat /circles/[(scot %p our.bol)]
- =/ inboxwir /circle/[(scot %p our.bol)]/inbox/config/group
+ =/ inboxwir /circle/[(scot %p our.bol)]/inbox/config/group-r/group-l
=/ inboxi/poke
:- %hall-action
[%source %inbox %.y (silt [[our.bol %i] ~]~)]
@@ -58,13 +58,97 @@
==
[~ this(sta u.old)]
::
-:: +peer-primary: subscribe to our data and updates
+:: +peer-messages: subscribe to subset of messages and updates
+::
++$ internal-state
+ $:
+ lis=(list [circle:hall @])
+ item=[cir=circle:hall count=@ud]
+ index=@
+ ==
+++ generate-circle-indices
+ |= wir=wire
+ ^- (list [circle:hall @])
+ =/ data
+ %^ spin (swag [0 (lent wir)] wir) *internal-state
+ |= [a=@ta b=internal-state]
+ ^- [* out=internal-state]
+ =/ switch (dvr index.b 3)
+ ?: =(q.switch 0) :: remainder 0, should be a ship
+ ?: =(index.b 0) :: if item is null, don't add to list
+ :- 0
+ %= b
+ hos.cir.item (slav %p a)
+ index +(index.b)
+ ==
+ :: if item is not null, add to list
+ :- 0
+ %= b
+ hos.cir.item (slav %p a)
+ nom.cir.item *name:hall
+ count.item 0
+ lis (snoc lis.b item.b)
+ index +(index.b)
+ ==
+ ?: =(q.switch 1) :: remainder 1, should be a circle name
+ :- 0
+ %= b
+ nom.cir.item a
+ index +(index.b)
+ ==
+ ?: =(q.switch 2) :: remainder 2, should be a number
+ :- 0
+ %= b
+ count.item (need (rush a dem))
+ index +(index.b)
+ ==
+ !! :: impossible
+ ?: =(index.q.data 0)
+ ~
+ (snoc lis.q.data item.q.data)
::
++ peer-primary
|= wir=wire
^- (quip move _this)
+ =/ indices (generate-circle-indices wir)
+ ?~ indices
+ :_ this
+ [ost.bol %diff %chat-initial str.sta]~
+ =* messages messages.str.sta
+ =/ lisunitmov/(list (unit move))
+ %+ turn indices
+ |= [cir=circle:hall start=@ud]
+ ^- (unit move)
+ =/ wholelist/(unit (list envelope:hall)) (~(get by messages) cir)
+ ?~ wholelist
+ ~
+ =/ end/@ (lent u.wholelist)
+ ?: (gte start end)
+ ~
+ :- ~
+ :* ost.bol
+ %diff
+ %chat-update
+ [%messages cir start end (swag [start end] u.wholelist)]
+ ==
+ =/ lismov/(list move)
+ %+ turn
+ %+ skim lisunitmov
+ |= umov=(unit move)
+ ^- ?
+ ?~ umov
+ %.n
+ %.y
+ need
:_ this
- [ost.bol %diff %chat-streams str.sta]~
+ %+ weld
+ [ost.bol %diff %chat-config str.sta]~
+ lismov
+::
+++ peer-updates
+ |= wir=wire
+ ^- (quip move _this)
+ [~ this]
::
++ poke-noun
|= a=*
@@ -93,7 +177,7 @@
++ send-chat-update
|= upd=update
^- (list move)
- %+ turn (prey:pubsub:userlib /primary bol)
+ %+ turn (prey:pubsub:userlib /updates bol)
|= [=bone *]
[bone %diff %chat-update upd]
::
@@ -123,19 +207,12 @@
:: %circle wire
::
%circle
-:: ?+ -.piz
-:: ::
-:: :: %peers prize
-:: ::
-:::: %peers
-:::: ?> ?=(%peers -.piz)
-:::: [~ this]
:: ::
:: :: %circle prize
:: ::
:: %circle
?> ?=(%circle -.piz)
- ~& piz
+ ~& pes.piz
=/ circle/circle:hall [our.bol &2:wir]
?: =(circle [our.bol %inbox])
::
@@ -145,27 +222,46 @@
%- ~(uni in configs.str.sta)
^- (map circle:hall (unit config:hall))
(~(run by rem.cos.piz) |=(a=config:hall `a))
- ~& pes.piz
+ ::
=/ circles/(list circle:hall)
%+ turn ~(tap in src.loc.cos.piz)
|= src=source:hall
^- circle:hall
cir.src
+ ::
=/ meslis/(list [circle:hall (list envelope:hall)])
%+ turn circles
|= cir=circle:hall
^- [circle:hall (list envelope:hall)]
[cir ~]
+ ::
+ =/ localpeers/(set @p)
+ %- silt %+ turn ~(tap by loc.pes.piz)
+ |= [shp=@p stat=status:hall]
+ shp
+ ::
+ =/ peers/(map circle:hall (set @p))
+ %- ~(rep by rem.pes.piz)
+ |= [[cir=circle:hall grp=group:hall] acc=(map circle:hall (set @p))]
+ ^- (map circle:hall (set @p))
+ =/ newset
+ %- silt %+ turn ~(tap by grp)
+ |= [shp=@p stat=status:hall]
+ shp
+ (~(put by acc) cir newset)
+ ::
:-
%+ turn ~(tap in (~(del in (silt circles)) [our.bol %inbox]))
|= cir=circle:hall
^- move
- =/ pat/path /circle/[nom.cir]/config/grams
+ =/ pat/path /circle/[nom.cir]/config-l/config-r/group-r/group-l
[ost.bol %peer pat [our.bol %hall] pat]
+ ::
%= this
inbox.str.sta loc.cos.piz
configs.str.sta configs
messages.str.sta (molt meslis)
+ peers.str.sta (~(put by peers) [our.bol %inbox] localpeers)
==
::
:: fill remote configs with message data
@@ -224,22 +320,27 @@
messages.str.sta (~(put by messages) circle (snoc nes nev.sto))
==
::
- :: %peer:
+ :: %status:
::
- %peer
- ?> ?=(%peer -.sto)
- ~& add.sto
- ~& who.sto
- ~& qer.sto
- [~ this]
+ %status
+ ?> ?=(%status -.sto)
+ =/ peers/(set @p)
+ ?: =(%remove -.dif.sto)
+ (~(del in (~(got by peers.str.sta) cir.sto)) who.sto)
+ (~(put in (~(got by peers.str.sta) cir.sto)) who.sto)
+ :- (send-chat-update [%peers cir.sto peers])
+ %= this
+ peers.str.sta (~(put by peers.str.sta) cir.sto peers)
+ ==
+
::
:: %config: config has changed
::
%config
- =* circ cir.sto
- ::
- ?+ -.dif.sto
- [~ this]
+ =* circ cir.sto
+ ::
+ ?+ -.dif.sto
+ [~ this]
::
:: %full: set all of config without side effects
::
@@ -277,8 +378,8 @@
[~ this]
=* affectedcir cir.src.dif.sto
=/ newwir/wire
- /circle/[(scot %p hos.affectedcir)]/[nom.affectedcir]/grams/config
- =/ pat/path /circle/[nom.affectedcir]/grams/config
+ /circle/[(scot %p hos.affectedcir)]/[nom.affectedcir]/grams/config/group-r/group-l
+ =/ pat/path /circle/[nom.affectedcir]/grams/config/group-r/group-l
:: we've added a source to our inbox
::
?: add.dif.sto
@@ -411,7 +512,7 @@
::
%circle
=/ shp/@p (slav %p &2:wir)
- =/ pat /circle/[&3:wir]/grams/config
+ =/ pat /circle/[&3:wir]/grams/config/group-r/group-l
:_ this
[ost.bol %peer wir [shp %hall] wir]~
::
diff --git a/apps/chat/urbit/app/chat/js/index.js b/apps/chat/urbit/app/chat/js/index.js
index 382746e479..ed0d6d8632 100644
--- a/apps/chat/urbit/app/chat/js/index.js
+++ b/apps/chat/urbit/app/chat/js/index.js
@@ -17,6 +17,10 @@
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
+ function getCjsExportFromNamespace (n) {
+ return n && n.default || n;
+ }
+
/*
object-assign
(c) Sindre Sorhus
@@ -47458,6 +47462,8 @@
isBuffer: isBuffer
});
+ var require$$0 = getCjsExportFromNamespace(bufferEs6);
+
var bn = createCommonjsModule(function (module) {
(function (module, exports) {
@@ -47510,7 +47516,7 @@
var Buffer;
try {
- Buffer = bufferEs6.Buffer;
+ Buffer = require$$0.Buffer;
} catch (e) {
}
@@ -51734,6 +51740,15 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
});
}
+ notify(aud, bool) {
+ this.hall({
+ notify: {
+ aud,
+ pes: !!bool ? 'hear' : 'gone'
+ }
+ });
+ }
+
permit(cir, aud, message) {
this.hall({
permit: {
@@ -51814,11 +51829,22 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
let api = new UrbitApi();
window.api = api;
- class ChatReducer {
+ class InitialReducer {
+ reduce(json, state) {
+ let data = lodash.get(json, 'initial', false);
+ if (data) {
+ state.messages = data.messages;
+ state.inbox = data.inbox;
+ state.configs = data.configs;
+ state.circles = data.circles;
+ }
+ }
+ }
+
+ class ConfigReducer {
reduce(json, state) {
let data = lodash.get(json, 'chat', false);
if (data) {
- state.messages = data.messages;
state.inbox = data.inbox;
state.configs = data.configs;
state.circles = data.circles;
@@ -51832,6 +51858,7 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
if (data) {
this.reduceInbox(lodash.get(data, 'inbox', false), state);
this.reduceMessage(lodash.get(data, 'message', false), state);
+ this.reduceMessages(lodash.get(data, 'messages', false), state);
this.reduceConfig(lodash.get(data, 'config', false), state);
this.reduceCircles(lodash.get(data, 'circles', false), state);
}
@@ -51851,6 +51878,22 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
}
}
+ reduceMessages(messages, state) {
+ if (messages.circle in state.messages) {
+ let station = state.messages[messages.circle];
+ if (
+ station.length > 0 &&
+ station[station.length - 1].num === station.length - 1 &&
+ messages.start === station.length
+ ) {
+ state.messages[messages.circle] =
+ state.messages[messages.circle].concat(messages.envelopes);
+ } else {
+ console.error('%messages has indices inconsistent with localStorage');
+ }
+ }
+ }
+
reduceConfig(config, state) {
if (config) {
state.configs[config.circle] = config.config;
@@ -51867,16 +51910,29 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
class Store {
constructor() {
- this.state = {
- inbox: {},
- messages: [],
- configs: {},
- circles: []
- };
+ let state = localStorage.getItem('store');
- this.chatReducer = new ChatReducer();
+ if (!state) {
+ this.state = {
+ inbox: {},
+ messages: [],
+ configs: {},
+ circles: [],
+ local: false
+ };
+ } else {
+ this.state = JSON.parse(state);
+ // TODO: wtf???
+ delete this.state.messages[undefined];
+ console.log(this.state);
+ this.state.local = true;
+ }
+
+ this.initialReducer = new InitialReducer();
+ this.configReducer = new ConfigReducer();
this.updateReducer = new UpdateReducer();
this.setState = () => {};
+
}
setStateHandler(setState) {
@@ -51884,16 +51940,20 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
}
handleEvent(data) {
+ console.log(data);
let json = data.data;
- this.chatReducer.reduce(json, this.state);
+ this.initialReducer.reduce(json, this.state);
+ this.configReducer.reduce(json, this.state);
this.updateReducer.reduce(json, this.state);
this.setState(this.state);
+ localStorage.setItem('store', JSON.stringify(this.state));
}
}
let store = new Store();
+ window.store = store;
const _jsxFileName = "/Users/logan/Dev/interface/apps/chat/src/js/components/skeleton.js";
@@ -56957,20 +57017,56 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
}
render() {
+
+ const { props, state } = this;
+ /*let closure = () => {
+ let aud, sep;
+ let wen = Date.now();
+ let uid = uuid();
+ let aut = window.ship;
+
+ let config = props.configs[state.station];
+
+ aud = [props.station];
+ sep = {
+ lin: {
+ msg: Date.now().toString(),
+ pat: false
+ }
+ }
+
+ let message = {
+ uid,
+ aut,
+ wen,
+ aud,
+ sep,
+ };
+
+ props.api.hall({
+ convey: [message]
+ });
+
+ setTimeout(closure, 1000);
+ };
+
+ closure();*/
+
+
return (
- react.createElement('div', { className: "mt2 pa3 cf flex black bt" , __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 109}}
- , react.createElement('div', { className: "fl", style: { flexBasis: 35, height: 40 }, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 110}}
- , react.createElement(Sigil, { ship: window.ship, size: 32, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 111}} )
+ react.createElement('div', { className: "mt2 pa3 cf flex black bt" , __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 145}}
+ , react.createElement('div', { className: "fl", style: { flexBasis: 35, height: 40 }, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 146}}
+ , react.createElement(Sigil, { ship: window.ship, size: 32, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 147}} )
)
- , react.createElement('div', { className: "fr h-100 flex" , style: { flexGrow: 1, height: 40 }, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 113}}
+ , react.createElement('div', { className: "fr h-100 flex" , style: { flexGrow: 1, height: 40 }, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 149}}
, react.createElement('input', { className: "ml2 bn" ,
style: { flexGrow: 1 },
ref: this.textareaRef,
- placeholder: this.props.placeholder,
- value: this.state.message,
- onChange: this.messageChange, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 114}} )
- , react.createElement('div', { className: "pointer", onClick: this.messageSubmit, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 120}}
- , react.createElement(IconSend, {__self: this, __source: {fileName: _jsxFileName$9, lineNumber: 121}} )
+ placeholder: props.placeholder,
+ value: state.message,
+ onChange: this.messageChange, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 150}} )
+ , react.createElement('div', { className: "pointer", onClick: this.messageSubmit, __self: this, __source: {fileName: _jsxFileName$9, lineNumber: 156}}
+ , react.createElement(IconSend, {__self: this, __source: {fileName: _jsxFileName$9, lineNumber: 157}} )
)
)
)
@@ -56987,14 +57083,47 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
station: props.match.params.ship + "/" + props.match.params.station,
circle: props.match.params.station,
host: props.match.params.ship,
- numPeople: 0
+ numPeople: 0,
+ numPages: 1,
+ scrollLocked: false
};
+ this.topMessage = {};
this.buildMessage = this.buildMessage.bind(this);
+ this.onScroll = this.onScroll.bind(this);
}
componentDidMount() {
this.updateNumPeople();
+ this.scrollElement.scrollIntoView(false);
+ }
+
+ scrollToBottom() {
+ if (!this.state.scrollLocked) {
+ console.log('scroll to bottom');
+ this.scrollElement.scrollIntoView({ behavior: 'smooth' });
+ }
+ }
+
+ onScroll(e) {
+ if (e.target.scrollTop === 0) {
+ let topMessage = this.topMessage;
+
+ this.setState({
+ numPages: this.state.numPages + 1,
+ scrollLocked: true
+ }, () => {
+ this.topMessage[1].scrollIntoView(true);
+ });
+ } else if (
+ (e.target.scrollHeight - Math.round(e.target.scrollTop)) ===
+ e.target.clientHeight
+ ) {
+ this.setState({
+ numPages: 1,
+ scrollLocked: false
+ });
+ }
}
componentDidUpdate(prevProps, prevState) {
@@ -57012,6 +57141,7 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
this.updateReadNumber();
this.updateNumPeople();
this.updateNumMessagesLoaded(prevProps, prevState);
+ this.scrollToBottom();
}
updateReadNumber() {
@@ -57048,42 +57178,62 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
}
}
- buildMessage(msg) {
+ buildMessage(msg, index) {
let details = msg.printship ? null : getMessageContent(msg.gam);
if (msg.printship) {
return (
react.createElement('a', {
className: "vanilla hoverline text-600 text-mono" ,
- href: prettyShip(msg.gam.aut)[1], __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 85}}
+ href: prettyShip(msg.gam.aut)[1], __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 119}}
, prettyShip(`~${msg.gam.aut}`)[0]
)
);
}
- return (
- react.createElement(Message, { key: msg.gam.uid, msg: msg.gam, details: details, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 93}} )
- );
+
+ if (index % 50 === 0) {
+ let pageNum = index / 50;
+ return (
+ react.createElement('div', { ref: el => { this.topMessage[pageNum] = el; }, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 130}}
+ , react.createElement(Message, {
+ key: msg.gam.uid, msg: msg.gam, details: details, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 131}} )
+ )
+ );
+ } else {
+ return (
+ react.createElement(Message, { key: msg.gam.uid, msg: msg.gam, details: details, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 137}} )
+ );
+ }
}
render() {
+ const { props, state } = this;
let messages = this.props.messages[this.state.station] || [];
+ if (messages.length > 50 * state.numPages) {
+ messages =
+ messages.slice(messages.length - (50 * state.numPages), messages.length);
+ }
let chatMessages = messages.map(this.buildMessage);
return (
- react.createElement('div', { className: "h-100 w-100 overflow-hidden flex flex-column" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 102}}
- , react.createElement('div', { className: "pl2 pt2 bb mb3" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 103}}
- , react.createElement('h2', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 104}}, this.state.circle)
- , react.createElement(ChatTabBar, { ...this.props, station: this.state.station, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 105}} )
+ react.createElement('div', { className: "h-100 w-100 overflow-hidden flex flex-column" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 152}}
+ , react.createElement('div', { className: "pl2 pt2 bb mb3" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 153}}
+ , react.createElement('h2', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 154}}, this.state.circle)
+ , react.createElement(ChatTabBar, { ...this.props, station: this.state.station, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 155}} )
)
- , react.createElement('div', { className: "overflow-y-scroll", style: { flexGrow: 1 }, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 107}}
+ , react.createElement('div', {
+ className: "overflow-y-scroll",
+ style: { flexGrow: 1 },
+ onScroll: this.onScroll, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 157}}
, chatMessages
+ , react.createElement('div', { ref: el => { this.scrollElement = el; }, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 162}})
)
, react.createElement(ChatInput, {
api: this.props.api,
configs: this.props.configs,
station: this.state.station,
circle: this.state.circle,
- placeholder: "Message...", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 110}} )
+ placeholder: "Message...", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 164}} )
)
)
}
@@ -57545,33 +57695,32 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
start() {
if (api.authTokens) {
this.initializeChat();
- //this.setCleanupTasks();
} else {
console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
}
}
- /*setCleanupTasks() {
- window.addEventListener("beforeunload", e => {
- api.bindPaths.forEach(p => {
- this.wipeSubscription(p);
- });
- });
- }
-
- wipeSubscription(path) {
- api.hall({
- wipe: {
- sub: [{
- hos: api.authTokens.ship,
- pax: path
- }]
- }
- });
- }*/
-
initializeChat() {
- api.bind('/primary', 'PUT', api.authTokens.ship, 'chat',
+ if (store.state.local) {
+ let path = [];
+ let msg = Object.keys(store.state.messages);
+ for (let i = 0; i < msg.length; i++) {
+ let cir = msg[i];
+ let len = store.state.messages[cir].length;
+ path.push(`${cir}/${len}`);
+ }
+ path = path.join('/');
+
+ api.bind(`/primary/${path}`, 'PUT', api.authTokens.ship, 'chat',
+ this.handleEvent.bind(this),
+ this.handleError.bind(this));
+ } else {
+ api.bind('/primary', 'PUT', api.authTokens.ship, 'chat',
+ this.handleEvent.bind(this),
+ this.handleError.bind(this));
+ }
+
+ api.bind('/updates', 'PUT', api.authTokens.ship, 'chat',
this.handleEvent.bind(this),
this.handleError.bind(this));
}
diff --git a/apps/chat/urbit/lib/chat.hoon b/apps/chat/urbit/lib/chat.hoon
index 588cfca7be..a724bcf3ce 100644
--- a/apps/chat/urbit/lib/chat.hoon
+++ b/apps/chat/urbit/lib/chat.hoon
@@ -16,8 +16,9 @@
::
+$ diff
$% [%hall-rumor rumor:hall]
- [%chat-streams streams]
+ [%chat-initial streams]
[%chat-update update]
+ [%chat-config streams]
==
::
+$ poke
@@ -49,6 +50,7 @@
+$ update
$% [%inbox con=config:hall]
[%message cir=circle:hall env=envelope:hall]
+ [%messages cir=circle:hall start=@ud end=@ud env=(list envelope:hall)]
[%config cir=circle:hall con=config:hall]
[%circles cir=(set name:hall)]
[%peers cir=circle:hall per=(set @p)]
diff --git a/apps/chat/urbit/mar/chat/streams.hoon b/apps/chat/urbit/mar/chat/config.hoon
similarity index 82%
rename from apps/chat/urbit/mar/chat/streams.hoon
rename to apps/chat/urbit/mar/chat/config.hoon
index 2b33cb3398..539091be26 100644
--- a/apps/chat/urbit/mar/chat/streams.hoon
+++ b/apps/chat/urbit/mar/chat/config.hoon
@@ -24,19 +24,20 @@
^- [@t ^json]
:- (crip (circ:en-tape:hall-json cir))
?~(con ~ (conf:enjs:hall-json u.con))
- ::
- :- %messages
- %- pairs
- %+ turn ~(tap by messages.str)
- |= [cir=circle:hall lis=(list envelope:hall)]
- ^- [@t ^json]
- :- (crip (circ:en-tape:hall-json cir))
- [%a (turn lis enve:enjs:hall-json)]
::
:- %circles :- %a
%+ turn ~(tap in circles.str)
|= nom=name:hall
[%s nom]
+ ::
+ :- %peers
+ %- pairs
+ %+ turn ~(tap by peers.str)
+ |= [cir=circle:hall per=(set @p)]
+ ^- [@t ^json]
+ :- (crip (circ:en-tape:hall-json cir))
+ [%a (turn ~(tap in per) ship)]
+ ::
==
--
::
diff --git a/apps/chat/urbit/mar/chat/initial.hoon b/apps/chat/urbit/mar/chat/initial.hoon
new file mode 100644
index 0000000000..99c7f8dc55
--- /dev/null
+++ b/apps/chat/urbit/mar/chat/initial.hoon
@@ -0,0 +1,56 @@
+::
+::
+/? 309
+::
+/- hall
+/+ chat, hall-json
+::
+|_ str=streams:chat
+++ grow
+ |%
+ ++ json
+ =, enjs:format
+ ^- ^json
+ %+ frond %initial
+ %- pairs
+ :~
+ ::
+ [%inbox (conf:enjs:hall-json inbox.str)]
+ ::
+ :- %configs
+ %- pairs
+ %+ turn ~(tap by configs.str)
+ |= [cir=circle:hall con=(unit config:hall)]
+ ^- [@t ^json]
+ :- (crip (circ:en-tape:hall-json cir))
+ ?~(con ~ (conf:enjs:hall-json u.con))
+ ::
+ :- %messages
+ %- pairs
+ %+ turn ~(tap by messages.str)
+ |= [cir=circle:hall lis=(list envelope:hall)]
+ ^- [@t ^json]
+ :- (crip (circ:en-tape:hall-json cir))
+ [%a (turn lis enve:enjs:hall-json)]
+ ::
+ :- %circles :- %a
+ %+ turn ~(tap in circles.str)
+ |= nom=name:hall
+ [%s nom]
+ ::
+ :- %peers
+ %- pairs
+ %+ turn ~(tap by peers.str)
+ |= [cir=circle:hall per=(set @p)]
+ ^- [@t ^json]
+ :- (crip (circ:en-tape:hall-json cir))
+ [%a (turn ~(tap in per) ship)]
+ ::
+ ==
+ --
+::
+++ grab
+ |%
+ ++ noun streams:chat
+ --
+--
diff --git a/apps/chat/urbit/mar/chat/update.hoon b/apps/chat/urbit/mar/chat/update.hoon
index 24ed4aa847..23a5c172a8 100644
--- a/apps/chat/urbit/mar/chat/update.hoon
+++ b/apps/chat/urbit/mar/chat/update.hoon
@@ -30,6 +30,18 @@
[%envelope (enve:enjs:hall-json env.upd)]
==
::
+ :: %messages
+ ?: =(%messages -.upd)
+ ?> ?=(%messages -.upd)
+ :- %messages
+ %- pairs
+ :~
+ [%circle (circ:enjs:hall-json cir.upd)]
+ [%start (numb start.upd)]
+ [%end (numb end.upd)]
+ [%envelopes [%a (turn env.upd enve:enjs:hall-json)]]
+ ==
+ ::
:: %config
?: =(%config -.upd)
?> ?=(%config -.upd)
@@ -39,6 +51,8 @@
[%circle (circ:enjs:hall-json cir.upd)]
[%config (conf:enjs:hall-json con.upd)]
==
+ ::
+ :: %circles
?: =(%circles -.upd)
?> ?=(%circles -.upd)
:- %circles
@@ -51,6 +65,16 @@
[%s nom]
==
::
+ :: %peers
+ ?: =(%peers -.upd)
+ ?> ?=(%peers -.upd)
+ :- %peers
+ %- pairs
+ :~
+ [%circle (circ:enjs:hall-json cir.upd)]
+ [%peers [%a (turn ~(tap in per.upd) ship:enjs:format)]]
+ ==
+ ::
:: %noop
[*@t *^json]
==