diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..52c0922
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,11 @@
+{
+ "plugins": [
+ "react-hot-loader/babel",
+ "transform-decorators-legacy"
+ ],
+ "presets": [
+ "babel-polyfill", ["env", { "modules": false }],
+ "react",
+ "stage-0"
+ ]
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index df32d83..fd8d01d 100644
--- a/package.json
+++ b/package.json
@@ -1,106 +1,109 @@
{
- "name": "react-social",
- "version": "1.0.0",
- "description": "Simple react socail app",
- "main": "index.js",
- "scripts": {
- "test": "NODE_ENV=test karma start",
- "build": "NODE_ENV=production webpack -p",
- "watch": "webpack -w",
- "deploy:firebase": "npm run build && firebase deploy",
- "start": "npm run build && node server.js"
- },
- "author": "Amir Movahedi",
- "license": "MIT",
- "dependencies": {
- "amazon-cognito-identity-js": "^1.21.0",
- "aws-sdk": "^2.132.0",
- "axios": "^0.16.1",
- "classnames": "^2.2.5",
- "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",
- "file-loader": "^0.11.1",
- "firebase": "^3.9.0",
- "inversify": "^4.3.0",
- "keycode": "^2.1.9",
- "lodash": "^4.17.4",
- "material-ui": "^0.19.4",
- "moment": "^2.18.1",
- "morgan": "^1.8.1",
- "node-env-file": "^0.1.8",
- "node-sass": "^4.5.2",
- "prop-types": "^15.6.0",
- "react": "^16.0.0",
- "react-addons-test-utils": "^15.6.2",
- "react-avatar-editor": "^10.3.0",
- "react-dom": "^16.0.0",
- "react-event-listener": "^0.5.1",
- "react-linkify": "^0.2.1",
- "react-parallax": "^1.4.4",
- "react-redux": "^5.0.6",
- "react-router": "^4.1.1 ",
- "react-router-dom": "^4.1.1",
- "react-router-redux": "^5.0.0-alpha.6",
- "react-string-replace": "^0.4.0",
- "react-tap-event-plugin": "^3.0.2",
- "redux": "^3.7.2",
- "redux-actions": "^2.0.3",
- "redux-thunk": "^2.2.0",
- "reflect-metadata": "^0.1.10",
- "sass-loader": "^6.0.3",
- "save": "^2.3.0",
- "script-loader": "^0.7.0",
- "style-loader": "^0.16.1",
- "url-loader": "^0.5.8",
- "uuid": "^3.0.1"
- },
- "devDependencies": {
- "@types/lodash": "^4.14.77",
- "@types/material-ui": "^0.18.2",
- "@types/node": "^8.0.33",
- "@types/prop-types": "^15.5.2",
- "@types/react": "^16.0.10",
- "@types/react-dom": "^16.0.1",
- "@types/react-event-listener": "^0.4.4",
- "@types/react-redux": "^5.0.10",
- "@types/react-router-dom": "^4.0.8",
- "@types/react-router-redux": "^5.0.8",
- "@types/react-tap-event-plugin": "0.0.30",
- "@types/redux-logger": "^3.0.4",
- "@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-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",
- "redux-logger": "^3.0.1",
- "redux-mock-store": "^1.2.3",
- "source-map-loader": "^0.2.2",
- "ts-loader": "^2.3.7",
- "ts-node": "^3.3.0",
- "tslint": "^5.7.0",
- "tslint-config-standard": "^6.0.1",
- "typescript": "^2.5.3",
- "webpack": "^3.6.0"
- },
- "engines": {
- "node": "7.3.0",
- "npm": "3.10.10"
- }
-}
\ No newline at end of file
+ "name": "react-social",
+ "version": "1.0.0",
+ "description": "Simple react socail app",
+ "main": "index.js",
+ "scripts": {
+ "test": "NODE_ENV=test karma start",
+ "build": "NODE_ENV=production webpack -p",
+ "watch": "webpack -w",
+ "deploy:firebase": "npm run build && firebase deploy",
+ "start": "npm run build && node server.js"
+ },
+ "author": "Amir Movahedi",
+ "license": "MIT",
+ "dependencies": {
+ "@types/react-hot-loader": "^3.0.5",
+ "amazon-cognito-identity-js": "^1.21.0",
+ "aws-sdk": "^2.132.0",
+ "axios": "^0.16.1",
+ "classnames": "^2.2.5",
+ "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",
+ "file-loader": "^0.11.1",
+ "firebase": "^3.9.0",
+ "inversify": "^4.3.0",
+ "keycode": "^2.1.9",
+ "lodash": "^4.17.4",
+ "material-ui": "^0.19.4",
+ "moment": "^2.18.1",
+ "morgan": "^1.8.1",
+ "node-env-file": "^0.1.8",
+ "node-sass": "^4.5.2",
+ "prop-types": "^15.6.0",
+ "react": "^16.0.0",
+ "react-addons-test-utils": "^15.6.2",
+ "react-avatar-editor": "^10.3.0",
+ "react-dom": "^16.0.0",
+ "react-event-listener": "^0.5.1",
+ "react-hot-loader": "^3.1.3",
+ "react-linkify": "^0.2.1",
+ "react-parallax": "^1.4.4",
+ "react-redux": "^5.0.6",
+ "react-router": "^4.1.1 ",
+ "react-router-dom": "^4.1.1",
+ "react-router-redux": "^5.0.0-alpha.6",
+ "react-string-replace": "^0.4.0",
+ "react-tap-event-plugin": "^3.0.2",
+ "redux": "^3.7.2",
+ "redux-actions": "^2.0.3",
+ "redux-thunk": "^2.2.0",
+ "reflect-metadata": "^0.1.10",
+ "sass-loader": "^6.0.3",
+ "save": "^2.3.0",
+ "script-loader": "^0.7.0",
+ "style-loader": "^0.16.1",
+ "url-loader": "^0.5.8",
+ "uuid": "^3.0.1"
+ },
+ "devDependencies": {
+ "@types/lodash": "^4.14.77",
+ "@types/material-ui": "^0.18.2",
+ "@types/node": "^8.0.33",
+ "@types/prop-types": "^15.5.2",
+ "@types/react": "^16.0.10",
+ "@types/react-dom": "^16.0.1",
+ "@types/react-event-listener": "^0.4.4",
+ "@types/react-redux": "^5.0.10",
+ "@types/react-router-dom": "^4.0.8",
+ "@types/react-router-redux": "^5.0.8",
+ "@types/react-tap-event-plugin": "0.0.30",
+ "@types/redux-logger": "^3.0.4",
+ "@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-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",
+ "redux-logger": "^3.0.1",
+ "redux-mock-store": "^1.2.3",
+ "source-map-loader": "^0.2.2",
+ "ts-loader": "^2.3.7",
+ "ts-node": "^3.3.0",
+ "tslint": "^5.7.0",
+ "tslint-config-standard": "^6.0.1",
+ "typescript": "^2.5.3",
+ "webpack": "^3.6.0",
+ "webpack-hot-middleware": "^2.20.0"
+ },
+ "engines": {
+ "node": "7.3.0",
+ "npm": "3.10.10"
+ }
+}
diff --git a/server.js b/server.js
index 9e4f69f..889b625 100644
--- a/server.js
+++ b/server.js
@@ -1,6 +1,9 @@
var express = require('express');
var morgan = require('morgan');
var path = require('path');
+var webpack = require('webpack');
+var webpackConfig = require('./webpack.config');
+var compiler = webpack(webpackConfig);
// Create our app
var app = express();
@@ -10,18 +13,25 @@ const PORT = process.env.PORT || 3000;
app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms'));
-app.use(function (req, res, next){
- if (req.headers['x-forwarded-proto'] === 'https') {
- res.redirect('http://' + req.hostname + req.url);
- } else {
- next();
- }
+app.use(require("webpack-dev-middleware")(compiler, {
+ noInfo: true,
+ publicPath: webpackConfig.output.publicPath
+}));
+
+app.use(require("webpack-hot-middleware")(compiler));
+
+app.use(function(req, res, next) {
+ if (req.headers['x-forwarded-proto'] === 'https') {
+ res.redirect('http://' + req.hostname + req.url);
+ } else {
+ next();
+ }
});
app.use(function(req, res, next) {
- var userAgent = req.get('User-Agent');
- console.log(userAgent);
- next();
+ var userAgent = req.get('User-Agent');
+ console.log(userAgent);
+ next();
});
app.use(express.static('public'));
@@ -29,11 +39,11 @@ app.use(express.static('public'));
// Always return the main index.html, so react-router render the route in the client
app.get('*', (req, res) => {
- res.sendFile(path.resolve('public', 'index.html'));
+ res.sendFile(path.resolve('public', 'index.html'));
});
-app.listen(PORT, function () {
- console.log('Express server is up on port ' + PORT);
-});
+app.listen(PORT, function() {
+ console.log('Express server is up on port ' + PORT);
+});
\ No newline at end of file
diff --git a/src/actions/authorizeActions.ts b/src/actions/authorizeActions.ts
index 8f4b668..da52c7d 100644
--- a/src/actions/authorizeActions.ts
+++ b/src/actions/authorizeActions.ts
@@ -6,6 +6,7 @@ import { push } from 'react-router-redux'
// -Import domain
import { User } from 'core/domain/users'
import { SocialError } from 'core/domain/common'
+import { OAuthType, LoginUser } from 'core/domain/authorize'
import { UserRegisterModel } from 'models/users/userRegisterModel'
@@ -150,6 +151,27 @@ export const dbSendEmailVerfication = () => {
}
}
+ /**
+ * Login user with OAuth
+ */
+export const dbLoginWithOAuth = (type: OAuthType) => {
+ return (dispatch: any, getState: any) => {
+ dispatch(globalActions.showNotificationRequest())
+
+ return authorizeService.loginWithOAuth(type).then((result: LoginUser) => {
+ // Send email verification successful.
+ dispatch(globalActions.showNotificationSuccess())
+ dispatch(login(result.uid, true))
+ dispatch(push('/'))
+ })
+ .catch((error: SocialError) => {
+ // An error happened.
+ dispatch(globalActions.showErrorMessage(error.code))
+
+ })
+ }
+}
+
/* _____________ CRUD State _____________ */
/**
diff --git a/src/components/emailVerification/EmailVerificationComponent.tsx b/src/components/emailVerification/EmailVerificationComponent.tsx
index 9028e79..e66c3fe 100644
--- a/src/components/emailVerification/EmailVerificationComponent.tsx
+++ b/src/components/emailVerification/EmailVerificationComponent.tsx
@@ -27,9 +27,13 @@ export class EmailVerificationComponent extends Component
An verificiation email has been already sent to you. Please check your inbox. If you couldn't see the emai, please resend email verification.
-
+
+ this.props.homePage()} />
this.props.sendEmailVerification()} />
+
+
@@ -109,8 +116,8 @@ export class EmailVerificationComponent extends Component {
return {
- loginPage: () => {
- dispatch(push('/login'))
+ homePage: () => {
+ dispatch(push('/'))
},
sendEmailVerification: () => dispatch(authorizeActions.dbSendEmailVerfication())
}
diff --git a/src/components/emailVerification/IEmailVerificationComponentProps.ts b/src/components/emailVerification/IEmailVerificationComponentProps.ts
index f121efc..ece6338 100644
--- a/src/components/emailVerification/IEmailVerificationComponentProps.ts
+++ b/src/components/emailVerification/IEmailVerificationComponentProps.ts
@@ -1,4 +1,5 @@
export interface IEmailVerificationComponentProps {
sendEmailVerification: () => any
+ homePage: () => any
}
diff --git a/src/components/home/HomeComponent.tsx b/src/components/home/HomeComponent.tsx
index 305d00d..4dda80e 100644
--- a/src/components/home/HomeComponent.tsx
+++ b/src/components/home/HomeComponent.tsx
@@ -111,7 +111,8 @@ export class HomeComponent extends Component any
+ /**
+ * Login user with OAuth
+ *
+ * @memberof ILoginComponentProps
+ */
+ loginWithOAuth: (type: OAuthType) => any
+
/**
* Redirect to signup page
*
diff --git a/src/components/login/LoginComponent.tsx b/src/components/login/LoginComponent.tsx
index 7a53ba9..1177408 100644
--- a/src/components/login/LoginComponent.tsx
+++ b/src/components/login/LoginComponent.tsx
@@ -15,6 +15,8 @@ import ActionAndroid from 'material-ui/svg-icons/action/android'
import * as authorizeActions from 'actions/authorizeActions'
import { ILoginComponentProps } from './ILoginComponentProps'
import { ILoginComponentState } from './ILoginComponentState'
+import { firebaseAuth } from 'data/firebaseClient'
+import { OAuthType } from 'core/domain/authorize'
// - Create Login component class
export class LoginComponent extends Component {
@@ -130,6 +132,8 @@ export class LoginComponent extends Component
@@ -163,12 +167,16 @@ export class LoginComponent extends Component
}
- />
+ onClick={() => loginWithOAuth(OAuthType.FACEBOOK)}
+ />
}
- />
+ onClick={() => loginWithOAuth(OAuthType.GOOGLE)}
+ />
}
+ onClick={() => loginWithOAuth(OAuthType.GITHUB)}
+
/>
@@ -221,6 +229,7 @@ const mapDispatchToProps = (dispatch: any, ownProps: ILoginComponentProps) => {
login: (email: string, password: string) => {
dispatch(authorizeActions.dbLogin(email, password))
},
+ loginWithOAuth: (type: OAuthType) => dispatch(authorizeActions.dbLoginWithOAuth(type)),
signupPage: () => {
dispatch(push('/signup'))
}
diff --git a/src/components/master/MasterComponent.tsx b/src/components/master/MasterComponent.tsx
index 57ac15b..d852f7c 100644
--- a/src/components/master/MasterComponent.tsx
+++ b/src/components/master/MasterComponent.tsx
@@ -77,7 +77,6 @@ export class MasterComponent extends Component Promise
+
+ /**
+ * Login user by OAuth authentication
+ *
+ * @memberof IAuthorizeService
+ */
+ loginWithOAuth: (type: OAuthType) => Promise
}
diff --git a/src/data/firebaseClient/services/authorize/AuthorizeService.ts b/src/data/firebaseClient/services/authorize/AuthorizeService.ts
index b97d011..6668a5a 100644
--- a/src/data/firebaseClient/services/authorize/AuthorizeService.ts
+++ b/src/data/firebaseClient/services/authorize/AuthorizeService.ts
@@ -1,11 +1,13 @@
+
// - Import react components
import { firebaseRef, firebaseAuth } from 'data/firebaseClient'
import { IAuthorizeService } from 'core/services/authorize'
-import { User } from 'core/domain/users'
+import { User, UserProvider } from 'core/domain/users'
import { LoginUser, RegisterUserResult } from 'core/domain/authorize'
import { SocialError } from 'core/domain/common'
+import { OAuthType } from 'core/domain/authorize/oauthType'
/**
* Firbase authorize service
*
@@ -66,15 +68,8 @@ export class AuthorizeService implements IAuthorizeService {
firebaseAuth()
.createUserWithEmailAndPassword(user.email as string, user.password as string)
.then((signupResult) => {
- firebaseRef.child(`users/${signupResult.uid}/info`)
- .set({
- ...user,
- avatar: 'noImage'
- })
- .then((result) => {
- resolve(new RegisterUserResult(signupResult.uid))
- })
- .catch((error: any) => reject(new SocialError(error.name, error.message)))
+ const {uid, email, displayName, photoURL} = signupResult
+ this.storeUserInformation(uid,email,displayName,photoURL).then(resolve)
})
.catch((error: any) => reject(new SocialError(error.code, error.message)))
})
@@ -140,6 +135,11 @@ export class AuthorizeService implements IAuthorizeService {
})
}
+ /**
+ * Send verfication email to user email
+ *
+ * @memberof AuthorizeService
+ */
public sendEmailVerification: () => Promise = () => {
return new Promise((resolve,reject) => {
let auth = firebaseAuth()
@@ -153,9 +153,109 @@ export class AuthorizeService implements IAuthorizeService {
reject(new SocialError(error.code, error.message))
})
} else {
- reject(new SocialError('nullException', 'User was null'));
+ reject(new SocialError('authorizeService/nullException', 'User was null!'))
}
})
}
+
+ public loginWithOAuth: (type: OAuthType) => Promise = (type) => {
+ return new Promise((resolve,reject) => {
+
+ let provider: any
+
+ switch (type) {
+ case OAuthType.GITHUB:
+ provider = new firebaseAuth.GithubAuthProvider()
+ break
+ case OAuthType.FACEBOOK:
+ provider = new firebaseAuth.FacebookAuthProvider()
+ break
+ case OAuthType.GOOGLE:
+ provider = new firebaseAuth.GoogleAuthProvider()
+ break
+ default:
+ throw new SocialError('authorizeService/loginWithOAuth','None of OAuth type is matched!')
+ }
+ firebaseAuth().signInWithPopup(provider).then((result) => {
+ // This gives you a GitHub Access Token. You can use it to access the GitHub API.
+ let token = result.credential.accessToken
+ // The signed-in user info.
+ const {user} = result
+ const {credential} = result
+ const {uid, displayName, email, photoURL} = user
+ const {accessToken, provider, providerId} = credential
+
+ this.storeUserProviderData(uid,email,displayName,photoURL,providerId,provider,accessToken)
+ // this.storeUserInformation(uid,email,displayName,photoURL).then(resolve)
+ resolve(new LoginUser(user.uid,true,providerId,displayName,email,photoURL))
+
+ }).catch(function (error: any) {
+ // Handle Errors here.
+ let errorCode = error.code
+ let errorMessage = error.message
+ // The email of the user's account used.
+ let email = error.email
+ // The firebase.auth.AuthCredential type that was used.
+ let credential = error.credential
+
+ })
+
+ })
+ }
+
+ /**
+ * Store user information
+ *
+ * @private
+ * @memberof AuthorizeService
+ */
+ private storeUserInformation = (userId: string, email: string, fullName: string, avatar?: string) => {
+ return new Promise((resolve,reject) => {
+ firebaseRef.child(`users/${userId}/info`)
+ .set({
+ userId,
+ avatar,
+ email,
+ fullName
+ })
+ .then((result) => {
+ resolve(new RegisterUserResult(userId))
+ })
+ .catch((error: any) => reject(new SocialError(error.name, error.message)))
+ })
+ }
+
+ /**
+ * Store user provider information
+ *
+ * @private
+ * @memberof AuthorizeService
+ */
+ private storeUserProviderData = (
+ userId: string,
+ email: string,
+ fullName: string,
+ avatar: string,
+ providerId: string,
+ provider: string,
+ accessToken: string
+ ) => {
+ return new Promise((resolve,reject) => {
+ firebaseRef.child(`users/${userId}/providerInfo`)
+ .set(new UserProvider(
+ userId,
+ email,
+ fullName,
+ avatar,
+ providerId,
+ provider,
+ accessToken
+ ))
+ .then((result) => {
+ resolve(new RegisterUserResult(userId))
+ })
+ .catch((error: any) => reject(new SocialError(error.name, error.message)))
+ })
+ }
}
diff --git a/src/data/firebaseClient/services/users/UserService.ts b/src/data/firebaseClient/services/users/UserService.ts
index 6a84df4..e689269 100644
--- a/src/data/firebaseClient/services/users/UserService.ts
+++ b/src/data/firebaseClient/services/users/UserService.ts
@@ -2,7 +2,7 @@
import { firebaseRef, firebaseAuth } from 'data/firebaseClient'
import { SocialError } from 'core/domain/common'
-import { Profile } from 'core/domain/users'
+import { Profile, UserProvider } from 'core/domain/users'
import { IUserService } from 'core/services/users'
/**
@@ -15,41 +15,51 @@ import { IUserService } from 'core/services/users'
export class UserService implements IUserService {
public getUserProfile: (userId: string)
=> Promise = (userId) => {
- return new Promise((resolve,reject) => {
+ return new Promise((resolve, reject) => {
let userProfileRef: any = firebaseRef.child(`users/${userId}/info`)
userProfileRef.once('value').then((snapshot: any) => {
let userProfile: Profile = snapshot.val() || {}
- resolve(userProfile)
- })
- .catch((error: any) => {
- reject(new SocialError(error.code,error.message))
+ if (Object.keys(userProfile).length === 0 && userProfile.constructor === Object) {
+ this.getUserProviderData(userId).then((providerData: UserProvider) => {
+ const {avatar,fullName, email} = providerData
+ const userProfile = new Profile(avatar,fullName,'','',email)
+ resolve(userProfile)
+ this.updateUserProfile(userId,userProfile)
+ })
+ } else {
+ resolve(userProfile)
+ }
+
})
+ .catch((error: any) => {
+ reject(new SocialError(error.code, error.message))
+ })
})
}
public updateUserProfile: (userId: string, profile: Profile)
- => Promise = (userId, profile) => {
- return new Promise((resolve,reject) => {
- let updates: any = {}
+ => Promise = (userId, profile) => {
+ return new Promise((resolve, reject) => {
+ let updates: any = {}
- updates[`users/${userId}/info`] = profile
- firebaseRef.update(updates).then(() => {
- resolve()
- })
- .catch((error: any) => {
- reject(new SocialError(error.code,error.message))
+ updates[`users/${userId}/info`] = profile
+ firebaseRef.update(updates).then(() => {
+ resolve()
+ })
+ .catch((error: any) => {
+ reject(new SocialError(error.code, error.message))
+ })
})
- })
- }
+ }
public getUsersProfile: (userId: string)
=> Promise<{ [userId: string]: Profile }> = (userId) => {
- return new Promise<{ [userId: string]: Profile }>((resolve,reject) => {
+ return new Promise<{ [userId: string]: Profile }>((resolve, reject) => {
let usersProfileRef: any = firebaseRef.child(`users`)
usersProfileRef.once('value').then((snapshot: any) => {
let usersProfile: any = snapshot.val() || {}
- let parsedusersProfile: {[userId: string]: Profile} = {}
+ let parsedusersProfile: { [userId: string]: Profile } = {}
Object.keys(usersProfile).forEach((userKey) => {
if (userId !== userKey) {
let userInfo = usersProfile[userKey].info
@@ -64,10 +74,28 @@ export class UserService implements IUserService {
})
resolve(parsedusersProfile)
})
- .catch((error: any) => {
- reject(new SocialError(error.code,error.message))
- })
+ .catch((error: any) => {
+ reject(new SocialError(error.code, error.message))
+ })
})
}
+ private getUserProviderData = (userId: string) => {
+ return new Promise((resolve,reject) => {
+ let userProviderRef: any = firebaseRef.child(`users/${userId}/providerInfo`)
+ userProviderRef.once('value').then((snapshot: any) => {
+ let userProviderRef: any = firebaseRef.child(`users/${userId}/info`)
+ let userProvider: UserProvider = snapshot.val() || {}
+ console.log('----------------userProfile')
+ console.log(userProvider)
+ console.log('-----------------------')
+ resolve(userProvider)
+ })
+ .catch((error: any) => {
+ reject(new SocialError(error.code, error.message))
+ })
+ })
+
+ }
+
}
diff --git a/src/index.tsx b/src/index.tsx
index 0493303..4f29fea 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,6 +1,7 @@
// Import external components refrence
import React from 'react'
import ReactDOM from 'react-dom'
+import { AppContainer } from 'react-hot-loader'
import injectTapEventPlugin from 'react-tap-event-plugin'
import { cyan500 } from 'material-ui/styles/colors'
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'
@@ -20,7 +21,7 @@ import Master from 'components/master'
// Set default data
// tslint:disable-next-line:no-empty
-store.subscribe(() => {})
+store.subscribe(() => { })
// Needed for onTouchTap
// http://stackoverflow.com/a/34015469/988941
@@ -37,14 +38,35 @@ const muiTheme = getMuiTheme({
import 'applicationStyles'
const supportsHistory = 'pushState' in window.history
-ReactDOM.render(
-
-
-
-
- {/* */}
-
-
- ,
- document.getElementById('app')
-)
+// ReactDOM.render(
+//
+//
+//
+//
+//
+//
+// ,
+// document.getElementById('app')
+// )
+const render = (Component: any) => {
+ ReactDOM.render(
+
+
+
+
+
+
+
+
+
+ ,
+ document.getElementById('app')
+ )
+}
+
+render(Master)
+
+// Webpack Hot Module Replacement API
+if (module.hot) {
+ module.hot.accept('components/master', () => { render(Master) })
+}
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index 9c3e027..cb95361 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -11,14 +11,10 @@ try {
} catch (e) {
}
-
-var babelOptions = {
- plugins: ['transform-decorators-legacy'],
- presets: ['babel-polyfill', 'react', 'env', 'stage-0']
-};
-
module.exports = {
entry: [
+ 'react-hot-loader/patch',
+ 'webpack-hot-middleware/client',
'./src/index.tsx'
],
externals: {
@@ -44,6 +40,7 @@ module.exports = {
}
})
] : [
+ new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
@@ -58,6 +55,7 @@ module.exports = {
})
],
output: {
+ publicPath: '/',
path: path.resolve(__dirname, './public'),
filename: 'bundle-v0.1.js',
@@ -91,8 +89,7 @@ module.exports = {
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [{
- loader: 'babel-loader',
- options: babelOptions
+ loader: 'babel-loader'
},
{
loader: 'ts-loader',
@@ -109,8 +106,7 @@ module.exports = {
test: /\.js(x?)$/,
exclude: /(node_modules|bower_components)/,
use: {
- loader: 'babel-loader',
- options: babelOptions
+ loader: 'babel-loader'
}
},
{