Skip to content
This repository was archived by the owner on Oct 11, 2022. It is now read-only.

Commit e69a639

Browse files
authored
Merge pull request #3302 from withspectrum/2.4.7
2.4.7
2 parents 00c1e0f + 1e1682f commit e69a639

File tree

66 files changed

+1142
-211
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1142
-211
lines changed

analytics/utils/transformations.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type {
1010
DBMessage,
1111
DBUsersThreads,
1212
} from 'shared/types';
13-
import { getTruthyValuesFromObject } from './truthy-values';
13+
import { getTruthyValuesFromObject } from 'shared/truthy-values';
1414

1515
type AnalyticsChannel = {
1616
id: ?string,

api/models/utils.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ export const getAu = (range: Timeframe) => {
5353
const { current } = parseRange(range);
5454
return db
5555
.table('users')
56-
.filter(db.row('lastSeen').during(db.now().sub(current), db.now()))
56+
.filter(row =>
57+
row
58+
.hasFields('lastSeen')
59+
.and(row('lastSeen').during(db.now().sub(current), db.now()))
60+
)
5761
.count()
5862
.default(0)
5963
.run();
@@ -102,6 +106,8 @@ export const getCount = (table: string, filter: mixed) => {
102106
export const getCoreMetrics = () => {
103107
return db
104108
.table('coreMetrics')
109+
.orderBy(db.desc('date'))
110+
.limit(90)
105111
.orderBy('date')
106112
.run();
107113
};

chronos/models/coreMetrics.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ export const getAu = (range: string) => {
3838
const RANGE = parseRange(range);
3939
return db
4040
.table('users')
41-
.filter(db.row('lastSeen').during(db.now().sub(RANGE), db.now()))
41+
.filter(row =>
42+
row
43+
.hasFields('lastSeen')
44+
.and(row('lastSeen').during(db.now().sub(RANGE), db.now()))
45+
)
4246
.count()
4347
.default(0)
4448
.run();

chronos/models/usersSettings.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@ export const getUsersForDigest = (
2828
// save some processing time by making sure the user has a username
2929
.filter(row => row.hasFields('username').and(row('username').ne(null)))
3030
// save some processing time by making sure the user was active in the last month
31-
.filter(
32-
db.row('lastSeen').during(db.now().sub(60 * 60 * 24 * 30), db.now())
31+
.filter(row =>
32+
row
33+
.hasFields('lastSeen')
34+
.and(
35+
row('lastSeen').during(db.now().sub(60 * 60 * 24 * 30), db.now())
36+
)
3337
)
3438
.pluck(['userId', 'email', 'firstName', 'name', 'username'])
3539
.distinct()

config-overrides.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const debug = require('debug')('build:config-overrides');
88
const webpack = require('webpack');
99
const { injectBabelPlugin } = require('react-app-rewired');
1010
const rewireStyledComponents = require('react-app-rewire-styled-components');
11+
const rewireReactHotLoader = require('react-app-rewire-hot-loader');
1112
const swPrecachePlugin = require('sw-precache-webpack-plugin');
1213
const fs = require('fs');
1314
const path = require('path');
@@ -74,15 +75,19 @@ const transpileShared = config => {
7475
module.exports = function override(config, env) {
7576
if (process.env.NODE_ENV === 'development') {
7677
config.output.path = path.join(__dirname, './build');
78+
config = rewireReactHotLoader(config, env);
79+
config.plugins.push(
80+
WriteFilePlugin({
81+
log: true,
82+
useHashIndex: false,
83+
})
84+
);
7785
}
7886
config.plugins.push(
7987
new ReactLoadablePlugin({
8088
filename: './build/react-loadable.json',
8189
})
8290
);
83-
if (process.env.NODE_ENV === 'production') {
84-
removeEslint(config);
85-
}
8691
config = injectBabelPlugin('react-loadable/babel', config);
8792
config = transpileShared(config);
8893
// Filter the default serviceworker plugin, add offline plugin instead
@@ -126,14 +131,6 @@ module.exports = function override(config, env) {
126131
if (process.env.BUNDLE_BUDDY === 'true') {
127132
config.plugins.push(new BundleBuddyWebpackPlugin());
128133
}
129-
if (process.env.NODE_ENV === 'development') {
130-
config.plugins.push(
131-
WriteFilePlugin({
132-
log: true,
133-
useHashIndex: false,
134-
})
135-
);
136-
}
137134
config.plugins.unshift(
138135
new webpack.optimize.CommonsChunkPlugin({
139136
names: ['bootstrap'],
@@ -142,6 +139,7 @@ module.exports = function override(config, env) {
142139
})
143140
);
144141
if (process.env.NODE_ENV === 'production') {
142+
removeEslint(config);
145143
config.plugins.push(
146144
new webpack.DefinePlugin({
147145
'process.env': {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
describe('Renders conceirge page ', () => {
2+
beforeEach(() => {
3+
cy.visit(`/pricing/concierge`);
4+
});
5+
6+
it('should render key conceirge page components', () => {
7+
cy.get('[data-cy="concierge-page"]').should('be.visible');
8+
});
9+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// flow-typed signature: fa2daa44307abd285e881b992fa9d76c
2+
// flow-typed version: <<STUB>>/electron-context-menu_v0.9.1/flow_v0.66.0
3+
4+
/**
5+
* This is an autogenerated libdef stub for:
6+
*
7+
* 'electron-context-menu'
8+
*
9+
* Fill this stub out by replacing all the `any` types.
10+
*
11+
* Once filled out, we encourage you to share your work with the
12+
* community by sending a pull request to:
13+
* https://github.com/flowtype/flow-typed
14+
*/
15+
16+
declare module 'electron-context-menu' {
17+
declare module.exports: any;
18+
}

hermes/send-email.js

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,6 @@ const sendEmail = (options: Options) => {
5959
return;
6060
}
6161

62-
if (!isEmail(To)) {
63-
if (userId) {
64-
trackQueue.add({
65-
userId: userId,
66-
event: events.EMAIL_BOUNCED,
67-
// we can safely log the To field because it's not a valid email, thus not PII
68-
properties: {
69-
tag: Tag,
70-
to: To,
71-
error: 'To field was not a valid email address',
72-
},
73-
});
74-
}
75-
76-
return;
77-
}
78-
7962
// $FlowFixMe
8063
return new Promise((res, rej) => {
8164
client.sendEmailWithTemplate(

mobile/App.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ import Sentry from 'sentry-expo';
33
import React, { Fragment } from 'react';
44
import { StatusBar } from 'react-native';
55
import { SecureStore, AppLoading } from 'expo';
6-
import { createStore } from 'redux';
76
import { Provider } from 'react-redux';
87
import { ApolloProvider } from 'react-apollo';
98
import { ThemeProvider } from 'styled-components';
109
import { ActionSheetProvider } from '@expo/react-native-action-sheet';
1110
import { type ApolloClient } from 'apollo-client';
11+
import { initStore } from './reducers/store';
1212

13+
import Toasts from './components/Toasts';
1314
import theme from '../shared/theme';
1415
import { createClient } from '../shared/graphql';
1516
import Login from './components/Login';
1617
import TabBar from './views/TabBar';
17-
import reducers from './reducers';
1818
import { authenticate } from './actions/authentication';
1919

2020
let sentry = Sentry.config(
@@ -24,7 +24,7 @@ let sentry = Sentry.config(
2424
// Need to guard this for HMR to work
2525
if (sentry && sentry.install) sentry.install();
2626

27-
export const store = createStore(reducers);
27+
export const store = initStore();
2828

2929
type State = {
3030
authLoaded: ?boolean,
@@ -61,7 +61,9 @@ class App extends React.Component<{}, State> {
6161
};
6262

6363
listen = () => {
64-
const { authentication } = store.getState();
64+
const storeState = store.getState();
65+
// $FlowFixMe
66+
const authentication = storeState && storeState.authentication;
6567
const { token: oldToken } = this.state;
6668
if (authentication.token !== oldToken) {
6769
this.setState({
@@ -89,6 +91,7 @@ class App extends React.Component<{}, State> {
8991
<ActionSheetProvider>
9092
<Fragment>
9193
<StatusBar barStyle={'default'} />
94+
<Toasts />
9295
{!token ? <Login /> : <TabBar />}
9396
</Fragment>
9497
</ActionSheetProvider>

mobile/actions/toasts.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// @flow
2+
import type { Dispatch } from 'redux';
3+
import type { GlyphTypes } from '../components/Icon/types';
4+
5+
type ToastTypes = 'notification' | 'success' | 'error' | 'neutral';
6+
7+
export type AddToastType = {
8+
type: ToastTypes,
9+
message: string,
10+
onPressHandler: Function,
11+
icon?: ?GlyphTypes,
12+
};
13+
14+
export type ToastType = {
15+
...$Exact<AddToastType>,
16+
id: number,
17+
};
18+
19+
export type AddToastActionType = {
20+
type: 'ADD_TOAST',
21+
payload: {
22+
...$Exact<ToastType>,
23+
},
24+
};
25+
26+
let nextToastId = 0;
27+
export const addToast = (payload: AddToastType) => (
28+
dispatch: Dispatch<Object>
29+
) => {
30+
const id = nextToastId++;
31+
return dispatch({
32+
type: 'ADD_TOAST',
33+
payload: {
34+
id,
35+
...payload,
36+
},
37+
});
38+
};
39+
40+
export const removeToast = (id: number) => {
41+
return { type: 'REMOVE_TOAST', payload: { id } };
42+
};

0 commit comments

Comments
 (0)