mirror of
https://github.com/urbit/shrub.git
synced 2024-12-25 13:04:17 +03:00
chat-js: improve subscription speed by doing two rounds of subscriptions and no longer subscribing to groups
This commit is contained in:
parent
0d3e409f7c
commit
221238c0fa
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -224,7 +224,7 @@ export class ChatScreen extends Component {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let group = Array.from(props.group.values());
|
let group = Array.from(props.permission.who.values());
|
||||||
|
|
||||||
const isinPopout = props.popout ? "popout/" : "";
|
const isinPopout = props.popout ? "popout/" : "";
|
||||||
|
|
||||||
@ -301,7 +301,6 @@ export class ChatScreen extends Component {
|
|||||||
station={props.station}
|
station={props.station}
|
||||||
owner={deSig(props.match.params.ship)}
|
owner={deSig(props.match.params.ship)}
|
||||||
ownerContact={ownerContact}
|
ownerContact={ownerContact}
|
||||||
permissions={props.permissions}
|
|
||||||
envelopes={props.envelopes}
|
envelopes={props.envelopes}
|
||||||
contacts={props.contacts}
|
contacts={props.contacts}
|
||||||
placeholder="Message..."
|
placeholder="Message..."
|
||||||
|
@ -422,36 +422,7 @@ export class ChatInput extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
readOnlyRender() {
|
render() {
|
||||||
const { props } = this;
|
|
||||||
let color = !!props.ownerContact
|
|
||||||
? uxToHex(props.ownerContact.color) : '000000';
|
|
||||||
|
|
||||||
let sigilClass = !!props.ownerContact
|
|
||||||
? "" : "mix-blend-diff";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="pa3 cf flex black bt b--gray4 o-50">
|
|
||||||
<div className="fl" style={{
|
|
||||||
marginTop: 4,
|
|
||||||
flexBasis: 24,
|
|
||||||
height: 24
|
|
||||||
}}>
|
|
||||||
<Sigil
|
|
||||||
ship={window.ship}
|
|
||||||
size={24}
|
|
||||||
color={`#${color}`}
|
|
||||||
classes={sigilClass}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="fr h-100 flex" style={{ flexGrow: 1, height: 28, paddingTop: 6, resize: "none" }}>
|
|
||||||
<p className="pl3">This chat is read only and you cannot post.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
writeAccessRender() {
|
|
||||||
const { props, state } = this;
|
const { props, state } = this;
|
||||||
|
|
||||||
let color = !!props.ownerContact
|
let color = !!props.ownerContact
|
||||||
@ -505,29 +476,4 @@ export class ChatInput extends Component {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
|
||||||
const { props, state } = this;
|
|
||||||
|
|
||||||
let writePermission = props.permissions[`/chat${props.station}/write`];
|
|
||||||
if (writePermission) {
|
|
||||||
if (writePermission.kind === 'black') {
|
|
||||||
// black
|
|
||||||
if (writePermission.who.has(window.ship)) {
|
|
||||||
return this.readOnlyRender();
|
|
||||||
} else {
|
|
||||||
return this.writeAccessRender();
|
|
||||||
}
|
|
||||||
} else if (writePermission.kind === 'white') {
|
|
||||||
// white
|
|
||||||
if (writePermission.who.has(window.ship)) {
|
|
||||||
return this.writeAccessRender();
|
|
||||||
} else {
|
|
||||||
return this.readOnlyRender();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return this.writeAccessRender();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ export class InviteSearch extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
peerUpdate() {
|
peerUpdate() {
|
||||||
let groups = Array.from(Object.keys(this.props.groups));
|
let groups = Array.from(Object.keys(this.props.permissions));
|
||||||
groups = groups.filter(e => !e.startsWith("/~/"))
|
groups = groups.filter(e => !e.startsWith("/~/"))
|
||||||
.map(e => {
|
.map(e => {
|
||||||
let eachGroup = new Set();
|
let eachGroup = new Set();
|
||||||
@ -49,15 +49,17 @@ export class InviteSearch extends Component {
|
|||||||
let peers = [],
|
let peers = [],
|
||||||
peerSet = new Set(),
|
peerSet = new Set(),
|
||||||
contacts = new Map;
|
contacts = new Map;
|
||||||
Object.keys(this.props.groups).map(group => {
|
|
||||||
if (this.props.groups[group].size > 0) {
|
Object.keys(this.props.permissions).map(group => {
|
||||||
let groupEntries = this.props.groups[group].values();
|
if (this.props.permissions[group].who.size > 0) {
|
||||||
|
let groupEntries = this.props.permissions[group].who.values();
|
||||||
for (let member of groupEntries) {
|
for (let member of groupEntries) {
|
||||||
peerSet.add(member);
|
peerSet.add(member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.contacts[group]) {
|
if (this.props.contacts[group]) {
|
||||||
let groupEntries = this.props.groups[group].values();
|
let groupEntries = this.props.permissions[group].who.values();
|
||||||
for (let member of groupEntries) {
|
for (let member of groupEntries) {
|
||||||
if (this.props.contacts[group][member]) {
|
if (this.props.contacts[group][member]) {
|
||||||
if (contacts.has(member)) {
|
if (contacts.has(member)) {
|
||||||
|
@ -259,7 +259,7 @@ export class NewScreen extends Component {
|
|||||||
Selected groups or ships will be able to post to chat
|
Selected groups or ships will be able to post to chat
|
||||||
</p>
|
</p>
|
||||||
<InviteSearch
|
<InviteSearch
|
||||||
groups={props.groups}
|
permissions={props.permissions}
|
||||||
contacts={props.contacts}
|
contacts={props.contacts}
|
||||||
associations={props.associations}
|
associations={props.associations}
|
||||||
groupResults={true}
|
groupResults={true}
|
||||||
|
@ -99,7 +99,7 @@ export class Root extends Component {
|
|||||||
<NewScreen
|
<NewScreen
|
||||||
api={api}
|
api={api}
|
||||||
inbox={state.inbox || {}}
|
inbox={state.inbox || {}}
|
||||||
groups={state.groups || {}}
|
permissions={state.permissions || {}}
|
||||||
contacts={state.contacts || {}}
|
contacts={state.contacts || {}}
|
||||||
associations={associations.contacts}
|
associations={associations.contacts}
|
||||||
{...props}
|
{...props}
|
||||||
@ -119,7 +119,6 @@ export class Root extends Component {
|
|||||||
station = '/~' + station;
|
station = '/~' + station;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
spinner={state.spinner}
|
spinner={state.spinner}
|
||||||
@ -168,8 +167,11 @@ export class Root extends Component {
|
|||||||
let association =
|
let association =
|
||||||
station in associations["chat"] ? associations.chat[station] : {};
|
station in associations["chat"] ? associations.chat[station] : {};
|
||||||
|
|
||||||
|
let permission =
|
||||||
let group = state.groups[station] || new Set([]);
|
station in state.permissions ? state.permissions[station] : {
|
||||||
|
who: new Set([]),
|
||||||
|
kind: 'white'
|
||||||
|
};
|
||||||
let popout = props.match.url.includes("/popout/");
|
let popout = props.match.url.includes("/popout/");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -190,9 +192,8 @@ export class Root extends Component {
|
|||||||
length={mailbox.config.length}
|
length={mailbox.config.length}
|
||||||
envelopes={mailbox.envelopes}
|
envelopes={mailbox.envelopes}
|
||||||
inbox={state.inbox}
|
inbox={state.inbox}
|
||||||
group={group}
|
|
||||||
contacts={roomContacts}
|
contacts={roomContacts}
|
||||||
permissions={state.permissions}
|
permission={permission}
|
||||||
pendingMessages={state.pendingMessages}
|
pendingMessages={state.pendingMessages}
|
||||||
popout={popout}
|
popout={popout}
|
||||||
sidebarShown={state.sidebarShown}
|
sidebarShown={state.sidebarShown}
|
||||||
@ -255,7 +256,6 @@ export class Root extends Component {
|
|||||||
if (sig) {
|
if (sig) {
|
||||||
station = '/~' + station;
|
station = '/~' + station;
|
||||||
}
|
}
|
||||||
let group = state.groups[station] || new Set([]);
|
|
||||||
|
|
||||||
let popout = props.match.url.includes("/popout/");
|
let popout = props.match.url.includes("/popout/");
|
||||||
|
|
||||||
@ -280,12 +280,11 @@ export class Root extends Component {
|
|||||||
station={station}
|
station={station}
|
||||||
association={association}
|
association={association}
|
||||||
permission={permission}
|
permission={permission}
|
||||||
groups={state.groups || {}}
|
permissions={state.permissions || {}}
|
||||||
contacts={state.contacts || {}}
|
contacts={state.contacts || {}}
|
||||||
associations={associations.contacts}
|
associations={associations.contacts}
|
||||||
api={api}
|
api={api}
|
||||||
station={station}
|
station={station}
|
||||||
group={group}
|
|
||||||
inbox={state.inbox}
|
inbox={state.inbox}
|
||||||
popout={popout}
|
popout={popout}
|
||||||
sidebarShown={state.sidebarShown}
|
sidebarShown={state.sidebarShown}
|
||||||
|
@ -223,7 +223,7 @@ export class SettingsScreen extends Component {
|
|||||||
group to add this chat to.
|
group to add this chat to.
|
||||||
</p>
|
</p>
|
||||||
<InviteSearch
|
<InviteSearch
|
||||||
groups={props.groups}
|
permissions={props.permissions}
|
||||||
contacts={props.contacts}
|
contacts={props.contacts}
|
||||||
associations={props.associations}
|
associations={props.associations}
|
||||||
groupResults={true}
|
groupResults={true}
|
||||||
@ -340,7 +340,7 @@ export class SettingsScreen extends Component {
|
|||||||
const { props, state } = this;
|
const { props, state } = this;
|
||||||
const isinPopout = this.props.popout ? "popout/" : "";
|
const isinPopout = this.props.popout ? "popout/" : "";
|
||||||
|
|
||||||
let writeGroup = Array.from(props.group.values());
|
let permission = Array.from(props.permission.who.values());
|
||||||
|
|
||||||
if (!!state.isLoading) {
|
if (!!state.isLoading) {
|
||||||
let text = state.loadingText || 'Working...';
|
let text = state.loadingText || 'Working...';
|
||||||
@ -378,7 +378,7 @@ export class SettingsScreen extends Component {
|
|||||||
<ChatTabBar
|
<ChatTabBar
|
||||||
{...props}
|
{...props}
|
||||||
station={props.station}
|
station={props.station}
|
||||||
numPeers={writeGroup.length}
|
numPeers={permission.length}
|
||||||
host={props.match.params.ship}
|
host={props.match.params.ship}
|
||||||
api={props.api}
|
api={props.api}
|
||||||
/>
|
/>
|
||||||
@ -423,7 +423,7 @@ export class SettingsScreen extends Component {
|
|||||||
<ChatTabBar
|
<ChatTabBar
|
||||||
{...props}
|
{...props}
|
||||||
station={props.station}
|
station={props.station}
|
||||||
numPeers={writeGroup.length}
|
numPeers={permission.length}
|
||||||
isOwner={deSig(props.match.params.ship) === window.ship}
|
isOwner={deSig(props.match.params.ship) === window.ship}
|
||||||
popout={this.props.popout}
|
popout={this.props.popout}
|
||||||
/>
|
/>
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
|
|
||||||
export class GroupUpdateReducer {
|
|
||||||
reduce(json, state) {
|
|
||||||
let data = _.get(json, 'group-update', false);
|
|
||||||
if (data) {
|
|
||||||
this.add(data, state);
|
|
||||||
this.remove(data, state);
|
|
||||||
this.bundle(data, state);
|
|
||||||
this.unbundle(data, state);
|
|
||||||
this.keys(data, state);
|
|
||||||
this.path(data, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add(json, state) {
|
|
||||||
let data = _.get(json, 'add', false);
|
|
||||||
if (data) {
|
|
||||||
for (let member of data.members) {
|
|
||||||
state.groups[data.path].add(member);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(json, state) {
|
|
||||||
let data = _.get(json, 'remove', false);
|
|
||||||
if (data) {
|
|
||||||
for (let member of data.members) {
|
|
||||||
state.groups[data.path].delete(member);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bundle(json, state) {
|
|
||||||
|
|
||||||
let data = _.get(json, 'bundle', false);
|
|
||||||
if (data) {
|
|
||||||
state.groups[data.path] = new Set();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unbundle(json, state) {
|
|
||||||
let data = _.get(json, 'unbundle', false);
|
|
||||||
if (data) {
|
|
||||||
delete state.groups[data.path];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keys(json, state) {
|
|
||||||
let data = _.get(json, 'keys', false);
|
|
||||||
if (data) {
|
|
||||||
state.groupKeys = new Set(data.keys);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path(json, state) {
|
|
||||||
let data = _.get(json, 'path', false);
|
|
||||||
if (data) {
|
|
||||||
state.groups[data.path] = new Set([data.members]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -9,13 +9,6 @@ export class InitialReducer {
|
|||||||
state.chatInitialized = true;
|
state.chatInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = _.get(json, 'group-initial', false);
|
|
||||||
if (data) {
|
|
||||||
for (let group in data) {
|
|
||||||
state.groups[group] = new Set(data[group]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data = _.get(json, 'permission-initial', false);
|
data = _.get(json, 'permission-initial', false);
|
||||||
if (data) {
|
if (data) {
|
||||||
for (let perm in data) {
|
for (let perm in data) {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { InitialReducer } from '/reducers/initial';
|
import { InitialReducer } from '/reducers/initial';
|
||||||
import { GroupUpdateReducer } from '/reducers/group-update';
|
|
||||||
import { ContactUpdateReducer } from '/reducers/contact-update';
|
import { ContactUpdateReducer } from '/reducers/contact-update';
|
||||||
import { ChatUpdateReducer } from '/reducers/chat-update';
|
import { ChatUpdateReducer } from '/reducers/chat-update';
|
||||||
import { InviteUpdateReducer } from '/reducers/invite-update';
|
import { InviteUpdateReducer } from '/reducers/invite-update';
|
||||||
@ -13,7 +12,6 @@ class Store {
|
|||||||
this.state = {
|
this.state = {
|
||||||
inbox: {},
|
inbox: {},
|
||||||
chatSynced: {},
|
chatSynced: {},
|
||||||
groups: {},
|
|
||||||
contacts: {},
|
contacts: {},
|
||||||
permissions: {},
|
permissions: {},
|
||||||
invites: {},
|
invites: {},
|
||||||
@ -28,7 +26,6 @@ class Store {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.initialReducer = new InitialReducer();
|
this.initialReducer = new InitialReducer();
|
||||||
this.groupUpdateReducer = new GroupUpdateReducer();
|
|
||||||
this.permissionUpdateReducer = new PermissionUpdateReducer();
|
this.permissionUpdateReducer = new PermissionUpdateReducer();
|
||||||
this.contactUpdateReducer = new ContactUpdateReducer();
|
this.contactUpdateReducer = new ContactUpdateReducer();
|
||||||
this.chatUpdateReducer = new ChatUpdateReducer();
|
this.chatUpdateReducer = new ChatUpdateReducer();
|
||||||
@ -47,7 +44,6 @@ class Store {
|
|||||||
|
|
||||||
console.log(json);
|
console.log(json);
|
||||||
this.initialReducer.reduce(json, this.state);
|
this.initialReducer.reduce(json, this.state);
|
||||||
this.groupUpdateReducer.reduce(json, this.state);
|
|
||||||
this.permissionUpdateReducer.reduce(json, this.state);
|
this.permissionUpdateReducer.reduce(json, this.state);
|
||||||
this.contactUpdateReducer.reduce(json, this.state);
|
this.contactUpdateReducer.reduce(json, this.state);
|
||||||
this.chatUpdateReducer.reduce(json, this.state);
|
this.chatUpdateReducer.reduce(json, this.state);
|
||||||
|
@ -5,19 +5,27 @@ import urbitOb from 'urbit-ob';
|
|||||||
|
|
||||||
|
|
||||||
export class Subscription {
|
export class Subscription {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.firstRoundSubscriptionComplete = false;
|
||||||
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
if (api.authTokens) {
|
if (api.authTokens) {
|
||||||
this.initializeChat();
|
this.firstRoundSubscription();
|
||||||
} else {
|
} else {
|
||||||
console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
|
console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeChat() {
|
firstRoundSubscription() {
|
||||||
api.bind('/primary', 'PUT', api.authTokens.ship, 'chat-view',
|
api.bind('/primary', 'PUT', api.authTokens.ship, 'chat-view',
|
||||||
this.handleEvent.bind(this),
|
this.handleEvent.bind(this),
|
||||||
this.handleError.bind(this),
|
this.handleError.bind(this),
|
||||||
this.handleQuitAndResubscribe.bind(this));
|
this.handleQuitAndResubscribe.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
secondRoundSubscriptions() {
|
||||||
api.bind('/synced', 'PUT', api.authTokens.ship, 'chat-hook',
|
api.bind('/synced', 'PUT', api.authTokens.ship, 'chat-hook',
|
||||||
this.handleEvent.bind(this),
|
this.handleEvent.bind(this),
|
||||||
this.handleError.bind(this),
|
this.handleError.bind(this),
|
||||||
@ -26,10 +34,6 @@ export class Subscription {
|
|||||||
this.handleEvent.bind(this),
|
this.handleEvent.bind(this),
|
||||||
this.handleError.bind(this),
|
this.handleError.bind(this),
|
||||||
this.handleQuitAndResubscribe.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, 'permission-store',
|
api.bind('/all', 'PUT', api.authTokens.ship, 'permission-store',
|
||||||
this.handleEvent.bind(this),
|
this.handleEvent.bind(this),
|
||||||
this.handleError.bind(this),
|
this.handleError.bind(this),
|
||||||
@ -49,6 +53,10 @@ export class Subscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleEvent(diff) {
|
handleEvent(diff) {
|
||||||
|
if (!this.firstRoundSubscriptionComplete) {
|
||||||
|
this.firstRoundSubscriptionComplete = true;
|
||||||
|
this.secondRoundSubscriptions();
|
||||||
|
}
|
||||||
store.handleEvent(diff);
|
store.handleEvent(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user