mirror of
https://github.com/urbit/shrub.git
synced 2024-12-24 20:47:27 +03:00
Merge pull request #2616 from urbit/two-round
chat-js: improve subscription speed by doing two rounds of subscriptions and no longer subscribing to groups
This commit is contained in:
commit
8f1655171d
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/" : "";
|
||||
|
||||
@ -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..."
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ 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();
|
||||
@ -56,6 +57,7 @@ export class InviteSearch extends Component {
|
||||
peerSet.add(member);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.props.contacts[group]) {
|
||||
let groupEntries = this.props.groups[group].values();
|
||||
for (let member of groupEntries) {
|
||||
|
@ -216,6 +216,11 @@ export class NewScreen extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
let groups = {};
|
||||
Object.keys(props.permissions).forEach((pem) => {
|
||||
groups[pem] = props.permissions[pem].who;
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
@ -259,7 +264,7 @@ export class NewScreen extends Component {
|
||||
Selected groups or ships will be able to post to chat
|
||||
</p>
|
||||
<InviteSearch
|
||||
groups={props.groups}
|
||||
groups={groups}
|
||||
contacts={props.contacts}
|
||||
associations={props.associations}
|
||||
groupResults={true}
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
/>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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);
|
||||
|
@ -5,50 +5,46 @@ 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() {
|
||||
api.bind('/primary', 'PUT', api.authTokens.ship, 'chat-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('/synced', 'PUT', api.authTokens.ship, 'chat-hook',
|
||||
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, 'permission-store',
|
||||
this.handleEvent.bind(this),
|
||||
this.handleError.bind(this),
|
||||
this.handleQuitAndResubscribe.bind(this));
|
||||
api.bind('/primary', 'PUT', api.authTokens.ship, 'contact-view',
|
||||
this.handleEvent.bind(this),
|
||||
this.handleError.bind(this),
|
||||
this.handleQuitAndResubscribe.bind(this));
|
||||
api.bind('/app-name/chat', 'PUT', api.authTokens.ship, 'metadata-store',
|
||||
this.handleEvent.bind(this),
|
||||
this.handleError.bind(this),
|
||||
this.handleQuitAndResubscribe.bind(this));
|
||||
api.bind('/app-name/contacts', 'PUT', api.authTokens.ship, 'metadata-store',
|
||||
this.handleEvent.bind(this),
|
||||
this.handleError.bind(this),
|
||||
this.handleQuitAndResubscribe.bind(this));
|
||||
() => {
|
||||
this.subscribe(path, app);
|
||||
});
|
||||
}
|
||||
|
||||
firstRoundSubscription() {
|
||||
this.subscribe('/primary', 'chat-view');
|
||||
}
|
||||
|
||||
secondRoundSubscriptions() {
|
||||
this.subscribe('/synced', 'chat-hook');
|
||||
this.subscribe('/primary', 'invite-view');
|
||||
this.subscribe('/all', 'permission-store');
|
||||
this.subscribe('/primary', 'contact-view');
|
||||
this.subscribe('/app-name/chat', 'metadata-store');
|
||||
this.subscribe('/app-name/contacts', 'metadata-store');
|
||||
}
|
||||
|
||||
handleEvent(diff) {
|
||||
if (!this.firstRoundSubscriptionComplete) {
|
||||
this.firstRoundSubscriptionComplete = true;
|
||||
this.secondRoundSubscriptions();
|
||||
}
|
||||
store.handleEvent(diff);
|
||||
}
|
||||
|
||||
@ -56,14 +52,6 @@ export class Subscription {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
handleQuitSilently(quit) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
handleQuitAndResubscribe(quit) {
|
||||
// TODO: resubscribe
|
||||
}
|
||||
|
||||
fetchMessages(start, end, path) {
|
||||
console.log(start, end, path);
|
||||
fetch(`/~chat/paginate/${start}/${end}${path}`)
|
||||
|
Loading…
Reference in New Issue
Block a user