Skip to content

Commit 5418bdd

Browse files
author
Cobb Jung
committed
Merge branch 'release/0.1.7'
2 parents c264ded + ce4afa8 commit 5418bdd

Some content is hidden

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

86 files changed

+1389
-705
lines changed

.eslintrc

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
"airbnb/rules/react",
55
],
66
"plugins": [
7+
"@typescript-eslint",
78
"simple-import-sort"
89
],
9-
"parser": "babel-eslint",
10+
"parser": "@typescript-eslint/parser",
1011
"parserOptions": {
1112
"ecmaVersion": 2018,
1213
"sourceType": "module"
@@ -27,10 +28,24 @@
2728
"import/prefer-default-export": "warn",
2829
"import/named": "warn",
2930
"import/no-named-as-default": "off",
30-
"arrow-parens": 0,
31+
"import/extensions": [
32+
"error",
33+
"ignorePackages",
34+
{
35+
"js": "never",
36+
"jsx": "never",
37+
"ts": "never",
38+
"tsx": "never"
39+
}
40+
],
41+
"@typescript-eslint/type-annotation-spacing": ["warn", { "before": false, "after": true, "overrides": { "colon": { "before": true, "after": true }, "arrow": { "before": true, "after": true } } }],
42+
'arrow-parens': ['error', 'as-needed'],
3143
"no-nested-ternary": "off",
32-
"no-unused-vars": "warn",
33-
"no-unused-expressions": "warn",
44+
"no-unused-expressions": "off",
45+
"no-unused-vars": "off",
46+
"@typescript-eslint/no-unused-vars": "off",
47+
"no-useless-constructor": "off",
48+
"@typescript-eslint/no-useless-constructor": "warn",
3449
"space-before-function-paren": ["warn", "always"],
3550
"no-spaced-func": "off",
3651
"func-call-spacing": ["warn", "always"],
@@ -46,6 +61,7 @@
4661
"no-trailing-spaces": "warn",
4762
"indent": ["warn", 2],
4863
"semi": ["warn", "always"],
64+
"no-param-reassign": ["warn", { "props": true, "ignorePropertyModificationsFor": ["draft"] }],
4965
"simple-import-sort/sort": [
5066
1,
5167
{
@@ -90,8 +106,13 @@
90106
"settings": {
91107
"import/resolver": {
92108
"node": {
93-
"moduleDirectory": ["node_modules", "src", "src/components"]
109+
"moduleDirectory": ["node_modules", "src", "src/components"],
110+
"extensions": [".js",".jsx",".ts",".tsx"]
94111
}
112+
},
113+
"import/extensions": [".js",".jsx",".ts",".tsx"],
114+
"import/parsers": {
115+
"@typescript-eslint/parser": [".ts",".tsx"]
95116
}
96117
},
97118
"overrides": [

jsconfig.json

Lines changed: 0 additions & 3 deletions
This file was deleted.

package.json

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@
44
"version": "0.1.0",
55
"private": false,
66
"scripts": {
7-
"env:path": "cross-env NODE_PATH=src:src/components",
8-
"start": "cross-env NODE_PATH=src:src/components react-scripts start",
9-
"build": "$npm_execpath run env:path react-scripts build",
10-
"test": "$npm_execpath run env:path react-scripts test",
7+
"start": "react-scripts start",
8+
"build": "react-scripts build",
9+
"analyze": "source-map-explorer 'build/static/js/*.js'",
10+
"test": "react-scripts test",
1111
"eject": "react-scripts eject",
12-
"storybook": "$npm_execpath run env:path start-storybook -p 9009 -s public",
13-
"build-storybook": "$npm_execpath run env:path build-storybook -s public",
12+
"storybook": "start-storybook -p 9009 -s public",
13+
"build-storybook": "build-storybook -s public",
1414
"postbuild": "gzipper --verbose --brotli ./build && gzipper --verbose ./build && ./tools/moveBuildFolder.sh",
1515
"generate": "python tools/generate-component.py",
16-
"lint:css": "stylelint './src/**/*.js'"
16+
"lint:css": "stylelint './src/**/*.js' './src/**/*.ts*'"
1717
},
1818
"husky": {
1919
"hooks": {
2020
"pre-commit": "$npm_execpath lint-staged"
2121
}
2222
},
2323
"lint-staged": {
24-
"src/**/*.{js,jsx,json,scss}": [
24+
"src/**/*.{js,jsx,ts,tsx,json,scss}": [
2525
"eslint --fix",
2626
"stylelint",
2727
"git add"
@@ -50,6 +50,17 @@
5050
"@material-ui/icons": "^4.2.1",
5151
"@material-ui/pickers": "^3.2.9",
5252
"@sparcs-kaist/react-grid-layout": "^0.18.0",
53+
"@types/jest": "^25.1.4",
54+
"@types/jsonwebtoken": "^8.3.8",
55+
"@types/lodash": "^4.14.149",
56+
"@types/node": "^13.9.1",
57+
"@types/react": "^16.9.23",
58+
"@types/react-dom": "^16.9.5",
59+
"@types/react-helmet": "^5.0.15",
60+
"@types/react-redux": "^7.1.7",
61+
"@types/react-router-dom": "^5.1.3",
62+
"@types/redux-actions": "^2.6.1",
63+
"@types/styled-components": "^5.0.1",
5364
"animate.css": "^3.7.2",
5465
"awesome-debounce-promise": "^2.1.0",
5566
"axios": "^0.19.0",
@@ -69,9 +80,11 @@
6980
"immer": "^5.1.0",
7081
"immutable": "^4.0.0-rc.12",
7182
"jsonwebtoken": "^8.5.1",
83+
"lodash": "^4.17.15",
7284
"lodash.debounce": "^4.0.8",
7385
"lodash.get": "^4.4.2",
7486
"lodash.isequal": "^4.5.0",
87+
"lodash.set": "^4.3.2",
7588
"lodash.throttle": "^4.1.1",
7689
"lodash.uniq": "^4.5.0",
7790
"lodash.uniqby": "^4.7.0",
@@ -144,11 +157,12 @@
144157
"prettier": "^1.19.1",
145158
"regenerator-runtime": "^0.13.3",
146159
"require-context.macro": "^1.0.4",
160+
"source-map-explorer": "^2.3.1",
147161
"stylelint": "^12.0.1",
148162
"stylelint-config-recommended": "^3.0.0",
149163
"stylelint-config-styled-components": "^0.1.1",
150164
"stylelint-processor-styled-components": "^1.9.0",
151-
"typescript": "^3.7.5"
165+
"typescript": "^3.8.3"
152166
},
153167
"license": "MIT"
154168
}

public/main.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Modules to control application life and create native browser window
2+
const {app, BrowserWindow} = require('electron')
3+
const path = require('path')
4+
5+
function createWindow () {
6+
// Create the browser window.
7+
const mainWindow = new BrowserWindow({
8+
width: 800,
9+
height: 600,
10+
webPreferences: {
11+
preload: path.join(__dirname, 'preload.js')
12+
},
13+
frame: false,
14+
})
15+
16+
// and load the index.html of the app.
17+
mainWindow.loadFile(`file://${path.join (__dirname, '../deploy/index.html')}`)
18+
19+
// Open the DevTools.
20+
// mainWindow.webContents.openDevTools()
21+
}
22+
23+
// This method will be called when Electron has finished
24+
// initialization and is ready to create browser windows.
25+
// Some APIs can only be used after this event occurs.
26+
app.whenReady().then(() => {
27+
createWindow()
28+
29+
app.on('activate', function () {
30+
// On macOS it's common to re-create a window in the app when the
31+
// dock icon is clicked and there are no other windows open.
32+
if (BrowserWindow.getAllWindows().length === 0) createWindow()
33+
})
34+
})
35+
36+
// Quit when all windows are closed.
37+
app.on('window-all-closed', function () {
38+
// On macOS it is common for applications and their menu bar
39+
// to stay active until the user quits explicitly with Cmd + Q
40+
if (process.platform !== 'darwin') app.quit()
41+
})
42+
43+
// In this file you can include the rest of your app's specific main process
44+
// code. You can also put them in separate files and require them here.

src/App.js renamed to src/App.tsx

File renamed without changes.

src/boot.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import 'devtools-detect';
22

3+
import moment from 'moment';
4+
35
import store from 'store';
46
import { checkAuth } from 'store/reducers/auth';
57
import { initialize } from 'store/reducers/upload';
68
import axios from 'lib/axios';
7-
import serializer from 'lib/immutable';
89
import storage from 'lib/storage';
910

11+
import { parseJSON } from './lib/utils';
12+
1013
const pwaInstallPromptListener = () => {
1114
window.addEventListener ('beforeinstallprompt', e => {
1215
// Prevent Chrome 67 and earlier from automatically showing the prompt
@@ -45,11 +48,16 @@ export default () => {
4548
throttle ('scroll', 'optimizedScroll');
4649
}) ());
4750

51+
4852
pwaInstallPromptListener ();
4953

50-
const uploadPersist = storage.getItem ('uploadPersist', false);
54+
const uploadPersist = storage.getItem ('uploadPersist');
5155
if (uploadPersist) {
52-
store.dispatch (initialize (serializer.parse (uploadPersist)));
56+
if (uploadPersist.date) {
57+
store.dispatch (initialize (uploadPersist));
58+
} else {
59+
storage.removeItem ('uploadPersist');
60+
}
5361
}
5462

5563
const token = storage.getItem ('token');
@@ -61,6 +69,7 @@ export default () => {
6169
};
6270

6371
window.addEventListener ('devtoolschange', () => {
72+
if (process.env.NODE_ENV !== 'production') return;
6473
import ('static/images/recruitAscii').then (asciiArt => {
6574
// eslint-disable-next-line no-console
6675
console.log (asciiArt.default);

src/components/atoms/Button/Button.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const Button = ({
99
}) => (
1010
<StyledButton
1111
{...props}
12-
onClick={(event) => {
12+
onClick={event => {
1313
if (typeof onClick === 'function') onClick (event);
1414
if (to) history.push (to);
1515
}}

src/components/atoms/InputBase/InputBase.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const useStyles = makeStyles ({
1414
},
1515
});
1616

17-
const InputBase = (props) => {
17+
const InputBase = props => {
1818
const classes = useStyles ();
1919
return <MInputBase className={classes.root} {...props} />;
2020
};

src/components/atoms/Modal/Modal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const ModalWrapper = styled.div`
3838
justify-content: center;
3939
`;
4040

41-
const Modal = (props) => (
41+
const Modal = props => (
4242
<Portal>
4343
<ModalWrapper>
4444
{props.children}

src/components/atoms/TwoCol/TwoCol.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const colMixin = css`
77
display: flex;
88
flex-direction: column;
99
flex: ${props => props.flex} 0 0;
10+
flex-shrink: 0;
11+
flex-basis: auto;
1012
min-width: 0;
1113
${media.tablet (css`
1214
flex: ${props => props.flex};
@@ -39,10 +41,11 @@ const TwoCol = styled.section`
3941
display: flex;
4042
width: 100%;
4143
flex-wrap: wrap;
44+
flex-shrink: 0;
45+
flex-basis: auto;
4246
${props => (props.mobileWrap ? css`
4347
flex-direction: column;
44-
` : css`
45-
`)};
48+
` : '')};
4649
4750
${media.tablet (css`
4851
flex-direction: row;

src/components/containers/ChannelTalk.js renamed to src/components/containers/ChannelTalk.tsx

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,21 @@
1-
import { useEffect, useMemo } from 'react';
2-
import { useLocation } from 'react-router-dom';
1+
import { useEffect } from 'react';
2+
import { RouteComponentProps, useLocation } from 'react-router-dom';
33
import { useSelector } from 'react-redux';
4+
import { get } from 'lodash';
45
import queryString from 'query-string';
6+
import { IState } from 'types/store.d';
57

68
import ChannelService from 'lib/channel_io';
79
import { isAuthedSelector } from 'lib/utils';
810

9-
const ChannelTalk = ({ match }) => {
11+
const ChannelTalk = ({ match } : RouteComponentProps<{top : string}>) => {
1012
const { search, pathname } = useLocation ();
1113
const { top } = match.params;
1214
const isAuthenticated = useSelector (isAuthedSelector);
13-
const infoImmutable = useSelector (state => state.getIn (['auth', 'info']));
14-
const info = useMemo (() => infoImmutable.toJS (), [infoImmutable]);
15-
const {
16-
_id,
17-
username,
18-
koreanName,
19-
groups,
20-
flags,
21-
email,
22-
profilePhoto,
23-
} = info;
15+
const info = useSelector ((state : IState) => get (state, ['auth', 'info']));
2416

2517
useEffect (() => {
26-
// if (process.env.NODE_ENV !== 'production') return;
18+
if (process.env.NODE_ENV !== 'production') return;
2719
if (top === 'settings') {
2820
ChannelService.shutdown ();
2921
return;
@@ -38,7 +30,16 @@ const ChannelTalk = ({ match }) => {
3830
pluginKey: '5fe8c634-bcbd-4499-ba99-967191a2ef77',
3931
};
4032
if (isAuthenticated) {
41-
if (!_id) return;
33+
if (!info) return;
34+
const {
35+
_id,
36+
username,
37+
koreanName,
38+
groups,
39+
flags,
40+
email,
41+
profilePhoto,
42+
} = info;
4243
Object.assign (settings, {
4344
userId: _id,
4445
profile: {
@@ -52,7 +53,7 @@ const ChannelTalk = ({ match }) => {
5253
});
5354
}
5455
ChannelService.boot (settings);
55-
}, [search, isAuthenticated, infoImmutable, top, pathname]);
56+
}, [search, isAuthenticated, info, top, pathname]);
5657
return null;
5758
};
5859

src/components/containers/ScrollToTop.js renamed to src/components/containers/ScrollToTop.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useEffect } from 'react';
22
import PropTypes from 'prop-types';
33
import { useLocation, useParams } from 'react-router-dom';
44

5-
const ScrollToTop = ({ updateWithPath }) => {
5+
const ScrollToTop = ({ updateWithPath } : { updateWithPath : boolean }) => {
66
const { route } = useParams ();
77
const { pathname } = useLocation ();
88
useEffect (() => {

src/components/organisms/AuthCallback/AuthCallback.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const AuthCallback = ({ location, history }) => {
1111
const { code, state } = queryString.parse (location.search);
1212
if (code && state) {
1313
dispatch (loginCallback (code, state))
14-
.then ((res) => {
14+
.then (res => {
1515
const referrer = storage.getItem ('referrer');
1616
if (referrer) {
1717
storage.removeItem ('referrer');
@@ -20,7 +20,7 @@ const AuthCallback = ({ location, history }) => {
2020
}
2121
history.replace (`/${res.user.username}`);
2222
})
23-
.catch ((error) => {
23+
.catch (error => {
2424
alert (error.message);
2525
history.replace ('/');
2626
});

src/components/organisms/GroupBox/GroupBoxP.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const GroupBox = ({ group, ...props }) => {
1414
const {
1515
name, profilePhoto, zabosCount, followersCount, recentUpload, isPending,
1616
} = group;
17-
const timePast = recentUpload ? getLabeledTimeDiff (recentUpload, true, true, true, true, true, true) : '없음';
17+
const timePast = recentUpload ? getLabeledTimeDiff (recentUpload, 60, 60, 24, 7, 5, 12) : '없음';
1818
const stats = [{
1919
name: '올린 자보',
2020
value: zabosCount,

src/components/organisms/GroupBox/GroupBoxS.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useEffect, useRef, useState } from 'react';
22
import { useSelector } from 'react-redux';
3+
import get from 'lodash.get';
34

45
import SuperTooltip from 'atoms/SuperTooltip';
56

@@ -16,7 +17,7 @@ const GroupBoxS = ({ group, ...props }) => {
1617
const {
1718
name, profilePhoto, subtitle,
1819
} = group;
19-
const width = useSelector (state => state.getIn (['app', 'windowSize', 'width']));
20+
const width = useSelector (state => get (state, ['app', 'windowSize', 'width']));
2021
const nameRef = useRef (null);
2122
const [showTooltip, setShowTooltip] = useState (false);
2223
useEffect (() => { setShowTooltip (isElemWidthOverflown (nameRef.current)); }, [nameRef, width]);

0 commit comments

Comments
 (0)