Compare commits

..

5 Commits

Author SHA1 Message Date
Tom Moor 2aaad03270 refactor 2020-08-20 19:05:48 -07:00
Tom Moor 9252683260 fix: SocketPresence account for socket changing 2020-08-20 00:06:51 -07:00
Tom Moor f5748eb5e7 check connection on page visibility change 2020-08-19 22:51:18 -07:00
Tom Moor 0555fd2caa pref: JS bundling improvements (#1461)
* perf: Split only initial vendors
2020-08-17 22:09:12 -07:00
Tom Moor d885252fb0 fix: Mobile style fixes and improvements (#1459)
* fixes #1457 – check for matchMedia function before using it

* fixes: Depth issues
closes #1458

* fixes: Long breadcrumbs cause horizontal overflow

* fix: Improve tabs and overflow on mobile
2020-08-17 00:08:22 -07:00
5 changed files with 90 additions and 31 deletions
+30 -10
View File
@@ -3,7 +3,7 @@ import { find } from "lodash";
import { observable } from "mobx";
import { inject, observer } from "mobx-react";
import * as React from "react";
import io from "socket.io-client";
import io, { Socket } from "socket.io-client";
import AuthStore from "stores/AuthStore";
import CollectionsStore from "stores/CollectionsStore";
import DocumentPresenceStore from "stores/DocumentPresenceStore";
@@ -13,6 +13,7 @@ import MembershipsStore from "stores/MembershipsStore";
import PoliciesStore from "stores/PoliciesStore";
import UiStore from "stores/UiStore";
import ViewsStore from "stores/ViewsStore";
import { getVisibilityListener, getPageVisible } from "utils/pageVisibility";
export const SocketContext: any = React.createContext();
@@ -31,9 +32,35 @@ type Props = {
@observer
class SocketProvider extends React.Component<Props> {
@observable socket;
@observable socket: Socket;
componentDidMount() {
this.createConnection();
document.addEventListener(getVisibilityListener(), this.checkConnection);
}
componentWillUnmount() {
if (this.socket) {
this.socket.authenticated = false;
this.socket.disconnect();
}
document.removeEventListener(getVisibilityListener(), this.checkConnection);
}
checkConnection = () => {
if (this.socket && this.socket.disconnected && getPageVisible()) {
// null-ifying this reference is important, do not remove. Without it
// references to old sockets are potentially held in context
this.socket.close();
this.socket = null;
this.createConnection();
}
};
createConnection = () => {
this.socket = io(window.location.origin, {
path: "/realtime",
transports: ["websocket"],
@@ -264,14 +291,7 @@ class SocketProvider extends React.Component<Props> {
this.socket.on("user.presence", (event) => {
presence.touch(event.documentId, event.userId, event.isEditing);
});
}
componentWillUnmount() {
if (this.socket) {
this.socket.disconnect();
this.socket.authenticated = false;
}
}
};
render() {
return (
@@ -41,7 +41,7 @@ export default class SocketPresence extends React.Component<Props> {
}
setupOnce = () => {
if (this.context && !this.previousContext) {
if (this.context && this.context !== this.previousContext) {
this.previousContext = this.context;
if (this.context.authenticated) {
+25
View File
@@ -0,0 +1,25 @@
// @flow
let hidden = "hidden";
let visibilityChange = "visibilitychange";
if ("hidden" in document) {
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if ("mozHidden" in document) {
// Firefox up to v17
hidden = "mozHidden";
visibilityChange = "mozvisibilitychange";
} else if ("webkitHidden" in document) {
// Chrome up to v32, Android up to v4.4, Blackberry up to v10
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
export function getVisibilityListener(): string {
return visibilityChange;
}
export function getPageVisible(): boolean {
// $FlowFixMe
return !document[hidden];
}
+28 -15
View File
@@ -10,30 +10,30 @@ require('dotenv').config({ silent: true });
module.exports = {
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
filename: '[name].[hash].js',
publicPath: '/static/',
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: [
path.join(__dirname, 'node_modules')
],
include: [
path.join(__dirname, 'app'),
path.join(__dirname, 'shared'),
],
options: {
cacheDirectory: true
}
test: /\.js$/,
loader: 'babel-loader',
exclude: [
path.join(__dirname, 'node_modules')
],
include: [
path.join(__dirname, 'app'),
path.join(__dirname, 'shared'),
],
options: {
cacheDirectory: true
}
},
// inline base64 URLs for <=8k images, direct URLs for the rest
{ test: /\.(png|jpg|svg)$/, loader: 'url-loader' },
{
test: /\.woff$/,
loader: 'url-loader?limit=1&mimetype=application/font-woff&name=public/fonts/[name].[ext]',
test: /\.woff$/,
loader: 'url-loader?limit=1&mimetype=application/font-woff&name=public/fonts/[name].[ext]',
},
{ test: /\.md/, loader: 'raw-loader' },
]
@@ -64,4 +64,17 @@ module.exports = {
stats: {
assets: false,
},
optimization: {
runtimeChunk: 'single',
moduleIds: 'hashed',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'initial',
},
},
},
}
};
+6 -5
View File
@@ -7,17 +7,18 @@ const TerserPlugin = require('terser-webpack-plugin');
commonWebpackConfig = require('./webpack.config');
productionWebpackConfig = Object.assign(commonWebpackConfig, {
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].[contenthash].js',
publicPath: '/static/',
},
cache: true,
mode: "production",
devtool: 'source-map',
entry: ['./app/index'],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.[hash].js',
publicPath: '/static/',
},
stats: "normal",
optimization: {
...commonWebpackConfig.optimization,
minimizer: [
new TerserPlugin({
terserOptions: {