[Improvement] Move to create-react-app (#17, #15)

This commit is contained in:
Qolzam
2018-02-04 11:19:18 +07:00
parent 5875f97685
commit 36f77ba99d
91 changed files with 26204 additions and 720 deletions

View File

@@ -1,12 +0,0 @@
{
"plugins": [
"react-hot-loader/babel",
"transform-decorators-legacy",
"transform-runtime"
],
"presets": [
["env", { "modules": false }],
"react",
"stage-0"
]
}

View File

@@ -1,35 +0,0 @@
{
"env": {
"browser": true,
"es6": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"never"
]
}
}

26
.gitignore vendored
View File

@@ -1,7 +1,25 @@
node_modules/ # See https://help.github.com/ignore-files/ for more about ignoring files.
public/bundle*.js
config/ # dependencies
/node_modules
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.vscode/ .vscode/
src/data/awsClient src/data/awsClient
src/components/AWS.tsx src/components/AWS.tsx
npm-debug.log

View File

@@ -1,11 +1,7 @@
{ {
"hosting": { "hosting": {
"public": "public", "public": "build",
"rewrites": [ "rewrites": [
{
"source": "/bundle-v0.4.js",
"destination": "/bundle-v0.4.js"
},
{ {
"source": "/favicon.ico", "source": "/favicon.ico",
"destination": "/favicon.ico" "destination": "/favicon.ico"

View File

@@ -1,27 +0,0 @@
var webpackConfig = require('./webpack.config.js');
module.exports = function (config) {
config.set({
browsers: ['Chrome'],
browserNoActivityTimeout: 100000,
singleRun: true,
frameworks: ['mocha'],
files: [
'node_modules/jquery/dist/jquery.min.js',
'app/tests/**/*.test.jsx'
],
preprocessors: {
'app/tests/**/*.test.jsx': ['webpack', 'sourcemap']
},
reporters: ['mocha'],
client: {
mocha: {
timeout: '5000'
}
},
webpack: webpackConfig,
webpackServer: {
noInfo: true
}
});
};

16403
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -3,30 +3,29 @@
"version": "1.0.0", "version": "1.0.0",
"description": "Simple react socail app", "description": "Simple react socail app",
"main": "index.js", "main": "index.js",
"private": true,
"scripts": { "scripts": {
"test": "NODE_ENV=test karma start", "build-css": "node-sass-chokidar src/ -o src/",
"build": "NODE_ENV=production webpack -p", "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
"start-js": "react-scripts-ts start",
"start": "npm-run-all -p watch-css start-js",
"build-js": "react-scripts-ts build",
"build": "npm-run-all build-css build-js",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject",
"watch": "webpack -w", "watch": "webpack -w",
"deploy:firebase": "npm run build && firebase deploy", "deploy:firebase": "npm run build && firebase deploy"
"start": "node server.js"
}, },
"author": "Amir Movahedi", "author": "Amir Movahedi",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/react-hot-loader": "^3.0.5",
"@types/react-infinite-scroller": "^1.0.4",
"amazon-cognito-identity-js": "^1.21.0", "amazon-cognito-identity-js": "^1.21.0",
"aws-sdk": "^2.132.0", "aws-sdk": "^2.132.0",
"axios": "^0.16.2", "axios": "^0.16.2",
"babel-runtime": "^6.26.0",
"classnames": "^2.2.5", "classnames": "^2.2.5",
"copy-to-clipboard": "^3.0.8",
"crypto-js": "^3.1.9-1", "crypto-js": "^3.1.9-1",
"css-loader": "^0.28.0",
"deep-freeze-strict": "^1.1.1",
"expect": "^1.20.2",
"express": "^4.15.2",
"faker": "^4.1.0", "faker": "^4.1.0",
"file-loader": "^0.11.1",
"firebase": "^4.6.2", "firebase": "^4.6.2",
"install": "^0.10.2", "install": "^0.10.2",
"inversify": "^4.6.0", "inversify": "^4.6.0",
@@ -36,16 +35,15 @@
"material-ui-icons": "^1.0.0-beta.17", "material-ui-icons": "^1.0.0-beta.17",
"moment": "^2.18.1", "moment": "^2.18.1",
"morgan": "^1.8.1", "morgan": "^1.8.1",
"node-env-file": "^0.1.8", "node-sass-chokidar": "0.0.3",
"node-sass": "^4.5.2",
"npm": "^5.6.0", "npm": "^5.6.0",
"npm-run-all": "^4.1.2",
"prop-types": "^15.6.0", "prop-types": "^15.6.0",
"react": "^16.2.0", "react": "^16.2.0",
"react-addons-test-utils": "^15.6.2", "react-addons-test-utils": "^15.6.2",
"react-avatar-editor": "^10.3.0", "react-avatar-editor": "^10.3.0",
"react-dom": "^16.0.0", "react-dom": "^16.2.0",
"react-event-listener": "^0.5.1", "react-event-listener": "^0.5.1",
"react-hot-loader": "^3.1.3",
"react-infinite-scroller": "^1.1.2", "react-infinite-scroller": "^1.1.2",
"react-linkify": "^0.2.1", "react-linkify": "^0.2.1",
"react-parallax": "^1.4.4", "react-parallax": "^1.4.4",
@@ -53,28 +51,26 @@
"react-router": "^4.1.1 ", "react-router": "^4.1.1 ",
"react-router-dom": "^4.1.1", "react-router-dom": "^4.1.1",
"react-router-redux": "^5.0.0-alpha.6", "react-router-redux": "^5.0.0-alpha.6",
"react-scripts-ts": "2.13.0",
"react-string-replace": "^0.4.0", "react-string-replace": "^0.4.0",
"react-tap-event-plugin": "^3.0.2", "react-tap-event-plugin": "^3.0.2",
"redux": "^3.7.2", "redux": "^3.7.2",
"redux-actions": "^2.0.3", "redux-actions": "^2.0.3",
"redux-thunk": "^2.2.0", "redux-thunk": "^2.2.0",
"reflect-metadata": "^0.1.10", "reflect-metadata": "^0.1.10",
"sass-loader": "^6.0.3",
"save": "^2.3.0", "save": "^2.3.0",
"script-loader": "^0.7.0",
"style-loader": "^0.16.1",
"typeface-roboto": "0.0.50", "typeface-roboto": "0.0.50",
"url-loader": "^0.5.8",
"uuid": "^3.0.1" "uuid": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/react-infinite-scroller": "^1.0.4",
"@types/classnames": "^2.2.3", "@types/classnames": "^2.2.3",
"@types/lodash": "^4.14.77", "@types/lodash": "^4.14.77",
"@types/moment": "^2.13.0", "@types/jest": "^22.1.1",
"@types/node": "^8.0.33", "@types/node": "^9.4.0",
"@types/prop-types": "^15.5.2", "@types/prop-types": "^15.5.2",
"@types/react": "^16.0.35", "@types/react": "^16.0.36",
"@types/react-dom": "^16.0.1", "@types/react-dom": "^16.0.3",
"@types/react-event-listener": "^0.4.4", "@types/react-event-listener": "^0.4.4",
"@types/react-redux": "^5.0.10", "@types/react-redux": "^5.0.10",
"@types/react-router-dom": "^4.0.8", "@types/react-router-dom": "^4.0.8",
@@ -82,38 +78,15 @@
"@types/react-tap-event-plugin": "0.0.30", "@types/react-tap-event-plugin": "0.0.30",
"@types/redux-logger": "^3.0.4", "@types/redux-logger": "^3.0.4",
"@types/uuid": "^3.4.3", "@types/uuid": "^3.4.3",
"@types/webpack": "^3.0.13",
"babel-core": "^6.24.1",
"babel-loader": "^7.1.2",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^0.28.7",
"eslint": "^4.9.0",
"karma": "^1.6.0",
"karma-chrome-launcher": "^2.0.0",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.3",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.3",
"mocha": "^3.2.0",
"open-browser-webpack-plugin": "0.0.5",
"redux-logger": "^3.0.1", "redux-logger": "^3.0.1",
"redux-mock-store": "^1.2.3", "redux-mock-store": "^1.2.3",
"source-map-loader": "^0.2.2", "typescript": "^2.7.1",
"ts-loader": "^2.3.7",
"ts-node": "^3.3.0", "ts-node": "^3.3.0",
"tslint": "^5.7.0", "tslint": "^5.7.0",
"tslint-config-standard": "^6.0.1", "tslint-config-standard": "^6.0.1"
"typescript": "^2.5.3",
"webpack": "^3.6.0",
"webpack-hot-middleware": "^2.20.0"
}, },
"engines": { "engines": {
"node": "7.3.0", "node": "8.9.4",
"npm": "3.10.10" "npm": "5.6.0"
} }
} }

View File

@@ -121,8 +121,6 @@
</div> </div>
</div> </div>
<script src="/bundle-v0.5.2.js"></script>
</body> </body>
</html> </html>

View File

@@ -1,6 +1,5 @@
// - Import react components // - Import react components
import moment from 'moment'
import { push } from 'react-router-redux' import { push } from 'react-router-redux'
// -Import domain // -Import domain
@@ -21,32 +20,69 @@ import * as globalActions from 'actions/globalActions'
import { provider } from '../socialEngine' import { provider } from '../socialEngine'
import { SocialProviderTypes } from 'core/socialProviderTypes' import { SocialProviderTypes } from 'core/socialProviderTypes'
/* _____________ CRUD State _____________ */
/**
* Loing user
* @param {string} uids
*/
export const login = (uid: string, isVerifide: boolean) => {
return {
type: AuthorizeActionType.LOGIN,
payload: { authed: true, isVerifide, uid }
}
}
/**
* Logout user
*/
export const logout = () => {
return { type: AuthorizeActionType.LOGOUT }
}
/**
* User registeration call
* @param user for registering
*/
export const signup = (user: UserRegisterModel) => {
return {
type: AuthorizeActionType.SIGNUP,
payload: { ...user }
}
}
/**
* Update user's password
*/
export const updatePassword = () => {
return { type: AuthorizeActionType.UPDATE_PASSWORD }
}
/** /**
* Get service providers * Get service providers
*/ */
const authorizeService: IAuthorizeService = provider.get<IAuthorizeService>(SocialProviderTypes.AuthorizeService) const authorizeService: IAuthorizeService = provider.get<IAuthorizeService>(SocialProviderTypes.AuthorizeService)
/* _____________ CRUD DB _____________ */ /* _____________ CRUD DB _____________ */
/** /**
* Log in user in server * Log in user in server
* @param {string} email */
* @param {string} password
*/
export const dbLogin = (email: string, password: string) => { export const dbLogin = (email: string, password: string) => {
return (dispatch: any, getState: any) => { return (dispatch: any, getState: any) => {
dispatch(globalActions.showNotificationRequest()) dispatch(globalActions.showNotificationRequest())
return authorizeService.login(email, password).then((result) => { return authorizeService.login(email, password).then((result) => {
dispatch(globalActions.showNotificationSuccess()) dispatch(globalActions.showNotificationSuccess())
dispatch(login(result.uid,result.emailVerified)) dispatch(login(result.uid, result.emailVerified))
dispatch(push('/')) dispatch(push('/'))
}, (error: SocialError) => dispatch(globalActions.showErrorMessage(error.code))) }, (error: SocialError) => dispatch(globalActions.showErrorMessage(error.code)))
} }
} }
/** /**
* Log out user in server * Log out user in server
*/ */
export const dbLogout = () => { export const dbLogout = () => {
return (dispatch: any, getState: any) => { return (dispatch: any, getState: any) => {
return authorizeService.logout().then((result) => { return authorizeService.logout().then((result) => {
@@ -58,10 +94,30 @@ export const dbLogout = () => {
} }
/** /**
* * Send email verification
* @param user for registering */
*/ export const dbSendEmailVerfication = () => {
return (dispatch: any, getState: any) => {
dispatch(globalActions.showNotificationRequest())
return authorizeService.sendEmailVerification().then(() => {
// Send email verification successful.
dispatch(globalActions.showNotificationSuccess())
dispatch(push('/'))
})
.catch((error: SocialError) => {
// An error happened.
dispatch(globalActions.showErrorMessage(error.code))
})
}
}
/**
*
* @param user for registering
*/
export const dbSignup = (user: UserRegisterModel) => { export const dbSignup = (user: UserRegisterModel) => {
return (dispatch: Function, getState: Function) => { return (dispatch: Function, getState: Function) => {
dispatch(globalActions.showNotificationRequest()) dispatch(globalActions.showNotificationRequest())
@@ -83,46 +139,46 @@ export const dbSignup = (user: UserRegisterModel) => {
} }
/** /**
* Change user's password * Change user's password
* @param {string} newPassword * @param {string} newPassword
*/ */
export const dbUpdatePassword = (newPassword: string) => { export const dbUpdatePassword = (newPassword: string) => {
return (dispatch: any, getState: any) => { return (dispatch: any, getState: any) => {
dispatch(globalActions.showNotificationRequest()) dispatch(globalActions.showNotificationRequest())
return authorizeService.updatePassword(newPassword).then(() => { return authorizeService.updatePassword(newPassword).then(() => {
// Update successful. // Update successful.
dispatch(globalActions.showNotificationSuccess()) dispatch(globalActions.showNotificationSuccess())
dispatch(updatePassword()) dispatch(updatePassword())
dispatch(push('/')) dispatch(push('/'))
}) })
.catch((error: SocialError) => { .catch((error: SocialError) => {
// An error happened. // An error happened.
switch (error.code) { switch (error.code) {
case 'auth/requires-recent-login': case 'auth/requires-recent-login':
dispatch(globalActions.showErrorMessage(error.code)) dispatch(globalActions.showErrorMessage(error.code))
dispatch(dbLogout()) dispatch(dbLogout())
break break
default: default:
} }
}) })
} }
} }
/** /**
* Reset user's password * Reset user's password
* @param {string} newPassword * @param {string} newPassword
*/ */
export const dbResetPassword = (email: string) => { export const dbResetPassword = (email: string) => {
return (dispatch: any, getState: any) => { return (dispatch: any, getState: any) => {
dispatch(globalActions.showNotificationRequest()) dispatch(globalActions.showNotificationRequest())
return authorizeService.resetPassword(email).then(() => { return authorizeService.resetPassword(email).then(() => {
// Reset password successful. // Reset password successful.
dispatch(globalActions.showNotificationSuccess()) dispatch(globalActions.showNotificationSuccess())
dispatch(push('/login')) dispatch(push('/login'))
}) })
@@ -134,35 +190,15 @@ export const dbResetPassword = (email: string) => {
} }
} }
/** /**
* Send email verification * Login user with OAuth
*/ */
export const dbSendEmailVerfication = () => {
return (dispatch: any, getState: any) => {
dispatch(globalActions.showNotificationRequest())
return authorizeService.sendEmailVerification().then(() => {
// Send email verification successful.
dispatch(globalActions.showNotificationSuccess())
dispatch(push('/'))
})
.catch((error: SocialError) => {
// An error happened.
dispatch(globalActions.showErrorMessage(error.code))
})
}
}
/**
* Login user with OAuth
*/
export const dbLoginWithOAuth = (type: OAuthType) => { export const dbLoginWithOAuth = (type: OAuthType) => {
return (dispatch: any, getState: any) => { return (dispatch: any, getState: any) => {
dispatch(globalActions.showNotificationRequest()) dispatch(globalActions.showNotificationRequest())
return authorizeService.loginWithOAuth(type).then((result: LoginUser) => { return authorizeService.loginWithOAuth(type).then((result: LoginUser) => {
// Send email verification successful. // Send email verification successful.
dispatch(globalActions.showNotificationSuccess()) dispatch(globalActions.showNotificationSuccess())
dispatch(login(result.uid, true)) dispatch(login(result.uid, true))
dispatch(push('/')) dispatch(push('/'))
@@ -174,42 +210,3 @@ export const dbLoginWithOAuth = (type: OAuthType) => {
}) })
} }
} }
/* _____________ CRUD State _____________ */
/**
* Loing user
* @param {string} uids
*/
export const login = (uid: string, isVerifide: boolean) => {
return {
type: AuthorizeActionType.LOGIN,
payload: { authed: true, isVerifide, uid }
}
}
/**
* Logout user
*/
export const logout = () => {
return { type: AuthorizeActionType.LOGOUT }
}
/**
* User registeration call
* @param user for registering
*/
export const signup = (user: UserRegisterModel) => {
return {
type: AuthorizeActionType.SIGNUP,
payload: { ...user }
}
}
/**
* Update user's password
*/
export const updatePassword = () => {
return { type: AuthorizeActionType.UPDATE_PASSWORD }
}

View File

@@ -1,22 +1,18 @@
// - Import domain // - Import domain
import { User, Profile } from 'core/domain/users' import { User } from 'core/domain/users'
import { Circle, UserTie } from 'core/domain/circles' import { Circle, UserTie } from 'core/domain/circles'
import { SocialError } from 'core/domain/common' import { SocialError } from 'core/domain/common'
import * as moment from 'moment/moment'
// - Import utility components
import moment from 'moment'
// - Import action types // - Import action types
import { CircleActionType } from 'constants/circleActionType' import { CircleActionType } from 'constants/circleActionType'
// - Import actions // - Import actions
import * as globalActions from 'actions/globalActions' import * as globalActions from 'actions/globalActions'
import * as postActions from 'actions/postActions'
import * as userActions from 'actions/userActions' import * as userActions from 'actions/userActions'
import * as notifyActions from 'actions/notifyActions' import * as notifyActions from 'actions/notifyActions'
import * as serverActions from 'actions/serverActions' import * as serverActions from 'actions/serverActions'
import { IServiceProvider, ServiceProvide } from 'core/factories'
import { ICircleService } from 'core/services/circles' import { ICircleService } from 'core/services/circles'
import { SocialProviderTypes } from 'core/socialProviderTypes' import { SocialProviderTypes } from 'core/socialProviderTypes'
import { provider } from '../socialEngine' import { provider } from '../socialEngine'

View File

@@ -1,5 +1,5 @@
// - Import react components // - Import react components
import moment from 'moment' import moment from 'moment/moment'
import _ from 'lodash' import _ from 'lodash'
// - Import domain // - Import domain
@@ -33,9 +33,6 @@ const commentService: ICommentService = provider.get<ICommentService>(SocialProv
/** /**
* Add comment to database * Add comment to database
* @param {object} ownerPostUserId the identifier of the user who is the owner of the post which comment belong to
* @param {object} newComment user comment
* @param {function} callBack will be fired when server responsed
*/ */
export const dbAddComment = (ownerPostUserId: string, newComment: Comment, callBack: Function) => { export const dbAddComment = (ownerPostUserId: string, newComment: Comment, callBack: Function) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
@@ -43,13 +40,13 @@ export const dbAddComment = (ownerPostUserId: string, newComment: Comment, callB
dispatch(globalActions.showTopLoading()) dispatch(globalActions.showTopLoading())
const state = getState() const state = getState()
let uid: string = getState().authorize.uid let uid: string = state.authorize.uid
let comment: Comment = { let comment: Comment = {
score : 0, score : 0,
creationDate : moment().unix(), creationDate : moment().unix(),
userDisplayName : getState().user.info[uid].fullName, userDisplayName : state.user.info[uid].fullName,
userAvatar : getState().user.info[uid].avatar, userAvatar : state.user.info[uid].avatar,
userId : uid, userId : uid,
postId: newComment.postId, postId: newComment.postId,
text: newComment.text text: newComment.text
@@ -102,7 +99,6 @@ export const dbGetComments = (ownerUserId: string, postId: string) => {
*/ */
dispatch(addCommentList(comments)) dispatch(addCommentList(comments))
let commentsCount: number let commentsCount: number
const state = getState()
const post: Post = state.post.userPosts[ownerUserId][postId] const post: Post = state.post.userPosts[ownerUserId][postId]
if (!post) { if (!post) {
return return
@@ -131,18 +127,12 @@ export const dbGetComments = (ownerUserId: string, postId: string) => {
/** /**
* Update a comment from database * Update a comment from database
* @param {string} id of comment
* @param {string} postId is the identifier of the post which comment belong to
* @param {string} text is the text of comment
*/ */
export const dbUpdateComment = (comment: Comment) => { export const dbUpdateComment = (comment: Comment) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
delete comment.editorStatus delete comment.editorStatus
dispatch(globalActions.showTopLoading()) dispatch(globalActions.showTopLoading())
// Get current user id
let uid: string = getState().authorize.uid
return commentService.updateComment(comment) return commentService.updateComment(comment)
.then(() => { .then(() => {
dispatch(updateComment( comment)) dispatch(updateComment( comment))
@@ -158,8 +148,6 @@ export const dbUpdateComment = (comment: Comment) => {
/** /**
* Delete a comment from database * Delete a comment from database
* @param {string} id of comment
* @param {string} postId is the identifier of the post which comment belong to
*/ */
export const dbDeleteComment = (id?: string | null, postId?: string) => { export const dbDeleteComment = (id?: string | null, postId?: string) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
@@ -169,9 +157,6 @@ export const dbDeleteComment = (id?: string | null, postId?: string) => {
} }
dispatch(globalActions.showTopLoading()) dispatch(globalActions.showTopLoading())
// Get current user id
let uid: string = getState().authorize.uid
return commentService.deleteComment(id!) return commentService.deleteComment(id!)
.then(() => { .then(() => {
dispatch(deleteComment(id!, postId!)) dispatch(deleteComment(id!, postId!))
@@ -214,10 +199,7 @@ export const addComment = (comment: Comment) => {
} }
/** /**
* * Update comment
* @param id comment identifier
* @param postId post identefier which comment belong to
* @param text the new text for comment
*/ */
export const updateComment = ( comment: Comment) => { export const updateComment = ( comment: Comment) => {
@@ -241,8 +223,6 @@ export const addCommentList = (postComments: {[postId: string]: {[commentId: str
/** /**
* Delete a comment * Delete a comment
* @param {string} id of comment
* @param {string} postId is the identifier of the post which comment belong to
*/ */
export const deleteComment = (id: string, postId: string) => { export const deleteComment = (id: string, postId: string) => {
return { type: CommentActionType.DELETE_COMMENT, payload: { id, postId } } return { type: CommentActionType.DELETE_COMMENT, payload: { id, postId } }

View File

@@ -2,9 +2,6 @@
import { GlobalActionType } from 'constants/globalActionType' import { GlobalActionType } from 'constants/globalActionType'
// - Import actions // - Import actions
import * as postActions from 'actions/postActions'
import * as commentActions from 'actions/commentActions'
import * as userActions from 'actions/userActions'
import * as serverActions from 'actions/serverActions' import * as serverActions from 'actions/serverActions'
import { ICommonService } from 'core/services/common/ICommonService' import { ICommonService } from 'core/services/common/ICommonService'
@@ -23,8 +20,6 @@ const commonService: ICommonService = provider.get<ICommonService>(SocialProvide
/** /**
* Add a normal feed * Add a normal feed
* @param {any} newFeed
* @param {Function} callBack
*/ */
export let dbSendFeed = (newFeed: Feed) => { export let dbSendFeed = (newFeed: Feed) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
@@ -52,8 +47,6 @@ export let dbSendFeed = (newFeed: Feed) => {
/** /**
* Progress change * Progress change
* @param {string} percent
* @param {boolean} visible
*/ */
export const progressChange = (percent: number, visible: Boolean) => { export const progressChange = (percent: number, visible: Boolean) => {
return { return {
@@ -257,29 +250,6 @@ export const loadDataGuest = () => {
} }
/**
* Show error report dialog
*/
const showErrorReport = (message: string) => {
const appElement = document.getElementById('app')
const masterElement = document.getElementById('master')
const container = document.createElement('div')
const div = document.createElement('div')
div.innerHTML = message
container.style.position = '100000'
container.style.position = 'fixed'
container.style.backgroundColor = '#32c3e4b8'
container.style.width = '100%'
container.style.height = '100%'
container.style.display = 'flex'
container.style.alignItems = 'center'
container.style.alignItems = 'center'
container.style.flexDirection = 'row'
container.appendChild(div)
appElement!.insertBefore(container, masterElement)
}
/** /**
* Create send feedback serevr request model * Create send feedback serevr request model
*/ */

View File

@@ -1,6 +1,5 @@
import { IStorageService } from 'core/services/files'
// - Import react componetns // - Import react componetns
import moment from 'moment' import moment from 'moment/moment'
// - Import domain // - Import domain
import { Image } from 'core/domain/imageGallery' import { Image } from 'core/domain/imageGallery'
@@ -12,9 +11,6 @@ import { ImageGalleryActionType } from 'constants/imageGalleryActionType'
// - Import actions // - Import actions
import * as globalActions from 'actions/globalActions' import * as globalActions from 'actions/globalActions'
// - Import app API
import FileAPI from 'api/FileAPI'
import { IImageGalleryService } from 'core/services/imageGallery' import { IImageGalleryService } from 'core/services/imageGallery'
import { FileResult } from 'models/files/fileResult' import { FileResult } from 'models/files/fileResult'
import { SocialProviderTypes } from 'core/socialProviderTypes' import { SocialProviderTypes } from 'core/socialProviderTypes'
@@ -24,7 +20,6 @@ import { provider } from '../socialEngine'
* Get service providers * Get service providers
*/ */
const imageGalleryService: IImageGalleryService = provider.get<IImageGalleryService>(SocialProviderTypes.ImageGalleryService) const imageGalleryService: IImageGalleryService = provider.get<IImageGalleryService>(SocialProviderTypes.ImageGalleryService)
const storageService: IStorageService = provider.get<IStorageService>(SocialProviderTypes.StorageService)
/* _____________ UI Actions _____________ */ /* _____________ UI Actions _____________ */
@@ -52,8 +47,6 @@ export const dbGetImageGallery = () => {
/** /**
* Save image URL in the server * Save image URL in the server
* @param {string} imageURL is the URL of image
* @param {string} imageFullPath is the folder name + / + file name
*/ */
export const dbSaveImage = (imageURL: string,imageFullPath: string) => { export const dbSaveImage = (imageURL: string,imageFullPath: string) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
@@ -104,8 +97,6 @@ export const dbDeleteImage = (id: string) => {
/** /**
* Upload image on the server * Upload image on the server
* @param {file} file
* @param {string} fileName
*/ */
export const dbUploadImage = (image: any, imageName: string) => { export const dbUploadImage = (image: any, imageName: string) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
@@ -137,10 +128,10 @@ export const dbDownloadImage = (fileName: string) => {
return {} return {}
} }
if (getState().imageGallery.imageURLList[fileName] && fileName !== '') { if (getState().imageGallery.imageURLList[fileName] && fileName !== '') {
return return undefined
} }
if (getState().imageGallery.imageRequests.indexOf(fileName) > -1) { if (getState().imageGallery.imageRequests.indexOf(fileName) > -1) {
return return undefined
} }
dispatch(sendImageRequest(fileName)) dispatch(sendImageRequest(fileName))
@@ -213,5 +204,4 @@ export const sendImageRequest = (name: string) => {
payload: name payload: name
} }
} }

View File

@@ -1,5 +1,3 @@
// - Import react components
import moment from 'moment'
// - Import domain // - Import domain
import { Notification } from 'core/domain/notifications' import { Notification } from 'core/domain/notifications'
@@ -30,8 +28,6 @@ const notificationService: INotificationService = provider.get<INotificationServ
export const dbAddNotification = (newNotify: Notification) => { export const dbAddNotification = (newNotify: Notification) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
let uid: string = getState().authorize.uid
let notify: Notification = { let notify: Notification = {
isSeen: false, isSeen: false,
description: newNotify.description, description: newNotify.description,

View File

@@ -1,13 +1,9 @@
// - Import react components
import { Action } from 'redux'
// - Import domain // - Import domain
import { Post } from 'core/domain/posts' import { Post } from 'core/domain/posts'
import { Comment } from 'core/domain/comments'
import { SocialError } from 'core/domain/common' import { SocialError } from 'core/domain/common'
// - Import utility components // - Import utility components
import moment from 'moment' import moment from 'moment/moment'
// - Import action types // - Import action types
import { PostActionType } from 'constants/postActionType' import { PostActionType } from 'constants/postActionType'
@@ -28,8 +24,6 @@ const postService: IPostService = provider.get<IPostService>(SocialProviderTypes
/** /**
* Add a normal post * Add a normal post
* @param {any} newPost
* @param {Function} callBack
*/ */
export let dbAddPost = (newPost: Post, callBack: Function) => { export let dbAddPost = (newPost: Post, callBack: Function) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
@@ -71,8 +65,6 @@ export let dbAddPost = (newPost: Post, callBack: Function) => {
/** /**
* Add a post with image * Add a post with image
* @param {object} newPost
* @param {function} callBack
*/ */
export const dbAddImagePost = (newPost: Post, callBack: Function) => { export const dbAddImagePost = (newPost: Post, callBack: Function) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
@@ -118,15 +110,11 @@ export const dbAddImagePost = (newPost: Post, callBack: Function) => {
/** /**
* Update a post from database * Update a post from database
* @param {object} newPost
* @param {func} callBack //TODO: anti pattern should change to parent state or move state to redux
*/ */
export const dbUpdatePost = (updatedPost: Post, callBack: Function) => { export const dbUpdatePost = (updatedPost: Post, callBack: Function) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
dispatch(globalActions.showTopLoading()) dispatch(globalActions.showTopLoading())
// Get current user id
let uid: string = getState().authorize.uid
return postService.updatePost(updatedPost).then(() => { return postService.updatePost(updatedPost).then(() => {
@@ -178,7 +166,6 @@ export const dbGetPosts = (page: number = 0, limit: number = 10) => {
const {stream} = state.post const {stream} = state.post
const lastPageRequest = stream.lastPageRequest const lastPageRequest = stream.lastPageRequest
const lastPostId = stream.lastPostId const lastPostId = stream.lastPostId
const hasMoreData = stream.hasMoreData
let uid: string = state.authorize.uid let uid: string = state.authorize.uid
if (uid && lastPageRequest !== page) { if (uid && lastPageRequest !== page) {
@@ -224,7 +211,6 @@ export const dbGetPostsByUserId = (userId: string, page: number = 0, limit: numb
const {profile} = state.post const {profile} = state.post
const lastPageRequest = profile[userId] ? profile[userId].lastPageRequest : -1 const lastPageRequest = profile[userId] ? profile[userId].lastPageRequest : -1
const lastPostId = profile[userId] ? profile[userId].lastPostId : '' const lastPostId = profile[userId] ? profile[userId].lastPostId : ''
const hasMoreData = profile[userId] ? profile[userId].hasMoreData : true
let uid: string = state.authorize.uid let uid: string = state.authorize.uid
@@ -265,8 +251,6 @@ export const dbGetPostsByUserId = (userId: string, page: number = 0, limit: numb
/** /**
* Get all user posts from data base * Get all user posts from data base
* @param uid post owner identifier
* @param postId post identifier
*/ */
export const dbGetPostById = (uid: string, postId: string) => { export const dbGetPostById = (uid: string, postId: string) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
@@ -287,8 +271,6 @@ export const dbGetPostById = (uid: string, postId: string) => {
/** /**
* Add a normal post * Add a normal post
* @param {string} uid is user identifier
* @param {Post} post
*/ */
export const addPost = (uid: string, post: Post) => { export const addPost = (uid: string, post: Post) => {
return { return {
@@ -299,8 +281,6 @@ export const addPost = (uid: string, post: Post) => {
/** /**
* Update a post * Update a post
* @param {string} uid is user identifier
* @param {Post} post
*/ */
export const updatePost = (post: Post) => { export const updatePost = (post: Post) => {
return { return {
@@ -311,8 +291,6 @@ export const updatePost = (post: Post) => {
/** /**
* Delete a post * Delete a post
* @param {string} uid is user identifier
* @param {string} id is post identifier
*/ */
export const deletePost = (uid: string, id: string) => { export const deletePost = (uid: string, id: string) => {
return { return {
@@ -323,8 +301,6 @@ export const deletePost = (uid: string, id: string) => {
/** /**
* Add a list of post * Add a list of post
* @param {string} uid
* @param {[object]} posts
*/ */
export const addPosts = (userPosts: { [userId: string]: {[postId: string]: Post} }) => { export const addPosts = (userPosts: { [userId: string]: {[postId: string]: Post} }) => {
return { return {
@@ -395,7 +371,6 @@ export const lastPostStream = (lastPostId: string) => {
} }
/** /**
* Set profile posts has more data to show * Set profile posts has more data to show
*/ */

View File

@@ -1,12 +1,9 @@
import moment from 'moment'
// - Import action types // - Import action types
import { ServerActionType } from 'constants/serverActionType' import { ServerActionType } from 'constants/serverActionType'
// - Import domain // - Import domain
// - Import actions // - Import actions
import * as globalActions from 'actions/globalActions'
import { ServerRequestModel } from 'models/server/serverRequestModel' import { ServerRequestModel } from 'models/server/serverRequestModel'
import { SocialError } from 'core/domain/common/socialError' import { SocialError } from 'core/domain/common/socialError'

View File

@@ -1,6 +1,5 @@
// - Import react components // - Import react components
import { provider } from '../socialEngine' import { provider } from '../socialEngine'
import _ from 'lodash'
// - Import domain // - Import domain
import { Profile } from 'core/domain/users' import { Profile } from 'core/domain/users'
import { SocialError } from 'core/domain/common' import { SocialError } from 'core/domain/common'
@@ -10,7 +9,6 @@ import { UserActionType } from 'constants/userActionType'
// - Import actions // - Import actions
import * as globalActions from 'actions/globalActions' import * as globalActions from 'actions/globalActions'
import * as userActions from 'actions/userActions'
import { IUserService } from 'core/services/users' import { IUserService } from 'core/services/users'
import { SocialProviderTypes } from 'core/socialProviderTypes' import { SocialProviderTypes } from 'core/socialProviderTypes'
@@ -47,8 +45,6 @@ export const dbGetUserInfo = () => {
/** /**
* Get user info from database * Get user info from database
* @param {string} uid
* @param {string} callerKey
*/ */
export const dbGetUserInfoByUserId = (uid: string, callerKey: string) => { export const dbGetUserInfoByUserId = (uid: string, callerKey: string) => {
return (dispatch: Function, getState: Function) => { return (dispatch: Function, getState: Function) => {
@@ -56,7 +52,7 @@ export const dbGetUserInfoByUserId = (uid: string, callerKey: string) => {
let caller = getState().global.temp.caller let caller = getState().global.temp.caller
if ( caller && caller.indexOf(`dbGetUserInfoByUserId-${uid}`) > -1) { if ( caller && caller.indexOf(`dbGetUserInfoByUserId-${uid}`) > -1) {
return return undefined
} }
dispatch(globalActions.temp({caller: `dbGetUserInfoByUserId-${uid}`})) dispatch(globalActions.temp({caller: `dbGetUserInfoByUserId-${uid}`}))
return userService.getUserProfile(uid).then((userProfile: Profile) => { return userService.getUserProfile(uid).then((userProfile: Profile) => {
@@ -122,7 +118,6 @@ export const dbGetPeopleInfo = (page: number, limit: number) => {
const {people} = state.user const {people} = state.user
const lastPageRequest = people.lastPageRequest const lastPageRequest = people.lastPageRequest
const lastUserId = people.lastUserId const lastUserId = people.lastUserId
const hasMoreData = people.hasMoreData
let uid: string = state.authorize.uid let uid: string = state.authorize.uid
@@ -159,8 +154,6 @@ export const dbGetPeopleInfo = (page: number, limit: number) => {
/** /**
* Add user information * Add user information
* @param {string} uid is the user identifier
* @param {Profile} info is the information about user
*/ */
export const addUserInfo = (uid: string, info: Profile) => { export const addUserInfo = (uid: string, info: Profile) => {
return { return {
@@ -182,8 +175,6 @@ export const addPeopleInfo = (infoList: {[userId: string]: Profile}) => {
/** /**
* Update user information * Update user information
* @param {string} uid is the user identifier
* @param {Profile} info is the information about user
*/ */
export const updateUserInfo = (uid: string, info: Profile) => { export const updateUserInfo = (uid: string, info: Profile) => {
return { return {

View File

@@ -1,4 +1,4 @@
import moment from 'moment' import moment from 'moment/moment'
// - Import action types // - Import action types
import { VoteActionType } from 'constants/voteActionType' import { VoteActionType } from 'constants/voteActionType'

View File

@@ -1,4 +1,4 @@
import * as moment from 'moment' import * as moment from 'moment/moment'
/** /**
* Log the data * Log the data
* @param title log title * @param title log title
@@ -7,7 +7,7 @@ import * as moment from 'moment'
const logger = (title: string, data: any) => { const logger = (title: string, data: any) => {
const randomColor = getRandomColor() const randomColor = getRandomColor()
console.log(`\n\n%c ======= ${title} ======= %c${moment().format('HH:mm:ss SSS')} \n`, `color:${getRandomColor()};font-size:15` console.log(`\n\n%c ======= ${title} ======= %c${moment().format('HH:mm:ss SSS')} \n`, `color:${randomColor};font-size:15`
, `color:${getRandomColor()};font-size:15`, data,`\n\n =========================================`) , `color:${getRandomColor()};font-size:15`, data,`\n\n =========================================`)
} }

View File

@@ -1,19 +1,16 @@
// - Import react components // - Import react components
import React, { Component } from 'react' import React, { Component } from 'react'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { push } from 'react-router-redux' import { push } from 'react-router-redux'
import { grey } from 'material-ui/colors'
import List, { import List, {
ListItem, ListItem,
ListItemIcon, ListItemIcon,
ListItemSecondaryAction, ListItemSecondaryAction,
ListItemText, ListItemText
ListSubheader
} from 'material-ui/List' } from 'material-ui/List'
import SvgGroup from 'material-ui-icons/groupWork' import SvgGroup from 'material-ui-icons/GroupWork'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import MoreVertIcon from 'material-ui-icons/moreVert' import MoreVertIcon from 'material-ui-icons/MoreVert'
import TextField from 'material-ui/TextField' import TextField from 'material-ui/TextField'
import { MenuList, MenuItem } from 'material-ui/Menu' import { MenuList, MenuItem } from 'material-ui/Menu'
import { withStyles } from 'material-ui/styles' import { withStyles } from 'material-ui/styles'
@@ -31,7 +28,7 @@ import Dialog, {
import Divider from 'material-ui/Divider' import Divider from 'material-ui/Divider'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import RaisedButton from 'material-ui/Button' import RaisedButton from 'material-ui/Button'
import SvgClose from 'material-ui-icons/close' import SvgClose from 'material-ui-icons/Close'
import AppBar from 'material-ui/AppBar' import AppBar from 'material-ui/AppBar'
import Paper from 'material-ui/Paper' import Paper from 'material-ui/Paper'
import Collapse from 'material-ui/transitions/Collapse' import Collapse from 'material-ui/transitions/Collapse'
@@ -102,7 +99,7 @@ export class CircleComponent extends Component<ICircleComponentProps, ICircleCom
* Component constructor * Component constructor
* @param {object} props is an object properties of component * @param {object} props is an object properties of component
*/ */
constructor(props: ICircleComponentProps) { constructor (props: ICircleComponentProps) {
super(props) super(props)
// Defaul state // Defaul state
@@ -229,7 +226,7 @@ export class CircleComponent extends Component<ICircleComponentProps, ICircleCom
* Reneder component DOM * Reneder component DOM
* @return {react element} return the DOM which rendered by component * @return {react element} return the DOM which rendered by component
*/ */
render() { render () {
const { circle, classes } = this.props const { circle, classes } = this.props
const { isMenuOpen } = this.state const { isMenuOpen } = this.state
@@ -242,7 +239,7 @@ export class CircleComponent extends Component<ICircleComponentProps, ICircleCom
<Manager> <Manager>
<Target> <Target>
<IconButton <IconButton
aria-owns={isMenuOpen! ? 'circle-menu' : null} aria-owns={isMenuOpen! ? 'circle-menu' : ''}
aria-haspopup='true' aria-haspopup='true'
onClick={this.handleOpenMenu} onClick={this.handleOpenMenu}
> >
@@ -255,7 +252,7 @@ export class CircleComponent extends Component<ICircleComponentProps, ICircleCom
className={classNames({ [classes.popperClose]: !isMenuOpen }, { [classes.popperOpen]: isMenuOpen })} className={classNames({ [classes.popperClose]: !isMenuOpen }, { [classes.popperOpen]: isMenuOpen })}
> >
<ClickAwayListener onClickAway={this.handleCloseMenu}> <ClickAwayListener onClickAway={this.handleCloseMenu}>
<Grow in={isMenuOpen} id='circle-menu' style={{ transformOrigin: '0 0 0' }}> <Grow in={isMenuOpen} style={{ transformOrigin: '0 0 0' }}>
<Paper> <Paper>
<MenuList role='menu'> <MenuList role='menu'>
<MenuItem onClick={this.handleDeleteCircle} > Delete circle </MenuItem> <MenuItem onClick={this.handleDeleteCircle} > Delete circle </MenuItem>
@@ -300,7 +297,7 @@ export class CircleComponent extends Component<ICircleComponentProps, ICircleCom
</ListItemIcon> </ListItemIcon>
<ListItemText inset primary={<span style={this.styles}>{this.props.circle.name}</span>} /> <ListItemText inset primary={<span style={this.styles}>{this.props.circle.name}</span>} />
<ListItemSecondaryAction> <ListItemSecondaryAction>
{ circle.isSystem ? null : rightIconMenu } {circle.isSystem ? null : rightIconMenu}
</ListItemSecondaryAction> </ListItemSecondaryAction>
</ListItem> </ListItem>
<Collapse component='li' in={this.state.open} timeout='auto' unmountOnExit> <Collapse component='li' in={this.state.open} timeout='auto' unmountOnExit>

View File

@@ -3,7 +3,7 @@ import React, { Component } from 'react'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import moment from 'moment' import moment from 'moment/moment'
import Linkify from 'react-linkify' import Linkify from 'react-linkify'
import { Comment } from 'core/domain/comments' import { Comment } from 'core/domain/comments'
@@ -14,7 +14,7 @@ import Paper from 'material-ui/Paper'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import MoreVertIcon from 'material-ui-icons/moreVert' import MoreVertIcon from 'material-ui-icons/MoreVert'
import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List' import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List'
import Menu, { MenuList, MenuItem } from 'material-ui/Menu' import Menu, { MenuList, MenuItem } from 'material-ui/Menu'
import TextField from 'material-ui/TextField' import TextField from 'material-ui/TextField'
@@ -167,11 +167,11 @@ export class CommentComponent extends Component<ICommentComponentProps, IComment
/** /**
* Comment text * Comment text
*/ */
text: this.props.comment.text, text: this.props.comment.text!,
/** /**
* Comment text to match edit with new comment that is edited * Comment text to match edit with new comment that is edited
*/ */
initialText: this.props.comment.text, initialText: this.props.comment.text!,
/** /**
* If comment text dosn't take any change it will be true * If comment text dosn't take any change it will be true
*/ */
@@ -212,7 +212,7 @@ export class CommentComponent extends Component<ICommentComponentProps, IComment
handleCancelEdit = (evt: any) => { handleCancelEdit = (evt: any) => {
this.setState({ this.setState({
text: this.state.initialText text: this.state.initialText!
}) })
this.props.closeEditor!() this.props.closeEditor!()
} }
@@ -303,7 +303,7 @@ export class CommentComponent extends Component<ICommentComponentProps, IComment
> >
<Target> <Target>
<IconButton <IconButton
aria-owns={openMenu! ? 'comment-menu' : null} aria-owns={openMenu! ? 'comment-menu' : ''}
aria-haspopup='true' aria-haspopup='true'
onClick={this.handleCommentMenu} onClick={this.handleCommentMenu}
> >
@@ -316,7 +316,7 @@ export class CommentComponent extends Component<ICommentComponentProps, IComment
className={classNames({ [classes.popperClose]: !openMenu! }, { [classes.popperOpen]: openMenu! })} className={classNames({ [classes.popperClose]: !openMenu! }, { [classes.popperOpen]: openMenu! })}
> >
<ClickAwayListener onClickAway={this.handleCloseCommentMenu}> <ClickAwayListener onClickAway={this.handleCloseCommentMenu}>
<Grow in={openMenu!} id='comment-menu' style={{ transformOrigin: '0 0 0' }}> <Grow in={openMenu!} style={{ transformOrigin: '0 0 0' }}>
<Paper> <Paper>
<MenuList role='menu'> <MenuList role='menu'>
<MenuItem className={classes.rightIconMenuItem}>Reply</MenuItem> <MenuItem className={classes.rightIconMenuItem}>Reply</MenuItem>
@@ -426,4 +426,4 @@ const mapStateToProps = (state: any, ownProps: any) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(CommentComponent as any) as any) export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles as any)(CommentComponent as any) as any)

View File

@@ -54,7 +54,7 @@ export interface ICommentComponentProps {
* *
* @memberof ICommentComponentProps * @memberof ICommentComponentProps
*/ */
delete?: (id?: string| null, postId?: string) => any delete?: (id?: string | null, postId?: string) => any
/** /**
* Get user profile * Get user profile
@@ -98,6 +98,6 @@ export interface ICommentComponentProps {
/** /**
* Styles * Styles
*/ */
classes: any classes?: any
} }

View File

@@ -7,7 +7,7 @@ export interface ICommentComponentState {
* @type {string} * @type {string}
* @memberof ICommentComponentProps * @memberof ICommentComponentProps
*/ */
initialText?: string | null initialText?: string
/** /**
* Initialt text comment * Initialt text comment

View File

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import _ from 'lodash' import _ from 'lodash'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import moment from 'moment' import moment from 'moment/moment'
import Paper from 'material-ui/Paper' import Paper from 'material-ui/Paper'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
@@ -24,16 +24,16 @@ import classNames from 'classnames'
import * as commentActions from 'actions/commentActions' import * as commentActions from 'actions/commentActions'
// - Import app components // - Import app components
import CommentListComponent from 'components/CommentList' import CommentListComponent from 'components/commentList'
import UserAvatar from 'components/userAvatar' import UserAvatar from 'components/userAvatar'
import { ICommentGroupComponentProps } from './ICommentGroupComponentProps' import { ICommentGroupComponentProps } from './ICommentGroupComponentProps'
import { ICommentGroupComponentState } from './ICommentGroupComponentState' import { ICommentGroupComponentState } from './ICommentGroupComponentState'
import { Comment } from 'core/domain/comments/comment' import { Comment } from 'core/domain/comments/comment'
import { ServerRequestModel } from 'models/server'; import { ServerRequestModel } from 'models/server'
import StringAPI from 'api/StringAPI'; import StringAPI from 'api/StringAPI'
import { ServerRequestType } from 'constants/serverRequestType'; import { ServerRequestType } from 'constants/serverRequestType'
import { ServerRequestStatusType } from 'actions/serverRequestStatusType'; import { ServerRequestStatusType } from 'actions/serverRequestStatusType'
const styles = (theme: any) => ({ const styles = (theme: any) => ({
textField: { textField: {
@@ -254,7 +254,7 @@ export class CommentGroupComponent extends Component<ICommentGroupComponentProps
<Card elevation={0}> <Card elevation={0}>
<CardHeader <CardHeader
className={classes.header} className={classes.header}
title={ <Author />} title={<Author />}
avatar={<UserAvatar fullName={commentFullName!} fileName={commentAvatar!} size={24} />} avatar={<UserAvatar fullName={commentFullName!} fileName={commentAvatar!} size={24} />}
subheader={commentBody} subheader={commentBody}
> >
@@ -278,7 +278,8 @@ export class CommentGroupComponent extends Component<ICommentGroupComponentProps
/** /**
* Comment list box * Comment list box
*/ */
const commentWriteBox = (<div> const commentWriteBox = (
<div>
<Divider /> <Divider />
<Paper key={postId! + '-commentwrite'} elevation={0} className='animate2-top10'> <Paper key={postId! + '-commentwrite'} elevation={0} className='animate2-top10'>
<Card elevation={0}> <Card elevation={0}>
@@ -313,7 +314,8 @@ export class CommentGroupComponent extends Component<ICommentGroupComponentProps
) )
const showComments = ( comments && Object.keys(comments).length > 0 const showComments = ( comments && Object.keys(comments).length > 0
? (<Paper elevation={0} style={open ? { display: 'block', padding: '0px 0px' } : { display: 'none', padding: '12px 16px' }}> ? (
<Paper elevation={0} style={open ? { display: 'block', padding: '0px 0px' } : { display: 'none', padding: '12px 16px' }}>
<CommentListComponent comments={comments!} isPostOwner={this.props.isPostOwner} disableComments={this.props.disableComments} /> <CommentListComponent comments={comments!} isPostOwner={this.props.isPostOwner} disableComments={this.props.disableComments} />
</Paper>) </Paper>)
: '') : '')
@@ -391,4 +393,4 @@ const mapStateToProps = (state: any, ownProps: ICommentGroupComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(CommentGroupComponent as any) as any) export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles as any)(CommentGroupComponent as any) as any)

View File

@@ -5,7 +5,7 @@ import PropTypes from 'prop-types'
import List, { ListItem, ListItemText } from 'material-ui/List' import List, { ListItem, ListItemText } from 'material-ui/List'
// - Import app components // - Import app components
import CommentComponent from 'components/Comment' import CommentComponent from 'components/comment'
import * as PostAPI from 'api/PostAPI' import * as PostAPI from 'api/PostAPI'

View File

@@ -4,8 +4,8 @@ import { connect } from 'react-redux'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import MoreVertIcon from 'material-ui-icons/moreVert' import MoreVertIcon from 'material-ui-icons/MoreVert'
import SvgCamera from 'material-ui-icons/photoCamera' import SvgCamera from 'material-ui-icons/PhotoCamera'
import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List' import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List'
import Menu, { MenuList, MenuItem } from 'material-ui/Menu' import Menu, { MenuList, MenuItem } from 'material-ui/Menu'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'

View File

@@ -59,5 +59,5 @@ export interface IEditProfileComponentProps {
/** /**
* Styles * Styles
*/ */
classes: any classes?: any
} }

View File

@@ -73,7 +73,7 @@ export class EmailVerificationComponent extends Component<IEmailVerificationComp
}}>Green</h1> }}>Green</h1>
<div className='animate-bottom'> <div className='animate-bottom'>
<Paper style={paperStyle} elevation={1} rounded={false} > <Paper style={paperStyle} elevation={1} >
<div style={{ padding: '48px 40px 36px' }}> <div style={{ padding: '48px 40px 36px' }}>
<div style={{ <div style={{
paddingLeft: '40px', paddingLeft: '40px',
@@ -93,8 +93,8 @@ export class EmailVerificationComponent extends Component<IEmailVerificationComp
An verificiation email has been already sent to you. Please check your inbox. If you couldn't see the emai, please resend email verification. An verificiation email has been already sent to you. Please check your inbox. If you couldn't see the emai, please resend email verification.
</p> </p>
<div style={this.styles.buttons}> <div style={this.styles.buttons}>
<Button raised style={this.styles.homeButton} label='Home' color='primary' onClick={() => this.props.homePage()} /> <Button raised style={this.styles.homeButton} color='primary' onClick={() => this.props.homePage()}> Home </Button>
<Button raised label='Send Email Verification' color='primary' onClick={() => this.props.sendEmailVerification()} /> <Button raised color='primary' onClick={() => this.props.sendEmailVerification()}> Send Email Verification </Button>
</div> </div>
<div> <div>
</div> </div>
@@ -135,4 +135,4 @@ const mapStateToProps = (state: any, ownProps: IEmailVerificationComponentProps)
} }
// - Connect component to redux store // - Connect component to redux store
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(EmailVerificationComponent as any)) export default withRouter(connect(mapStateToProps, mapDispatchToProps)(EmailVerificationComponent as any) as any)

View File

@@ -1,5 +1,4 @@
export interface IEmailVerificationComponentState { export interface IEmailVerificationComponentState {
} }

View File

@@ -57,7 +57,7 @@ export class FindPeopleComponent extends Component<IFindPeopleComponentProps, IF
loadMore={this.scrollLoad} loadMore={this.scrollLoad}
hasMore={hasMorePeople} hasMore={hasMorePeople}
useWindow={true} useWindow={true}
loader={ <LoadMoreProgressComponent />} loader={<LoadMoreProgressComponent />}
> >
<div className='tracks'> <div className='tracks'>

View File

@@ -8,7 +8,7 @@ import UserBoxList from 'components/userBoxList'
import { IFollowersComponentProps } from './IFollowersComponentProps' import { IFollowersComponentProps } from './IFollowersComponentProps'
import { IFollowersComponentState } from './IFollowersComponentState' import { IFollowersComponentState } from './IFollowersComponentState'
import { Circle } from 'core/domain/circles'; import { Circle } from 'core/domain/circles'
// - Import API // - Import API

View File

@@ -9,12 +9,12 @@ import Menu from 'material-ui/Menu'
import { MenuList, MenuItem } from 'material-ui/Menu' import { MenuList, MenuItem } from 'material-ui/Menu'
import { ListItemIcon, ListItemText } from 'material-ui/List' import { ListItemIcon, ListItemText } from 'material-ui/List'
import Divider from 'material-ui/Divider' import Divider from 'material-ui/Divider'
import SvgArrowLeft from 'material-ui-icons/keyboardArrowLeft' import SvgArrowLeft from 'material-ui-icons/KeyboardArrowLeft'
import SvgHome from 'material-ui-icons/home' import SvgHome from 'material-ui-icons/Home'
import SvgFeedback from 'material-ui-icons/feedback' import SvgFeedback from 'material-ui-icons/Feedback'
import SvgSettings from 'material-ui-icons/settings' import SvgSettings from 'material-ui-icons/Settings'
import SvgAccountCircle from 'material-ui-icons/accountCircle' import SvgAccountCircle from 'material-ui-icons/AccountCircle'
import SvgPeople from 'material-ui-icons/people' import SvgPeople from 'material-ui-icons/People'
// - Import app components // - Import app components
import Sidebar from 'components/sidebar' import Sidebar from 'components/sidebar'
@@ -130,6 +130,7 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
* @memberof Home * @memberof Home
*/ */
render () { render () {
const HR = HomeRouter as any
const { loaded, authed, loadDataStream, mergedPosts, hasMorePosts, showSendFeedback } = this.props const { loaded, authed, loadDataStream, mergedPosts, hasMorePosts, showSendFeedback } = this.props
return ( return (
<div id='home'> <div id='home'>
@@ -184,7 +185,7 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
<ListItemText inset primary='Settings' /> <ListItemText inset primary='Settings' />
</MenuItem> </MenuItem>
</NavLink> </NavLink>
<MenuItem onClick={() => showSendFeedback()} style={{ color: 'rgb(117, 117, 117)' }}> <MenuItem onClick={() => showSendFeedback!()} style={{ color: 'rgb(117, 117, 117)' }}>
<ListItemIcon> <ListItemIcon>
<SvgFeedback /> <SvgFeedback />
</ListItemIcon> </ListItemIcon>
@@ -194,7 +195,7 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
</SidebarContent> </SidebarContent>
<SidebarMain> <SidebarMain>
<HomeRouter enabled={loaded!} data={{ mergedPosts, loadDataStream, hasMorePosts }} /> <HR enabled={loaded!} data={{ mergedPosts, loadDataStream, hasMorePosts }} />
</SidebarMain> </SidebarMain>
</Sidebar> </Sidebar>
@@ -274,4 +275,4 @@ const mapStateToProps = (state: any, ownProps: IHomeComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(HomeComponent as any) as any) export default withRouter<any>(connect(mapStateToProps, mapDispatchToProps)(HomeComponent as any)) as typeof HomeComponent

View File

@@ -37,7 +37,7 @@ export interface IHomeComponentProps {
/** /**
* Load the data for stream * Load the data for stream
*/ */
loadDataStream: (lastPostId: string, page: number, limit: number) => any loadDataStream?: (lastPostId: string, page: number, limit: number) => any
/** /**
* Global state * Global state
@@ -101,11 +101,11 @@ export interface IHomeComponentProps {
/** /**
* Show send feedback form * Show send feedback form
*/ */
showSendFeedback: () => any showSendFeedback?: () => any
/** /**
* Hide send feedback form * Hide send feedback form
*/ */
hideSendFeedback: () => any hideSendFeedback?: () => any
} }

View File

@@ -2,7 +2,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import SvgDehaze from 'material-ui-icons/dehaze' import SvgDehaze from 'material-ui-icons/Dehaze'
import { grey, blue } from 'material-ui/colors' import { grey, blue } from 'material-ui/colors'
import Toolbar from 'material-ui/Toolbar' import Toolbar from 'material-ui/Toolbar'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
@@ -10,7 +10,7 @@ import Popover from 'material-ui/Popover'
import AppBar from 'material-ui/AppBar' import AppBar from 'material-ui/AppBar'
import Menu, { MenuList, MenuItem } from 'material-ui/Menu' import Menu, { MenuList, MenuItem } from 'material-ui/Menu'
import Paper from 'material-ui/Paper' import Paper from 'material-ui/Paper'
import NotificationsIcon from 'material-ui-icons/notifications' import NotificationsIcon from 'material-ui-icons/Notifications'
import EventListener, { withOptions } from 'react-event-listener' import EventListener, { withOptions } from 'react-event-listener'
import Tooltip from 'material-ui/Tooltip' import Tooltip from 'material-ui/Tooltip'
import Typography from 'material-ui/Typography' import Typography from 'material-ui/Typography'

View File

@@ -4,11 +4,11 @@ import PropTypes from 'prop-types'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import GridList, { GridListTile, GridListTileBar } from 'material-ui/GridList' import GridList, { GridListTile, GridListTileBar } from 'material-ui/GridList'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import StarBorder from 'material-ui-icons/starBorder' import StarBorder from 'material-ui-icons/StarBorder'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import SvgUpload from 'material-ui-icons/cloudUpload' import SvgUpload from 'material-ui-icons/CloudUpload'
import SvgAddImage from 'material-ui-icons/addAPhoto' import SvgAddImage from 'material-ui-icons/AddAPhoto'
import SvgDelete from 'material-ui-icons/delete' import SvgDelete from 'material-ui-icons/Delete'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'
import uuid from 'uuid' import uuid from 'uuid'
@@ -174,8 +174,7 @@ export class ImageGalleryComponent extends Component<IImageGalleryComponentProps
title={<SvgDelete style={this.styles.deleteImage as any} onClick={evt => this.handleDeleteImage(evt, image.id!)} />} title={<SvgDelete style={this.styles.deleteImage as any} onClick={evt => this.handleDeleteImage(evt, image.id!)} />}
titlePosition='top' titlePosition='top'
actionIcon={ actionIcon={
<SvgAddImage style={this.styles.addImage as any} onClick={evt => this.handleSetImage(evt, image.URL,image.fullPath)} /> <SvgAddImage style={this.styles.addImage as any} onClick={evt => this.handleSetImage(evt, image.URL,image.fullPath)} />}
}
actionPosition='left' actionPosition='left'
/> />
</GridListTile>) </GridListTile>)

View File

@@ -2,7 +2,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import SvgImage from 'material-ui-icons/image' import SvgImage from 'material-ui-icons/Image'
import { withStyles } from 'material-ui/styles' import { withStyles } from 'material-ui/styles'
// - Import app components // - Import app components
@@ -91,7 +91,7 @@ export class ImgComponent extends Component<IImgComponentProps,IImgComponentStat
return ( return (
<div> <div>
<img className={classes.image} onLoad={this.handleLoadImage} src={fileName || ''} style={isImageLoaded ? style : { display: 'none' }} /> <img className={classes.image} onLoad={this.handleLoadImage} src={fileName || ''} style={isImageLoaded ? style : { display: 'none' }} />
<div style={Object.assign({},{ backgroundColor: 'white' }, isImageLoaded ? { display: 'none' } : this.styles.loding) }> <div style={Object.assign({},{ backgroundColor: 'white' }, isImageLoaded ? { display: 'none' } : this.styles.loding)}>
<div style={this.styles.loadingContent as any}> <div style={this.styles.loadingContent as any}>
<SvgImage style={this.styles.loadingImage} /> <SvgImage style={this.styles.loadingImage} />
<div>Image has not loaded</div> <div>Image has not loaded</div>

View File

@@ -2,7 +2,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import SvgImage from 'material-ui-icons/image' import SvgImage from 'material-ui-icons/Image'
// - Import app components // - Import app components

View File

@@ -9,7 +9,7 @@ import RaisedButton from 'material-ui/Button'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import Divider from 'material-ui/Divider' import Divider from 'material-ui/Divider'
import ActionAndroid from 'material-ui-icons/android' import ActionAndroid from 'material-ui-icons/Android'
import { withStyles } from 'material-ui/styles' import { withStyles } from 'material-ui/styles'
// - Import actions // - Import actions
@@ -259,4 +259,4 @@ const mapStateToProps = (state: any, ownProps: ILoginComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(LoginComponent as any) as any)) export default withRouter(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(LoginComponent as any) as any) as any)

View File

@@ -112,8 +112,10 @@ export class NotifyComponent extends Component<INotifyComponentProps, INotifyCom
*/ */
render () { render () {
let { open, anchorEl, onRequestClose, classes } = this.props let { open, anchorEl, onRequestClose, classes } = this.props
const noNotify = ( <div className={classes.noNotify}> const noNotify = (
All caught up! </div>) <div className={classes.noNotify}>
All caught up! </div>
)
const items = this.notifyItemList() const items = this.notifyItemList()
return ( return (
<Popper <Popper
@@ -162,4 +164,4 @@ const mapStateToProps = (state: any, ownProps: INotifyComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(NotifyComponent as any) as any) export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles as any)(NotifyComponent as any) as any)

View File

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { push } from 'react-router-redux' import { push } from 'react-router-redux'
import SvgClose from 'material-ui-icons/close' import SvgClose from 'material-ui-icons/Close'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'
import { withStyles } from 'material-ui/styles' import { withStyles } from 'material-ui/styles'
import List, { ListItem, ListItemSecondaryAction, ListItemText } from 'material-ui/List' import List, { ListItem, ListItemSecondaryAction, ListItemText } from 'material-ui/List'

View File

@@ -130,7 +130,7 @@ export class PeopleComponent extends Component<IPeopleComponentProps,IPeopleComp
return ( return (
<div style={styles.people}> <div style={styles.people}>
<AppBar position='static' color='default'> <AppBar position='static' color='default'>
<Tabs indicatorColor= {grey[50]} <Tabs indicatorColor={grey[50]}
onChange={this.handleChangeTab} onChange={this.handleChangeTab}
value={tabIndex} centered value={tabIndex} centered
textColor='primary' textColor='primary'
@@ -197,4 +197,4 @@ const mapStateToProps = (state: any, ownProps: IPeopleComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(PeopleComponent as any)) export default withRouter(connect(mapStateToProps, mapDispatchToProps)(PeopleComponent as any) as any)

View File

@@ -4,18 +4,18 @@ import { connect } from 'react-redux'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { push } from 'react-router-redux' import { push } from 'react-router-redux'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import moment from 'moment' import moment from 'moment/moment'
import Linkify from 'react-linkify' import Linkify from 'react-linkify'
import copy from 'copy-to-clipboard' import copy from 'copy-to-clipboard'
// - Material UI // - Material UI
import { Card, CardActions, CardHeader, CardMedia, CardContent } from 'material-ui' import { Card, CardActions, CardHeader, CardMedia, CardContent } from 'material-ui'
import Typography from 'material-ui/Typography' import Typography from 'material-ui/Typography'
import SvgShare from 'material-ui-icons/share' import SvgShare from 'material-ui-icons/Share'
import SvgLink from 'material-ui-icons/link' import SvgLink from 'material-ui-icons/Link'
import SvgComment from 'material-ui-icons/comment' import SvgComment from 'material-ui-icons/Comment'
import SvgFavorite from 'material-ui-icons/favorite' import SvgFavorite from 'material-ui-icons/Favorite'
import SvgFavoriteBorder from 'material-ui-icons/favoriteBorder' import SvgFavoriteBorder from 'material-ui-icons/FavoriteBorder'
import Checkbox from 'material-ui/Checkbox' import Checkbox from 'material-ui/Checkbox'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import Divider from 'material-ui/Divider' import Divider from 'material-ui/Divider'
@@ -26,7 +26,7 @@ import { MenuList, MenuItem } from 'material-ui/Menu'
import TextField from 'material-ui/TextField' import TextField from 'material-ui/TextField'
import Dialog from 'material-ui/Dialog' import Dialog from 'material-ui/Dialog'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import MoreVertIcon from 'material-ui-icons/moreVert' import MoreVertIcon from 'material-ui-icons/MoreVert'
import { ListItemIcon, ListItemText } from 'material-ui/List' import { ListItemIcon, ListItemText } from 'material-ui/List'
import { withStyles } from 'material-ui/styles' import { withStyles } from 'material-ui/styles'
import { Manager, Target, Popper } from 'react-popper' import { Manager, Target, Popper } from 'react-popper'
@@ -342,7 +342,7 @@ export class PostComponent extends Component<IPostComponentProps, IPostComponent
<Manager> <Manager>
<Target> <Target>
<IconButton <IconButton
aria-owns={isPostMenuOpen! ? 'post-menu' : null} aria-owns={isPostMenuOpen! ? 'post-menu' : ''}
aria-haspopup='true' aria-haspopup='true'
onClick={this.openPostMenu.bind(this)} onClick={this.openPostMenu.bind(this)}
> >
@@ -356,7 +356,7 @@ export class PostComponent extends Component<IPostComponentProps, IPostComponent
className={classNames({ [classes.popperClose]: !isPostMenuOpen! }, { [classes.popperOpen]: isPostMenuOpen! })} className={classNames({ [classes.popperClose]: !isPostMenuOpen! }, { [classes.popperOpen]: isPostMenuOpen! })}
> >
<ClickAwayListener onClickAway={this.closePostMenu}> <ClickAwayListener onClickAway={this.closePostMenu}>
<Grow in={isPostMenuOpen!} id='post-menu' style={{ transformOrigin: '0 0 0' }}> <Grow in={isPostMenuOpen!} style={{ transformOrigin: '0 0 0' }}>
<Paper> <Paper>
<MenuList role='menu'> <MenuList role='menu'>
<MenuItem onClick={this.handleOpenPostWrite} > Edit </MenuItem> <MenuItem onClick={this.handleOpenPostWrite} > Edit </MenuItem>
@@ -537,4 +537,4 @@ const mapStateToProps = (state: any, ownProps: IPostComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(PostComponent as any) as any) export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles as any)(PostComponent as any) as any)

View File

@@ -49,8 +49,9 @@ export class PostPageComponent extends Component<IPostPageComponentProps,IPostPa
* @return {react element} return the DOM which rendered by component * @return {react element} return the DOM which rendered by component
*/ */
render () { render () {
const St = Stream as any
return ( return (
<Stream posts={this.props.posts} displayWriting={false} /> <St posts={this.props.posts} displayWriting={false} />
) )
} }
} }

View File

@@ -25,9 +25,9 @@ import IconButton from 'material-ui/IconButton'
import TextField from 'material-ui/TextField' import TextField from 'material-ui/TextField'
import Tooltip from 'material-ui/Tooltip' import Tooltip from 'material-ui/Tooltip'
import { MenuList, MenuItem } from 'material-ui/Menu' import { MenuList, MenuItem } from 'material-ui/Menu'
import SvgRemoveImage from 'material-ui-icons/removeCircle' import SvgRemoveImage from 'material-ui-icons/RemoveCircle'
import SvgCamera from 'material-ui-icons/photoCamera' import SvgCamera from 'material-ui-icons/PhotoCamera'
import MoreVertIcon from 'material-ui-icons/moreVert' import MoreVertIcon from 'material-ui-icons/MoreVert'
import { withStyles } from 'material-ui/styles' import { withStyles } from 'material-ui/styles'
import { Manager, Target, Popper } from 'react-popper' import { Manager, Target, Popper } from 'react-popper'
import Grow from 'material-ui/transitions/Grow' import Grow from 'material-ui/transitions/Grow'
@@ -87,7 +87,7 @@ export class PostWriteComponent extends Component<IPostWriteComponentProps, IPos
* Component constructor * Component constructor
* @param {object} props is an object properties of component * @param {object} props is an object properties of component
*/ */
constructor(props: IPostWriteComponentProps) { constructor (props: IPostWriteComponentProps) {
super(props) super(props)
@@ -323,7 +323,7 @@ export class PostWriteComponent extends Component<IPostWriteComponentProps, IPos
}) })
} }
componentWillReceiveProps(nextProps: IPostWriteComponentProps) { componentWillReceiveProps (nextProps: IPostWriteComponentProps) {
if (!nextProps.open) { if (!nextProps.open) {
const { postModel } = this.props const { postModel } = this.props
this.setState({ this.setState({
@@ -364,7 +364,7 @@ export class PostWriteComponent extends Component<IPostWriteComponentProps, IPos
* Reneder component DOM * Reneder component DOM
* @return {react element} return the DOM which rendered by component * @return {react element} return the DOM which rendered by component
*/ */
render() { render () {
const { classes } = this.props const { classes } = this.props
const { menuOpen } = this.state const { menuOpen } = this.state
@@ -421,7 +421,8 @@ export class PostWriteComponent extends Component<IPostWriteComponentProps, IPos
* Provide post image * Provide post image
*/ */
const loadImage = (this.state.image && this.state.image !== '') const loadImage = (this.state.image && this.state.image !== '')
? (<div> ? (
<div>
<div style={{ position: 'relative', overflowY: 'hidden', overflowX: 'auto' }}> <div style={{ position: 'relative', overflowY: 'hidden', overflowX: 'auto' }}>
<ul style={{ position: 'relative', whiteSpace: 'nowrap', padding: '0 0 0 16px', margin: '8px 0 0 0', paddingRight: '16px', verticalAlign: 'bottom', flexShrink: 0, listStyleType: 'none' }}> <ul style={{ position: 'relative', whiteSpace: 'nowrap', padding: '0 0 0 16px', margin: '8px 0 0 0', paddingRight: '16px', verticalAlign: 'bottom', flexShrink: 0, listStyleType: 'none' }}>
<div style={{ display: 'flex', position: 'relative' }}> <div style={{ display: 'flex', position: 'relative' }}>
@@ -442,7 +443,8 @@ export class PostWriteComponent extends Component<IPostWriteComponentProps, IPos
</ul> </ul>
</div> </div>
</div>) : '' </div>
) : ''
const styles = { const styles = {
dialog: { dialog: {
@@ -579,4 +581,4 @@ const mapStateToProps = (state: any, ownProps: IPostWriteComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(PostWriteComponent as any) as any) export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles as any)(PostWriteComponent as any) as any)

View File

@@ -78,7 +78,7 @@ export class ProfileComponent extends Component<IProfileComponentProps,IProfileC
} }
} }
const {loadPosts, hasMorePosts} = this.props const {loadPosts, hasMorePosts} = this.props
const St = StreamComponent as any
return ( return (
<div style={styles.profile}> <div style={styles.profile}>
<div style={styles.header}> <div style={styles.header}>
@@ -92,7 +92,7 @@ export class ProfileComponent extends Component<IProfileComponentProps,IProfileC
</div> </div>
<div style={{ height: '24px' }}></div> <div style={{ height: '24px' }}></div>
<StreamComponent <St
posts={this.props.posts} posts={this.props.posts}
loadStream={loadPosts} loadStream={loadPosts}
hasMorePosts={hasMorePosts} hasMorePosts={hasMorePosts}

View File

@@ -1,8 +1,8 @@
// - Import react components // - Import react components
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { grey400 } from 'material-ui/styles/colors' import { grey } from 'material-ui/colors'
import SvgClose from 'material-ui-icons/close' import SvgClose from 'material-ui-icons/Close'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import Divider from 'material-ui/Divider' import Divider from 'material-ui/Divider'
import { IDialogTitleComponentProps } from './IDialogTitleComponentProps' import { IDialogTitleComponentProps } from './IDialogTitleComponentProps'
@@ -76,13 +76,15 @@ export default class DialogTitleComponent extends Component<IDialogTitleComponen
<div className='g__dialog-title'> <div className='g__dialog-title'>
<div style={this.styles.contain as any}> <div style={this.styles.contain as any}>
<div style={{ paddingRight: '10px' }}> <div style={{ paddingRight: '10px' }}>
<SvgClose onClick={onRequestClose} hoverColor={grey400} style={{ cursor: 'pointer' }} /> <SvgClose onClick={onRequestClose} style={{ cursor: 'pointer' }} />
</div> </div>
<div style={this.styles.title}> <div style={this.styles.title}>
{title || ''} {title || ''}
</div> </div>
{ buttonLabel ? (<div style={{ marginTop: '-9px' }}> { buttonLabel ? (<div style={{ marginTop: '-9px' }}>
<Button label={buttonLabel || ''} color='primary' disabled={disabledButton ? disabledButton : false} onClick={onClickButton || (x => x)} /> <Button color='primary' disabled={disabledButton ? disabledButton : false} onClick={onClickButton || (x => x)}>
{buttonLabel || ''}
</Button>
</div>) : ''} </div>) : ''}
</div> </div>
<Divider /> <Divider />

View File

@@ -4,7 +4,7 @@ import { connect } from 'react-redux'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import MoreVertIcon from 'material-ui-icons/moreVert' import MoreVertIcon from 'material-ui-icons/MoreVert'
import { MenuList, MenuItem } from 'material-ui/Menu' import { MenuList, MenuItem } from 'material-ui/Menu'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import RaisedButton from 'material-ui/Button' import RaisedButton from 'material-ui/Button'

View File

@@ -189,4 +189,4 @@ const mapStateToProps = (state: any, ownProps: IResetPasswordComponentProps) =>
} }
// - Connect component to redux store // - Connect component to redux store
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(ResetPasswordComponent as any) as any)) export default withRouter(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(ResetPasswordComponent as any) as any) as any)

View File

@@ -5,9 +5,9 @@ import { connect } from 'react-redux'
import Paper from 'material-ui/Paper' import Paper from 'material-ui/Paper'
import TextField from 'material-ui/TextField' import TextField from 'material-ui/TextField'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import SvgHappy from 'material-ui-icons/tagFaces' import SvgHappy from 'material-ui-icons/TagFaces'
import SvgSad from 'material-ui-icons/face' import SvgSad from 'material-ui-icons/Face'
import SvgClose from 'material-ui-icons/clear' import SvgClose from 'material-ui-icons/Clear'
import { CircularProgress } from 'material-ui/Progress' import { CircularProgress } from 'material-ui/Progress'
import Tooltip from 'material-ui/Tooltip' import Tooltip from 'material-ui/Tooltip'
@@ -122,7 +122,8 @@ export class SendFeedbackComponent extends Component<ISendFeedbackComponentProps
} }
loadingForm = () => { loadingForm = () => {
return (<div className='loading'> return (
<div className='loading'>
<p> <p>
Your feedback is sending! Your feedback is sending!
</p> </p>

View File

@@ -228,4 +228,4 @@ const mapStateToProps = (state: any, ownProps: ISettingComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(SettingComponent as any) as any)) export default withRouter(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(SettingComponent as any) as any) as any)

View File

@@ -171,7 +171,7 @@ export class SidebarComponent extends Component<ISidebarComponentProps,ISidebarC
if (!this.state.auto && this.state.open) { if (!this.state.auto && this.state.open) {
this.open(false, 'auto') this.open(false, 'auto')
}else { } else {
this.setState({ this.setState({
overlayOpen: true, overlayOpen: true,
overlay: this.state.open overlay: this.state.open

View File

@@ -10,7 +10,7 @@ import { ISidebarContentComponentState } from './ISidebarContentComponentState'
// - Create component class // - Create component class
export default class SidebarContentComponent extends Component<ISidebarContentComponentProps,ISidebarContentComponentState> { export default class SidebarContentComponent extends Component<ISidebarContentComponentProps,ISidebarContentComponentState> {
static qcName= 'SidebarContent' static qcName = 'SidebarContent'
/** /**
* Component constructor * Component constructor

View File

@@ -228,7 +228,7 @@ export class SignupComponent extends Component<ISignupComponentProps,ISignupComp
<TextField <TextField
className={classes.textField} className={classes.textField}
onChange={this.handleInputChange} onChange={this.handleInputChange}
helperText={this.state.passwordInputError } helperText={this.state.passwordInputError}
error={this.state.passwordInputError.trim() !== ''} error={this.state.passwordInputError.trim() !== ''}
name='passwordInput' name='passwordInput'
label='Password' label='Password'
@@ -237,7 +237,7 @@ export class SignupComponent extends Component<ISignupComponentProps,ISignupComp
<TextField <TextField
className={classes.textField} className={classes.textField}
onChange={this.handleInputChange} onChange={this.handleInputChange}
helperText={this.state.confirmInputError } helperText={this.state.confirmInputError}
error={this.state.confirmInputError.trim() !== ''} error={this.state.confirmInputError.trim() !== ''}
name='confirmInput' name='confirmInput'
label='Confirm Password' label='Confirm Password'
@@ -296,4 +296,4 @@ const mapStateToProps = (state: any,ownProps: ISignupComponentProps) => {
} }
// - Connect component to redux store // - Connect component to redux store
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(withStyles(styles)(SignupComponent as any) as any)) export default withRouter(connect(mapStateToProps,mapDispatchToProps)(withStyles(styles)(SignupComponent as any) as any) as any)

View File

@@ -69,12 +69,12 @@ export interface IStreamComponentProps {
/** /**
* Load the data for stream * Load the data for stream
*/ */
loadStream: (page: number, limit: number) => any loadStream?: (page: number, limit: number) => any
/** /**
* If there is more post {true} or not {false} * If there is more post {true} or not {false}
*/ */
hasMorePosts: boolean hasMorePosts?: boolean
/** /**
* Posts for stream * Posts for stream
@@ -87,5 +87,5 @@ export interface IStreamComponentProps {
/** /**
* Router match property * Router match property
*/ */
match: any match?: any
} }

View File

@@ -5,7 +5,7 @@ import { connect } from 'react-redux'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import { grey,teal } from 'material-ui/colors' import { grey,teal } from 'material-ui/colors'
import SvgCamera from 'material-ui-icons/photoCamera' import SvgCamera from 'material-ui-icons/PhotoCamera'
import Paper from 'material-ui/Paper' import Paper from 'material-ui/Paper'
import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List' import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List'
import InfiniteScroll from 'react-infinite-scroller' import InfiniteScroll from 'react-infinite-scroller'
@@ -149,7 +149,7 @@ export class StreamComponent extends Component<IStreamComponentProps,IStreamComp
if (postMatch !== null) { if (postMatch !== null) {
parsedPosts.push({ ...posts[postId]}) parsedPosts.push({ ...posts[postId]})
} }
}else { } else {
parsedPosts.push({ ...posts[postId]}) parsedPosts.push({ ...posts[postId]})
} }
@@ -174,7 +174,7 @@ export class StreamComponent extends Component<IStreamComponentProps,IStreamComp
if ((index % 2) === 1 && postBack.divided) { if ((index % 2) === 1 && postBack.divided) {
postBack.oddPostList.push(newPost as never) postBack.oddPostList.push(newPost as never)
}else { } else {
postBack.evenPostList.push(newPost as never) postBack.evenPostList.push(newPost as never)
} }
}) })
@@ -188,7 +188,7 @@ export class StreamComponent extends Component<IStreamComponentProps,IStreamComp
*/ */
scrollLoad = (page: number) => { scrollLoad = (page: number) => {
const {loadStream} = this.props const {loadStream} = this.props
loadStream(page, 10) loadStream!(page, 10)
} }
componentWillMount () { componentWillMount () {
@@ -211,10 +211,10 @@ export class StreamComponent extends Component<IStreamComponentProps,IStreamComp
loadMore={this.scrollLoad} loadMore={this.scrollLoad}
hasMore={hasMorePosts} hasMore={hasMorePosts}
useWindow={true} useWindow={true}
loader={ <LoadMoreProgressComponent />} loader={<LoadMoreProgressComponent />}
> >
<div className='grid grid__gutters grid__1of2 grid__space-around animate-top'> <div className='grid grid__gutters grid__1of2 grid__space-around animate-top'>
<div className='grid-cell animate-top' style= {{maxWidth: '530px', minWidth: '280px'}}> <div className='grid-cell animate-top' style={{maxWidth: '530px', minWidth: '280px'}}>
{displayWriting && !tag {displayWriting && !tag
? (<PostWriteComponent open={this.state.openPostWrite} onRequestClose={this.handleClosePostWrite} edit={false} > ? (<PostWriteComponent open={this.state.openPostWrite} onRequestClose={this.handleClosePostWrite} edit={false} >
<Paper elevation={2}> <Paper elevation={2}>

View File

@@ -19,5 +19,5 @@ export interface IUserAvatarComponentProps {
/** /**
* Trigger on touch tap * Trigger on touch tap
*/ */
onClick?: (event: any) => anys onClick?: (event: any) => any
} }

View File

@@ -41,7 +41,7 @@ export interface IUserBoxComponentProps {
/** /**
* Whether current user followed this user * Whether current user followed this user
*/ */
isFollowed: boolean isFollowed?: boolean
/** /**
* The number of circles * The number of circles

View File

@@ -1,6 +1,6 @@
// - Import react components // - Import react components
import React, { Component } from 'react' import React, { Component } from 'react'
import moment from 'moment' import moment from 'moment/moment'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { push } from 'react-router-redux' import { push } from 'react-router-redux'
@@ -21,7 +21,7 @@ import Dialog, {
DialogTitle, DialogTitle,
withMobileDialog withMobileDialog
} from 'material-ui/Dialog' } from 'material-ui/Dialog'
import SvgAdd from 'material-ui-icons/add' import SvgAdd from 'material-ui-icons/Add'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'

View File

@@ -0,0 +1,10 @@
export const environment = {
firebase: {
apiKey: 'AIzaSyAHOZ7rWGDODCwJMB3WIt63CAIa90qI-jg',
authDomain: 'test-4515a.firebaseapp.com',
databaseURL: 'https://test-4515a.firebaseio.com',
projectId: 'test-4515a',
storageBucket: 'test-4515a.appspot.com',
messagingSenderId: '964743099489'
}
}

View File

@@ -0,0 +1,10 @@
export const environment = {
firebase: {
apiKey: 'AIzaSyAHOZ7rWGDODCwJMB3WIt63CAIa90qI-jg',
authDomain: 'test-4515a.firebaseapp.com',
databaseURL: 'https://test-4515a.firebaseio.com',
projectId: 'test-4515a',
storageBucket: 'test-4515a.appspot.com',
messagingSenderId: '964743099489'
}
}

17
src/config/index.ts Normal file
View File

@@ -0,0 +1,17 @@
import {environment as prod } from './environment.prod'
import {environment as dev } from './environment.dev'
const config = {
// Add common config values here
}
const configEnv = process.env.NODE_ENV === 'production'
? prod
: dev
export default {
// Add common config values here
...config,
...configEnv
}

View File

@@ -1,5 +1,5 @@
import { Circle } from './circle' import { Circle } from './circle'
import { UserTie } from './UserTie' import { UserTie } from './userTie'
export { export {
Circle, Circle,

View File

@@ -1,4 +1,4 @@
export class BaseDomain{ export class BaseDomain {
} }

View File

@@ -1,5 +1,5 @@
import { User } from 'core/domain/users' import { User } from 'core/domain/users'
import { Feed } from 'core/domain/common'; import { Feed } from 'core/domain/common'
/** /**
* Common service interface * Common service interface

View File

@@ -44,6 +44,4 @@ export const useFirestore = (container: Container) => {
container.bind<IGraphService>(FirestoreClientTypes.GraphService).to(GraphService) container.bind<IGraphService>(FirestoreClientTypes.GraphService).to(GraphService)
container.bind<IUserTieService>(SocialProviderTypes.UserTieService).to(UserTieService) container.bind<IUserTieService>(SocialProviderTypes.UserTieService).to(UserTieService)
} }

View File

@@ -1,16 +1,17 @@
import firebase from 'firebase' import firebase from 'firebase'
import 'firebase/firestore' import 'firebase/firestore'
import config from 'src/config'
try { try {
let config = { let firebaseConfig = {
apiKey: process.env.API_KEY, apiKey: config.firebase.apiKey,
authDomain: process.env.AUTH_DOMAIN, authDomain: config.firebase.authDomain,
databaseURL: process.env.DATABASE_URL, databaseURL: config.firebase.databaseURL,
projectId: process.env.PROJECT_ID, projectId: config.firebase.projectId,
storageBucket: process.env.STORAGE_BUCKET, storageBucket: config.firebase.storageBucket,
messagingSenderId: process.env.MESSAGING_SENDER_ID messagingSenderId: config.firebase.messagingSenderId
} }
firebase.initializeApp(config) firebase.initializeApp(firebaseConfig)
} catch (error) { } catch (error) {
console.log('=========Firebase firestore initializer==============') console.log('=========Firebase firestore initializer==============')
console.log(error) console.log(error)

View File

@@ -9,7 +9,7 @@ import { LoginUser, RegisterUserResult } from 'core/domain/authorize'
import { SocialError } from 'core/domain/common' import { SocialError } from 'core/domain/common'
import { OAuthType } from 'core/domain/authorize/oauthType' import { OAuthType } from 'core/domain/authorize/oauthType'
import moment from 'moment' import moment from 'moment/moment'
import { injectable } from 'inversify' import { injectable } from 'inversify'
/** /**
* Firbase authorize service * Firbase authorize service

View File

@@ -1,7 +1,7 @@
// - Import react components // - Import react components
import { datumString } from 'aws-sdk/clients/athena' import { datumString } from 'aws-sdk/clients/athena'
import firebase, { firebaseRef, firebaseAuth, db } from 'data/firestoreClient' import firebase, { firebaseRef, firebaseAuth, db } from 'data/firestoreClient'
import moment from 'moment' import moment from 'moment/moment'
import { SocialError } from 'core/domain/common' import { SocialError } from 'core/domain/common'
import { Profile, UserProvider, User } from 'core/domain/users' import { Profile, UserProvider, User } from 'core/domain/users'

View File

@@ -96,7 +96,7 @@ export class GraphService implements IGraphService {
// Delete documents in a batch // Delete documents in a batch
let batch = db.batch() let batch = db.batch()
snapshot.docs.forEach(function (doc) { snapshot.docs.forEach(function (doc: any) {
batch.delete(doc.ref) batch.delete(doc.ref)
}) })
@@ -115,7 +115,7 @@ export class GraphService implements IGraphService {
private getGraphsQuery: (collection: string, leftNode?: string | null, edgeType?: string, rightNode?: string | null) private getGraphsQuery: (collection: string, leftNode?: string | null, edgeType?: string, rightNode?: string | null)
=> Promise<firebase.firestore.QuerySnapshot> = (collection, leftNode, edgeType, rightNode) => { => Promise<firebase.firestore.QuerySnapshot> = (collection, leftNode, edgeType, rightNode) => {
return new Promise<firebase.firestore.QuerySnapshot>((resolve,reject) => { return new Promise<firebase.firestore.QuerySnapshot>((resolve,reject) => {
let graphsRef = db.collection(`graphs:${collection}`) let graphsRef = db.collection(`graphs:${collection}`) as any
if (leftNode != null) { if (leftNode != null) {
graphsRef = graphsRef.where('leftNode', '==', leftNode) graphsRef = graphsRef.where('leftNode', '==', leftNode)
@@ -129,14 +129,14 @@ export class GraphService implements IGraphService {
} }
if (graphsRef) { if (graphsRef) {
graphsRef.get().then((result) => { graphsRef.get().then((result: any) => {
resolve(result) resolve(result)
}).catch((error) => reject(error)) }).catch((error: any) => reject(error))
} else { } else {
graphsRef.get().then((result) => { graphsRef.get().then((result: any) => {
resolve(result) resolve(result)
}).catch((error) => reject(error)) }).catch((error: any) => reject(error))
} }
}) })

View File

@@ -1,5 +1,5 @@
import { VoteService } from './VoteService' import { GraphService } from './GraphService'
export { export {
VoteService GraphService
} }

View File

@@ -108,7 +108,7 @@ export class PostService implements IPostService {
postList = [ postList = [
...postList, ...postList,
...result.posts ...result.posts
]; ]
resolve(this.pagingPosts(postList, lastPostId, limit)) resolve(this.pagingPosts(postList, lastPostId, limit))
}) })

View File

@@ -1,6 +1,6 @@
// - Import react components // - Import react components
import firebase, { firebaseRef, firebaseAuth, db } from 'data/firestoreClient' import firebase, { firebaseRef, firebaseAuth, db } from 'data/firestoreClient'
import moment from 'moment' import moment from 'moment/moment'
import { SocialError } from 'core/domain/common' import { SocialError } from 'core/domain/common'
import { Profile, UserProvider } from 'core/domain/users' import { Profile, UserProvider } from 'core/domain/users'

View File

@@ -1,11 +1,11 @@
// Import external components refrence // Import external components refrence
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import injectTapEventPlugin from 'react-tap-event-plugin' import injectTapEventPlugin from 'react-tap-event-plugin'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles' import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles'
import 'reflect-metadata' import 'reflect-metadata'
import 'typeface-roboto' import 'typeface-roboto'
import registerServiceWorker from './registerServiceWorker'
import { Provider } from 'react-redux' import { Provider } from 'react-redux'
import store, { history } from 'store/configureStore' import store, { history } from 'store/configureStore'
@@ -21,7 +21,7 @@ store.subscribe(() => { })
// Needed for onClick // Needed for onClick
// http://stackoverflow.com/a/34015469/988941 // http://stackoverflow.com/a/34015469/988941
try { injectTapEventPlugin() } catch (e) { } try { injectTapEventPlugin() } catch (e) {}
const theme = createMuiTheme({ const theme = createMuiTheme({
palette: { palette: {
@@ -30,7 +30,7 @@ const theme = createMuiTheme({
} }
}) })
// App css // App css
import 'applicationStyles' import './styles/app.css'
/** /**
* Execute startup functions * Execute startup functions
@@ -38,24 +38,14 @@ import 'applicationStyles'
import './socialEngine' import './socialEngine'
const supportsHistory = 'pushState' in window.history const supportsHistory = 'pushState' in window.history
const render = (Component: any) => { ReactDOM.render(
ReactDOM.render(
<AppContainer warnings={false}>
<Provider store={store}> <Provider store={store}>
<ConnectedRouter history={history}> <ConnectedRouter history={history}>
<MuiThemeProvider theme={theme}> <MuiThemeProvider theme={theme}>
<Component /> <Master />
</MuiThemeProvider> </MuiThemeProvider>
</ConnectedRouter> </ConnectedRouter>
</Provider> </Provider>,
</AppContainer>, document.getElementById('app') as HTMLElement
document.getElementById('app') )
) registerServiceWorker()
}
render(Master)
// Webpack Hot Module Replacement API
if (module.hot) {
module.hot.accept()
}

View File

@@ -2,7 +2,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'
import SvgClose from 'material-ui-icons/close' import SvgClose from 'material-ui-icons/Close'
import Button from 'material-ui/Button' import Button from 'material-ui/Button'
import Divider from 'material-ui/Divider' import Divider from 'material-ui/Divider'
import { IDialogTitleComponentProps } from './IDialogTitleComponentProps' import { IDialogTitleComponentProps } from './IDialogTitleComponentProps'
@@ -76,13 +76,13 @@ export default class DialogTitleComponent extends Component<IDialogTitleComponen
<div className='g__dialog-title'> <div className='g__dialog-title'>
<div style={this.styles.contain as any}> <div style={this.styles.contain as any}>
<div style={{ paddingRight: '10px' }}> <div style={{ paddingRight: '10px' }}>
<SvgClose onClick={onRequestClose} hoverColor={grey[400]} style={{ cursor: 'pointer' }} /> <SvgClose onClick={onRequestClose} style={{ cursor: 'pointer' }} />
</div> </div>
<div style={this.styles.title}> <div style={this.styles.title}>
{title || ''} {title || ''}
</div> </div>
{ buttonLabel ? (<div style={{ marginTop: '-9px' }}> { buttonLabel ? (<div style={{ marginTop: '-9px' }}>
<Button label={buttonLabel || ''} color='primary' disabled={disabledButton ? disabledButton : false} onClick={onClickButton || (x => x)} /> <Button color='primary' disabled={disabledButton ? disabledButton : false} onClick={onClickButton || (x => x)}> {buttonLabel || ''} </Button>
</div>) : ''} </div>) : ''}
</div> </div>
<Divider /> <Divider />

View File

@@ -1,7 +1,7 @@
// - Import react components // - Import react components
import React, { Component } from 'react' import React, { Component } from 'react'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
import MoreVertIcon from 'material-ui-icons/moreVert' import MoreVertIcon from 'material-ui-icons/MoreVert'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'
/** /**

View File

@@ -1,5 +1,5 @@
// - Import react components // - Import react components
import moment from 'moment' import moment from 'moment/moment'
import _ from 'lodash' import _ from 'lodash'
// - Import domain // - Import domain

View File

@@ -1,5 +1,5 @@
// - Import react components // - Import react components
import moment from 'moment' import moment from 'moment/moment'
import _ from 'lodash' import _ from 'lodash'
// - Import domain // - Import domain

View File

@@ -1,5 +1,5 @@
// - Import react components // - Import react components
import moment from 'moment' import moment from 'moment/moment'
import _ from 'lodash' import _ from 'lodash'
// - Import domain // - Import domain

View File

@@ -1,5 +1,5 @@
// - Import react components // - Import react components
import moment from 'moment' import moment from 'moment/moment'
import _ from 'lodash' import _ from 'lodash'
import { Reducer, Action } from 'redux' import { Reducer, Action } from 'redux'

View File

@@ -1,5 +1,5 @@
// - Import react components // - Import react components
import moment from 'moment' import moment from 'moment/moment'
import _ from 'lodash' import _ from 'lodash'
// - Import action types // - Import action types

View File

@@ -0,0 +1,108 @@
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
} else {
// Is not local host. Just register service worker
registerValidSW(swUrl);
}
});
}
}
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}

View File

@@ -0,0 +1,114 @@
// tslint:disable:no-console
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the 'N+1' visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
)
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(
process.env.PUBLIC_URL!,
window.location.toString()
)
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
if (!isLocalhost) {
// Is not local host. Just register service worker
registerValidSW(swUrl)
} else {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl)
}
})
}
}
function registerValidSW(swUrl: string) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing
if (installingWorker) {
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a 'New content is
// available; please refresh.' message in your web app.
console.log('New content is available; please refresh.')
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// 'Content is cached for offline use.' message.
console.log('Content is cached for offline use.')
}
}
}
}
}
})
.catch(error => {
console.error('Error during service worker registration:', error)
})
}
function checkValidServiceWorker(swUrl: string) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type')!.indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload()
})
})
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl)
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
)
})
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister()
})
}
}

View File

@@ -19,18 +19,20 @@ import { IRouterProps } from './IRouterProps'
export class HomeRouter extends Component<IRouterProps, any> { export class HomeRouter extends Component<IRouterProps, any> {
render () { render () {
const { enabled, match, data } = this.props const { enabled, match, data } = this.props
const St = StreamComponent as any
return ( return (
enabled ? (<Switch> enabled ? (
<Switch>
<PrivateRoute path='/people/:tab?' component={<People />} /> <PrivateRoute path='/people/:tab?' component={<People />} />
<PrivateRoute path='/tag/:tag' component={( <PrivateRoute path='/tag/:tag' component={(
<div className='blog'><StreamComponent displayWriting={false} homeTitle={`#${match.params.tag}`} posts={data.mergedPosts} /></div> <div className='blog'><St displayWriting={false} homeTitle={`#${match.params.tag}`} posts={data.mergedPosts} /></div>
)} /> )} />
<Route path='/:userId/posts/:postId/:tag?' component={PostPage} /> <Route path='/:userId/posts/:postId/:tag?' component={PostPage} />
<Route path='/:userId' component={Profile} /> <Route path='/:userId' component={Profile} />
<PrivateRoute path='/' component={( <PrivateRoute path='/' component={(
<div className='blog'> <div className='blog'>
<StreamComponent <St
homeTitle='Home' homeTitle='Home'
posts={data.mergedPosts} posts={data.mergedPosts}
loadStream={data.loadDataStream} loadStream={data.loadDataStream}
@@ -38,10 +40,11 @@ export class HomeRouter extends Component<IRouterProps, any> {
displayWriting={true} /> displayWriting={true} />
</div> </div>
)} /> )} />
</Switch>) </Switch>
)
: '' : ''
) )
} }
} }
export default withRouter(connect(null, null)(HomeRouter as any)) export default withRouter(connect(null, null)(HomeRouter as any) as any)

View File

@@ -21,6 +21,6 @@ export interface IRouterProps {
* @type {*} * @type {*}
* @memberof IRouterProps * @memberof IRouterProps
*/ */
match: any match?: any
} }

View File

@@ -23,7 +23,8 @@ export class MasterRouter extends Component<IRouterProps, any> {
render () { render () {
const { enabled, match, data } = this.props const { enabled, match, data } = this.props
return ( return (
enabled ? (<Switch> enabled ? (
<Switch>
<Route path='/signup' component={Signup} /> <Route path='/signup' component={Signup} />
<Route path='/emailVerification' component={EmailVerification} /> <Route path='/emailVerification' component={EmailVerification} />
<Route path='/settings' component={Setting} /> <Route path='/settings' component={Setting} />
@@ -36,4 +37,4 @@ export class MasterRouter extends Component<IRouterProps, any> {
) )
} }
} }
export default withRouter(connect(null, null)(MasterRouter as any)) export default withRouter<any>(connect(null, null)(MasterRouter as any)) as typeof MasterRouter

948
src/styles/app.css Normal file
View File

@@ -0,0 +1,948 @@
.grid {
display: flex;
flex-flow: row;
flex-wrap: wrap; }
.grid__gutters {
margin-left: -1em; }
.grid__gutters .grid-cell {
padding-left: 1em; }
/* Justify per row*/
.grid__right {
justify-content: flex-end; }
.grid__left {
justify-content: flex-start; }
.grid__center {
justify-content: center; }
.grid__space-around {
justify-content: space-around; }
/* Alignment per row */
.grid__top {
align-items: flex-start; }
.grid__bottom {
align-items: flex-end; }
.grid__center {
align-items: center; }
/* Alignment per cell */
.grid-cell__top {
align-self: flex-start; }
.grid-cell__bottom {
align-self: flex-end; }
.grid-cell__center {
align-self: center; }
.grid__fit > .grid-cell {
flex: 1; }
.grid__full > .grid-cell {
flex: 0 0 100%; }
@media (min-width: 400px) {
.grid__cols-2 > .grid-cell,
.grid__cols-3 > .grid-cell,
.grid__cols-4 > .grid-cell,
.grid__cols-6 > .grid-cell,
.grid__cols-12 > .grid-cell {
flex: 1; }
.grid__1of2 > .grid-cell {
flex: 1; }
.grid__1of6 > .grid-cell {
flex: 0 0 16.6666%; }
.grid__1of4 > .grid-cell {
flex: 0 0 calc(48.6666% - 1em); }
.grid__1of3 > .grid-cell {
flex: 0 0 30%; } }
@media (min-width: 600px) {
.grid__cols-2 > .grid-cell,
.grid__cols-3 > .grid-cell,
.grid__cols-4 > .grid-cell,
.grid__cols-6 > .grid-cell,
.grid__cols-12 > .grid-cell {
flex: 1; }
.grid__1of2 > .grid-cell {
flex: 1; }
.grid__1of6 > .grid-cell {
flex: 0 0 16.6666%; }
.grid__1of4 > .grid-cell {
flex: 0 0 calc(48.6666% - 1em); }
.grid__1of3 > .grid-cell {
flex: 0 0 30%; } }
@media (min-width: 1000px) {
.grid__cols-2 > .grid-cell,
.grid__cols-3 > .grid-cell,
.grid__cols-4 > .grid-cell,
.grid__cols-6 > .grid-cell,
.grid__cols-12 > .grid-cell {
flex: 1; }
.grid__1of2 > .grid-cell {
flex: 0 0 50%;
flex-grow: 1; }
.grid__1of6 > .grid-cell {
flex: 0 0 16.6666%; }
.grid__1of4 > .grid-cell {
flex: 0 0 calc(24.33333% - 1em);
flex-grow: 1; }
.grid__1of3 > .grid-cell {
flex: 0 0 30%; } }
.animate__up {
animation-duration: .3s;
animation-name: staggerItems;
animation-timing-function: ease-out; }
@keyframes staggerItems {
0% {
-webkit-transform: translateY(30px);
transform: translateY(30px); } }
.spin {
animation: spin 2s infinite linear; }
@keyframes spin {
0% {
transform: rotate(0deg); }
100% {
transform: rotate(359deg); } }
.animate-fading {
animation: fading 10s infinite; }
@keyframes fading {
0% {
opacity: 0; }
50% {
opacity: 1; }
100% {
opacity: 0; } }
.animate-fading2 {
animation: fading 2s infinite; }
@keyframes fading {
0% {
opacity: 0; }
50% {
opacity: 1; }
100% {
opacity: 0; } }
.animate-opacity {
animation: opac 0.8s; }
@keyframes opac {
from {
opacity: 0; }
to {
opacity: 1; } }
.animate-top {
position: relative;
animation: animatetop 0.4s; }
@keyframes animatetop {
from {
top: -300px;
opacity: 0; }
to {
top: 0;
opacity: 1; } }
.animate2-top10 {
position: relative;
animation: animatetop 0.2s; }
@keyframes animatetop {
from {
top: -10px;
opacity: 0; }
to {
top: 0;
opacity: 1; } }
.animate-left {
position: relative;
animation: animateleft 0.4s; }
@keyframes animateleft {
from {
left: -300px;
opacity: 0; }
to {
left: 0;
opacity: 1; } }
.animate-right {
position: relative;
animation: animateright 0.4s; }
@keyframes animateright {
from {
right: -300px;
opacity: 0; }
to {
right: 0;
opacity: 1; } }
.animate-bottom {
position: relative;
animation: animatebottom 0.4s; }
@keyframes animatebottom {
from {
bottom: -300px;
opacity: 0; }
to {
bottom: 0;
opacity: 1; } }
.animate-bottom50 {
position: relative;
animation: animatebottom 0.4s; }
@keyframes animatebottom {
from {
bottom: -50px;
opacity: 0; }
to {
bottom: 0;
opacity: 1; } }
.animated {
animation-duration: .5s;
animation-fill-mode: both; }
.animated.infinite {
animation-iteration-count: infinite; }
.animated.hinge {
animation-duration: 2s; }
@keyframes zoomOutUp {
40% {
opacity: 1;
transform: scale3d(1, 1, 1) translate3d(0, 0px, 0);
animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); }
to {
transform: scale3d(0.8, 0.8, 0.8) translate3d(-80px, -40px, 0);
transform-origin: center bottom;
animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); } }
.zoomOutLCorner {
animation-name: zoomOutUp; }
.icon {
width: 24px;
height: 24px;
display: inline-block; }
.icon-github {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20fill%3D%22#24292e%22%20stroke%3D%22transparent%22%20stroke-width%3D%220%22%20style%3D%22%22%20d%3D%22M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12%22%20%2F%3E%3C%2Fsvg%3E"); }
.icon-google {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20fill%3D%22#db4437%22%20stroke%3D%22transparent%22%20stroke-width%3D%220%22%20style%3D%22%22%20d%3D%22M7.635 10.909v2.619h4.335c-.173 1.125-1.31 3.295-4.331 3.295-2.604 0-4.731-2.16-4.731-4.823 0-2.662 2.122-4.822 4.728-4.822 1.485 0 2.479.633 3.045 1.178l2.073-1.994c-1.33-1.245-3.056-1.995-5.115-1.995C3.412 4.365 0 7.785 0 12s3.414 7.635 7.635 7.635c4.41 0 7.332-3.098 7.332-7.461 0-.501-.054-.885-.12-1.265H7.635zm16.365 0h-2.183V8.726h-2.183v2.183h-2.182v2.181h2.184v2.184h2.189V13.09H24%22%20%2F%3E%3C%2Fsvg%3E"); }
.icon-fb {
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20fill%3D%22#4267b2%22%20stroke%3D%22transparent%22%20stroke-width%3D%220%22%20style%3D%22%22%20d%3D%22M22.676 0H1.324C.593 0 0 .593 0 1.324v21.352C0 23.408.593 24 1.324 24h11.494v-9.294H9.689v-3.621h3.129V8.41c0-3.099 1.894-4.785 4.659-4.785 1.325 0 2.464.097 2.796.141v3.24h-1.921c-1.5 0-1.792.721-1.792 1.771v2.311h3.584l-.465 3.63H16.56V24h6.115c.733 0 1.325-.592 1.325-1.324V1.324C24 .593 23.408 0 22.676 0%22%20%2F%3E%3C%2Fsvg%3E"); }
.icon__svg {
padding: 10px;
display: block;
font-family: "Flaticon";
font-size: 64px;
line-height: 1;
transform: translate(-10px, -9px); }
/*
Flaticon icon font: Flaticon
*/
@font-face {
font-family: "Flaticon";
src: url("../assets/fonts/Flaticon.eot");
src: url("../assets/fonts/Flaticon.eot?#iefix") format("embedded-opentype"), url("../assets/fonts/Flaticon.woff") format("woff"), url("../assets/fonts/Flaticon.ttf") format("truetype"), url("../assets/images/Flaticon.svg#Flaticon") format("svg");
font-weight: normal;
font-style: normal; }
@media screen and (-webkit-min-device-pixel-ratio: 0) {
@font-face {
font-family: "Flaticon";
src: url("../assets/images/Flaticon.svg#Flaticon") format("svg"); } }
.fi:before {
display: inline-block;
font-family: "Flaticon";
font-style: normal;
font-weight: normal;
font-variant: normal;
line-height: 1;
text-decoration: inherit;
text-rendering: optimizeLegibility;
text-transform: none;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-smoothing: antialiased; }
.flaticon-sad-2:before {
content: "\f100"; }
.flaticon-sad-1:before {
content: "\f101"; }
.flaticon-neutral:before {
content: "\f102"; }
.flaticon-happy-2:before {
content: "\f103"; }
.flaticon-sad:before {
content: "\f104"; }
.flaticon-happy-1:before {
content: "\f105"; }
.flaticon-happy:before {
content: "\f106"; }
html {
box-sizing: border-box; }
html {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%; }
body {
margin: 0; }
a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
text-decoration: none;
color: black; }
a:active,
a:hover {
outline-width: 0; }
img {
border-style: none; }
html,
body {
font-family: Verdana, sans-serif;
font-size: 15px;
line-height: 1.5; }
html {
overflow-x: hidden; }
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Roboto', sans-serif; }
/* Change autocomplete styles in WebKit */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus input:-webkit-autofill,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
border: 0px solid white;
-webkit-text-fill-color: black;
-webkit-box-shadow: 0 0 0px 1000px white inset;
transition: background-color 5000s ease-in-out 0s; }
.g__dialog-title {
margin: 0px;
padding: 24px 24px 20px;
color: rgba(0, 0, 0, 0.87);
font-size: 22px;
line-height: 32px;
font-weight: 400; }
.g__circle-black {
color: rgba(0, 0, 0, 0.87);
background: rgba(0, 0, 0, 0.26);
transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
box-sizing: border-box;
font-family: Roboto, sans-serif;
-webkit-tap-highlight-color: transparent;
box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px;
border-radius: 50%;
display: inline-block;
margin: 0px 8px;
height: 36px;
cursor: pointer;
width: 36px; }
.g__circle-black:hover {
transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
background: rgba(0, 0, 0, 0.42);
top: 0px; }
.g__circle {
color: rgba(0, 0, 0, 0.87);
background-color: #eeeeee;
transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
box-sizing: border-box;
font-family: Roboto, sans-serif;
-webkit-tap-highlight-color: transparent;
box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px;
border-radius: 50%;
display: inline-block;
margin: 0px 8px;
height: 36px;
cursor: pointer;
width: 36px; }
.g__circle:hover {
transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
background-color: rgba(0, 0, 0, 0.04);
top: 0px; }
.g__title, .g__title-center {
color: rgba(0, 0, 0, 0.54);
font-size: 16px;
font-weight: 500;
margin: 32px 0 0;
white-space: nowrap;
-webkit-flex-shrink: 1;
flex-shrink: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis; }
.g__title-center {
display: flex;
justify-content: center;
padding: 10px;
margin: 22px auto;
max-width: 300px; }
.g__greenColor {
color: #6d9828; }
.g__greenBox {
background-color: #6d9828 !important; }
.glob__shadow {
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.2), 0 4px 20px 0 rgba(0, 0, 0, 0.19); }
.global__color-teal {
color: #58d09f; }
.global__color-gold {
color: #FFD700; }
.global__color-lightGrey {
color: #ada7a7; }
input[type="file"] {
display: none; }
.global__hidden {
display: none; }
.global__scroll-CH::-webkit-scrollbar {
width: 5px; }
.global__scroll-CH::-webkit-scrollbar-track {
background: #ddd; }
.global__scroll-CH::-webkit-scrollbar-thumb {
background: #666; }
.global__scroll-IE {
scrollbar-base-color: #C0C0C0;
scrollbar-base-color: #C0C0C0;
scrollbar-dlight-color: #C0C0C0;
scrollbar-highlight-color: #C0C0C0;
scrollbar-track-color: #EBEBEB;
scrollbar-arrow-color: black;
scrollbar-shadow-color: #C0C0C0;
scrollbar-dark-shadow-color: #C0C0C0; }
.g-load-more {
text-align: center;
padding-top: 4px;
background-color: #ffffff59;
padding-bottom: 4px;
width: 76px;
margin: 3px auto 15px;
border-radius: 9px; }
g__input-underline::before {
display: none; }
g__input-underline::after {
display: none; }
.master__progress {
position: fixed;
top: 0;
top: 56px;
z-index: 1501;
width: 100%; }
.master__loading {
position: fixed;
top: 67px;
z-index: 1501;
width: 100%;
justify-content: center; }
.master__loading div.title {
color: white;
font-size: 11px;
text-align: center;
font-weight: 500;
white-space: nowrap;
-webkit-flex-shrink: 1;
flex-shrink: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
background-color: #db4437;
padding: 7px;
border-radius: 40px; }
.master__message {
position: fixed;
top: 5;
left: 0;
text-align: center;
z-index: 1001;
width: 100%; }
.profile__parallax {
height: 455px;
border-radius: 2px;
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14); }
.profile__title, .people__title {
color: rgba(0, 0, 0, 0.54);
font-size: 16px;
font-weight: 500;
margin: 32px 0 0;
white-space: nowrap;
-webkit-flex-shrink: 1;
flex-shrink: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis; }
.profile__head-info {
justify-content: space-between;
position: relative;
box-sizing: border-box;
height: 108px;
margin-top: -108px;
padding: 24px;
flex-direction: row;
align-items: center;
background-color: transparent;
background-image: -webkit-linear-gradient(transparent, rgba(0, 0, 0, 0.46));
background-image: linear-gradient(transparent, rgba(0, 0, 0, 0.46));
display: flex; }
.profile__head-info div.left {
display: flex;
flex-direction: row;
justify-content: space-between; }
.profile__head-info div.left div.info {
display: flex;
text-align: left;
margin-left: 24px;
flex-direction: column; }
.profile__head-info div.left div.info div.fullName {
font-size: 30px;
font-weight: 500;
color: #fff; }
.profile__head-info div.left div.info div.tagLine {
background: rgba(255, 255, 255, 0.2);
color: #eae9e9;
padding: 4px;
border-radius: 2px; }
.profile__head-info div.left div.info div.followers {
color: #fff;
margin-top: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
font-size: 14px; }
.profile__head-info div.right {
display: flex;
flex-direction: row;
justify-content: space-between; }
.profile__head-info-s, .profile__edit {
display: flex;
justify-content: space-between;
position: relative;
box-sizing: border-box;
height: 241px;
margin-top: -45px;
padding: 0 24px;
flex-direction: column;
justify-content: center;
align-items: center; }
.profile__head-info-s div.left, .profile__edit div.left {
display: flex;
flex-direction: column;
justify-content: space-between; }
.profile__head-info-s div.left div.profile__avatar, .profile__edit div.left div.profile__avatar {
display: flex;
justify-content: center; }
.profile__head-info-s div.left div.info, .profile__edit div.left div.info {
display: flex;
text-align: left;
margin-top: 24px;
flex-direction: column; }
.profile__head-info-s div.left div.info div.fullName, .profile__edit div.left div.info div.fullName {
font-size: 30px;
font-weight: 500;
color: #191818;
display: flex;
justify-content: center; }
.profile__head-info-s div.left div.info div.followers, .profile__edit div.left div.info div.followers {
color: #383838;
margin-top: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
font-size: 14px;
display: flex;
justify-content: center; }
.profile__head-info-s div.right, .profile__edit div.right {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: 24px; }
.profile__edit {
margin-top: -60px;
height: 171px; }
.sendFeedback__content {
position: fixed;
right: 5px;
bottom: 5px;
z-index: 1; }
.sendFeedback__content .paper {
width: 350px;
height: 100%;
margin: 20px;
text-align: center; }
.sendFeedback__content .main-box {
padding: 26px 26px 0px 26px; }
.sendFeedback__content .buttons {
margin-top: 20px;
margin-left: 50px;
position: relative; }
.sendFeedback__content .close {
position: absolute;
top: 13px;
right: 13px; }
.sendFeedback__content .success {
padding: 30px; }
.sendFeedback__content .error {
padding: 30px; }
.sendFeedback__content .loading {
padding: 18px 0px 0px 0px; }
.sendFeedback__content .loading .icon {
justify-content: center;
align-items: center;
align-content: center;
align-self: center; }
.user-box__add-circle {
position: absolute;
right: 16px;
bottom: 69px; }
.homeHeader__title-root {
flex: 1; }
.homeHeader__title {
border-left: 1px solid #fff;
padding-left: 24px;
margin-left: 24px;
line-height: 32px;
font-weight: 500;
font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif;
font-size: 20px;
-webkit-font-smoothing: antialiased;
color: #fff; }
.homeHeader__right {
padding-left: 30px;
padding-right: 30px;
position: relative;
margin-left: -24px;
display: flex;
justify-content: space-between;
align-items: center; }
.homeHeader__left {
padding-left: 30px;
padding-right: 30px; }
.homeHeader__notify {
color: rgba(0, 0, 0, 0.87);
background-color: #ff1717;
transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
box-sizing: border-box;
font-family: Roboto, sans-serif;
-webkit-tap-highlight-color: transparent;
border-radius: 50%;
display: inline-block;
height: 20px;
cursor: pointer;
width: 21px;
display: flex;
justify-content: center;
align-items: center; }
.homeHeader__notify div.title {
color: white;
font-size: 10px;
font-weight: 100;
white-space: nowrap;
-webkit-flex-shrink: 1;
flex-shrink: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis; }
.homeHeader__notify-menu {
background-color: #eee !important;
background: #e5e5e5 !important;
border: 1px solid #ccc !important;
color: #000 !important;
min-width: 376px !important;
width: 376px !important;
height: 380px !important;
display: block !important;
outline: none !important;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2) !important; }
.homeHeader__notify-menu div.container {
padding: 10px 0px 10px 0px;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
position: relative; }
.homeHeader__notify-menu div.container div.title {
display: flex;
justify-content: center;
color: rgba(102, 102, 102, 0.57);
font-size: 26px;
font-weight: 500;
width: 100%; }
.homeHeader__notify-menu div.container div.content {
width: 100%;
height: 100%;
padding: 10px 0px; }
.homeHeader__notify-menu div.container div.content div.item {
width: 100%;
height: 54px;
background-color: white;
margin-bottom: 10px;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
display: flex;
padding: 10px 0px 10px 0px;
flex-direction: row;
align-items: center;
position: relative; }
.homeHeader__notify-menu div.container div.content div.item div.avatar {
margin-left: 5px; }
.homeHeader__notify-menu div.container div.content div.item div.info {
margin-left: 10px;
height: 100%;
width: 100%;
overflow: hidden; }
.homeHeader__notify-menu div.container div.content div.item div.info div.user-name {
color: rgba(0, 0, 0, 0.77);
font-size: 15px;
font-weight: 500;
white-space: nowrap;
-webkit-flex-shrink: 1;
flex-shrink: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis; }
.homeHeader__notify-menu div.container div.content div.item div.info div.description {
color: rgba(0, 0, 0, 0.54);
font-size: 14px;
font-weight: 200;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; }
.homeHeader__notify-menu div.container div.content div.item div.close {
position: absolute;
right: 17px;
top: 3px;
height: 10px;
width: 10px; }
.home__main {
background-color: #eeeeee;
transition: margin-left .4s; }
@media screen and (max-width: 750px) {
.home__main {
margin-left: 0 !important;
margin-right: 0 !important; } }
.sidebar {
padding-top: 64px;
background-color: #fff;
max-width: 210px;
height: 100%;
width: 200px;
position: fixed !important;
z-index: 1;
overflow: hidden; }
.sidebar__large {
background-color: #eeeeee !important;
z-index: 1000; }
.sidebar__over {
z-index: 1102;
padding-top: 0;
background-color: #ffffff;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
z-index: 1111; }
.sidebar__title {
font-size: 20px;
font-weight: 500;
padding-right: 16px;
font-family: Roboto, sans-serif;
position: relative;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin-left: 15px; }
.blog {
margin: 0 auto;
width: 90%; }
@media (min-width: 993px) {
.blog__right-list {
margin-left: 2%; } }
.comment__list-show > div:nth-of-type(1) {
z-index: 3;
animation: commentSlideShow 12s linear 0s infinite;
position: absolute;
top: 0;
left: 0;
background-color: white;
height: 60px;
width: 100%; }
.comment__list-show > div:nth-of-type(2) {
z-index: 2;
animation: commentSlideShow 12s linear 4s infinite;
position: absolute;
top: 0;
left: 0;
background-color: white;
height: 60px;
width: 100%; }
.comment__list-show > div:nth-of-type(3) {
z-index: 1;
animation: commentSlideShow 12s linear 8s infinite;
position: absolute;
top: 0;
left: 0;
background-color: white;
height: 60px;
width: 100%; }
@keyframes commentSlideShow {
25% {
opacity: 1; }
33.33% {
opacity: 0; }
91.66% {
opacity: 0; }
100% {
opacity: 1; } }
.people__name {
display: flex;
word-break: break-word;
max-width: 100%;
align-items: center;
padding: 10px;
justify-content: center; }
.people__name div {
color: rgba(0, 0, 0, 0.87);
font-size: 16px;
line-height: 20px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-word;
overflow: hidden;
text-overflow: ellipsis;
max-height: 40px; }
.login__button-box, .signup__button-box, .settings__button-box {
display: flex;
justify-content: space-around; }
.signup__button-box {
margin-top: 30px; }
.mLoading__body {
background-color: #d8d8d8; }
.mLoading__loading {
position: fixed;
z-index: 2001;
height: 2em;
width: 2em;
overflow: show;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0; }
/* Transparent Overlay */
.mLoading__loading:before {
content: '';
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.65); }
/* :not(:required) hides these rules from IE9 and below */
.mLoading__loading:not(:required) {
/* hide "mLoading__loading..." text */
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0; }

View File

@@ -1,7 +0,0 @@
let expect = require('expect')
describe('App', () => {
it('should properly run tests', () => {
expect(1).toBe(1)
})
})

View File

@@ -1,9 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"module": "es6",
"target": "es6",
"lib": ["es7", "dom"],
"types": ["reflect-metadata"], "types": ["reflect-metadata"],
"allowSyntheticDefaultImports": true, // see below "allowSyntheticDefaultImports": true, // see below
"baseUrl": "./src/", // enables you to import relative to this folder "baseUrl": "./src/", // enables you to import relative to this folder
@@ -18,20 +15,35 @@
"layouts/*": ["layouts/*"], "layouts/*": ["layouts/*"],
"models/*": ["models/*"] "models/*": ["models/*"]
}, },
"sourceMap": true, // make TypeScript generate sourcemaps "outDir": "build/dist",
"outDir": "public", // output directory to build to (irrelevant because we use Webpack most of the time) "module": "esnext",
"jsx": "preserve", // enable JSX mode, but "preserve" tells TypeScript to not transform it (we'll use Babel) "target": "es5",
"strict": true, "lib": ["es7", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node", "moduleResolution": "node",
"experimentalDecorators": true, "rootDir": "src",
"emitDecoratorMetadata": true, "forceConsistentCasingInFileNames": true,
"allowJs": true "noImplicitReturns": false,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": false,
"experimentalDecorators": true
}, },
"include": [ "include": [
"src/**/*" "src/**/*"
], ],
"exclude": [ "exclude": [
"node_modules" "node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
] ]
} }

View File

@@ -1,3 +1,102 @@
{ {
"extends": "tslint-config-standard" "extends": ["tslint-react"],
"rules": {
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": false,
"forin": true,
"ter-indent": [
true,
2,
{
"SwitchCase": 1
}
],
"interface-name": [false, "always-prefix"],
"jsdoc-format": true,
"no-extra-boolean-cast": true,
"jsx-self-close": false,
"jsx-no-lambda": false,
"jsx-no-multiline-js": false,
"jsx-no-bind": false,
"jsx-boolean-value": false,
"jsx-alignment": false,
"label-position": true,
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-consecutive-blank-lines": true,
"no-construct": true,
"no-debugger": true,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-shadowed-variable": false,
"no-string-literal": false,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": false,
"no-unused-expression": true,
"no-use-before-declare": false,
"one-line": [
true,
"check-catch",
"check-else",
"check-open-brace",
"check-whitespace"
],
"quotemark": [true, "single", "avoid-escape", "jsx-single"],
"radix": true,
"semicolon": [true, "never"],
"switch-default": true,
"trailing-comma": [false],
"triple-equals": [ true, "allow-null-check" ],
"typedef": [
true,
"parameter",
"property-declaration"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case"],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-rest-spread",
"check-type",
"check-typecast",
"check-type-operator",
"check-preblock"
]
}
} }

View File

@@ -1,156 +0,0 @@
var webpack = require('webpack');
var path = require('path');
var envFile = require('node-env-file');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
console.log(process.env.NODE_ENV);
try {
envFile(path.join(__dirname, 'config/' + process.env.NODE_ENV + '.env'));
} catch (e) {
}
const devEntry = [
'react-hot-loader/patch',
'webpack-hot-middleware/client',
'./src/index.tsx'
];
module.exports = {
entry: (process.env.NODE_ENV === 'production') ? ['./src/index.tsx'] : devEntry,
externals: {
jquery: 'jQuery'
},
plugins: (process.env.NODE_ENV === 'production') ? [
new webpack.optimize.UglifyJsPlugin({
minimize: true,
compressor: {
warnings: false
}
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
API_KEY: JSON.stringify(process.env.API_KEY),
AUTH_DOMAIN: JSON.stringify(process.env.AUTH_DOMAIN),
DATABASE_URL: JSON.stringify(process.env.DATABASE_URL),
STORAGE_BUCKET: JSON.stringify(process.env.STORAGE_BUCKET),
PROJECT_ID: JSON.stringify(process.env.PROJECT_ID),
MESSAGING_SENDER_ID: JSON.stringify(process.env.MESSAGING_SENDER_ID),
HOST_URL: JSON.stringify(process.env.HOST_URL)
}
})
] : [
new webpack.HotModuleReplacementPlugin(),
new OpenBrowserPlugin({ url: `http://localhost:${process.env.PORT}` }),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
API_KEY: JSON.stringify(process.env.API_KEY),
AUTH_DOMAIN: JSON.stringify(process.env.AUTH_DOMAIN),
DATABASE_URL: JSON.stringify(process.env.DATABASE_URL),
STORAGE_BUCKET: JSON.stringify(process.env.STORAGE_BUCKET),
PROJECT_ID: JSON.stringify(process.env.PROJECT_ID),
MESSAGING_SENDER_ID: JSON.stringify(process.env.MESSAGING_SENDER_ID),
HOST_URL: JSON.stringify(process.env.HOST_URL),
PORT: JSON.stringify(process.env.PORT)
}
})
],
output: {
publicPath: '/',
path: path.resolve(__dirname, './public'),
filename: 'bundle-v0.5.2.js',
},
resolve: {
modules: [
__dirname,
path.resolve(__dirname, 'node_modules')
],
alias: {
src: 'src',
components: 'src/components',
reducers: 'src/reducers',
constants: 'src/constants',
core: 'src/core',
data: 'src/data',
api: 'src/api',
layouts: 'src/layouts',
routes: 'src/routes',
models: 'src/models',
store: 'src/store',
applicationStyles: 'src/styles/app.scss',
actions: 'src/actions',
actionTypes: 'src/constants/actionTypes.jsx'
},
extensions: [' ', '.scss', ".ts", ".tsx", ".js", '.jsx']
},
module: {
rules: [{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader'
},
{
loader: 'ts-loader',
options: { transpileOnly: true }
}
]
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
},
{
test: /\.js(x?)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader",
options: {
includePaths: [
]
}
}]
},
{
test: /\.css$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}]
},
{
test: /\.(woff|woff2|eot|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader'
}, {
test: /\.(jpe?g|png|webp|gif|cur)$/,
loader: 'file-loader?name=/images/[name].[ext]'
}
]
},
devtool: process.env.NODE_ENV === 'production' ? undefined : 'cheap-module-eval-source-map'
};

8124
yarn.lock Normal file

File diff suppressed because it is too large Load Diff