chat-js: improve subscription speed by doing two rounds of subscriptions and no longer subscribing to groups

This commit is contained in:
Logan Allen 2020-03-26 17:41:11 -04:00
parent 0d3e409f7c
commit 221238c0fa
12 changed files with 38 additions and 160 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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/" : "";
@ -301,7 +301,6 @@ export class ChatScreen extends Component {
station={props.station}
owner={deSig(props.match.params.ship)}
ownerContact={ownerContact}
permissions={props.permissions}
envelopes={props.envelopes}
contacts={props.contacts}
placeholder="Message..."

View File

@ -422,36 +422,7 @@ export class ChatInput extends Component {
});
}
readOnlyRender() {
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() {
render() {
const { props, state } = this;
let color = !!props.ownerContact
@ -505,29 +476,4 @@ export class ChatInput extends Component {
</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();
}
}
}

View File

@ -30,7 +30,7 @@ export class InviteSearch extends Component {
}
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("/~/"))
.map(e => {
let eachGroup = new Set();
@ -49,15 +49,17 @@ export class InviteSearch extends Component {
let peers = [],
peerSet = new Set(),
contacts = new Map;
Object.keys(this.props.groups).map(group => {
if (this.props.groups[group].size > 0) {
let groupEntries = this.props.groups[group].values();
Object.keys(this.props.permissions).map(group => {
if (this.props.permissions[group].who.size > 0) {
let groupEntries = this.props.permissions[group].who.values();
for (let member of groupEntries) {
peerSet.add(member);
}
}
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) {
if (this.props.contacts[group][member]) {
if (contacts.has(member)) {

View File

@ -259,7 +259,7 @@ export class NewScreen extends Component {
Selected groups or ships will be able to post to chat
</p>
<InviteSearch
groups={props.groups}
permissions={props.permissions}
contacts={props.contacts}
associations={props.associations}
groupResults={true}

View File

@ -99,7 +99,7 @@ export class Root extends Component {
<NewScreen
api={api}
inbox={state.inbox || {}}
groups={state.groups || {}}
permissions={state.permissions || {}}
contacts={state.contacts || {}}
associations={associations.contacts}
{...props}
@ -119,7 +119,6 @@ export class Root extends Component {
station = '/~' + station;
}
return (
<Skeleton
spinner={state.spinner}
@ -168,8 +167,11 @@ export class Root extends Component {
let association =
station in associations["chat"] ? associations.chat[station] : {};
let group = state.groups[station] || new Set([]);
let permission =
station in state.permissions ? state.permissions[station] : {
who: new Set([]),
kind: 'white'
};
let popout = props.match.url.includes("/popout/");
return (
@ -190,9 +192,8 @@ export class Root extends Component {
length={mailbox.config.length}
envelopes={mailbox.envelopes}
inbox={state.inbox}
group={group}
contacts={roomContacts}
permissions={state.permissions}
permission={permission}
pendingMessages={state.pendingMessages}
popout={popout}
sidebarShown={state.sidebarShown}
@ -255,7 +256,6 @@ export class Root extends Component {
if (sig) {
station = '/~' + station;
}
let group = state.groups[station] || new Set([]);
let popout = props.match.url.includes("/popout/");
@ -280,12 +280,11 @@ export class Root extends Component {
station={station}
association={association}
permission={permission}
groups={state.groups || {}}
permissions={state.permissions || {}}
contacts={state.contacts || {}}
associations={associations.contacts}
api={api}
station={station}
group={group}
inbox={state.inbox}
popout={popout}
sidebarShown={state.sidebarShown}

View File

@ -223,7 +223,7 @@ export class SettingsScreen extends Component {
group to add this chat to.
</p>
<InviteSearch
groups={props.groups}
permissions={props.permissions}
contacts={props.contacts}
associations={props.associations}
groupResults={true}
@ -340,7 +340,7 @@ export class SettingsScreen extends Component {
const { props, state } = this;
const isinPopout = this.props.popout ? "popout/" : "";
let writeGroup = Array.from(props.group.values());
let permission = Array.from(props.permission.who.values());
if (!!state.isLoading) {
let text = state.loadingText || 'Working...';
@ -378,7 +378,7 @@ export class SettingsScreen extends Component {
<ChatTabBar
{...props}
station={props.station}
numPeers={writeGroup.length}
numPeers={permission.length}
host={props.match.params.ship}
api={props.api}
/>
@ -423,7 +423,7 @@ export class SettingsScreen extends Component {
<ChatTabBar
{...props}
station={props.station}
numPeers={writeGroup.length}
numPeers={permission.length}
isOwner={deSig(props.match.params.ship) === window.ship}
popout={this.props.popout}
/>

View File

@ -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]);
}
}
}

View File

@ -9,13 +9,6 @@ export class InitialReducer {
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);
if (data) {
for (let perm in data) {

View File

@ -1,5 +1,4 @@
import { InitialReducer } from '/reducers/initial';
import { GroupUpdateReducer } from '/reducers/group-update';
import { ContactUpdateReducer } from '/reducers/contact-update';
import { ChatUpdateReducer } from '/reducers/chat-update';
import { InviteUpdateReducer } from '/reducers/invite-update';
@ -13,7 +12,6 @@ class Store {
this.state = {
inbox: {},
chatSynced: {},
groups: {},
contacts: {},
permissions: {},
invites: {},
@ -28,7 +26,6 @@ class Store {
};
this.initialReducer = new InitialReducer();
this.groupUpdateReducer = new GroupUpdateReducer();
this.permissionUpdateReducer = new PermissionUpdateReducer();
this.contactUpdateReducer = new ContactUpdateReducer();
this.chatUpdateReducer = new ChatUpdateReducer();
@ -47,7 +44,6 @@ class Store {
console.log(json);
this.initialReducer.reduce(json, this.state);
this.groupUpdateReducer.reduce(json, this.state);
this.permissionUpdateReducer.reduce(json, this.state);
this.contactUpdateReducer.reduce(json, this.state);
this.chatUpdateReducer.reduce(json, this.state);

View File

@ -5,19 +5,27 @@ import urbitOb from 'urbit-ob';
export class Subscription {
constructor() {
this.firstRoundSubscriptionComplete = false;
}
start() {
if (api.authTokens) {
this.initializeChat();
this.firstRoundSubscription();
} else {
console.error("~~~ ERROR: Must set api.authTokens before operation ~~~");
}
}
initializeChat() {
firstRoundSubscription() {
api.bind('/primary', 'PUT', api.authTokens.ship, 'chat-view',
this.handleEvent.bind(this),
this.handleError.bind(this),
this.handleQuitAndResubscribe.bind(this));
}
secondRoundSubscriptions() {
api.bind('/synced', 'PUT', api.authTokens.ship, 'chat-hook',
this.handleEvent.bind(this),
this.handleError.bind(this),
@ -26,10 +34,6 @@ export class Subscription {
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, 'permission-store',
this.handleEvent.bind(this),
this.handleError.bind(this),
@ -49,6 +53,10 @@ export class Subscription {
}
handleEvent(diff) {
if (!this.firstRoundSubscriptionComplete) {
this.firstRoundSubscriptionComplete = true;
this.secondRoundSubscriptions();
}
store.handleEvent(diff);
}