119
README.md
119
README.md
@@ -6,12 +6,13 @@
|
|||||||
</p>
|
</p>
|
||||||
<!-- Name -->
|
<!-- Name -->
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
<a href="https://github.com/Qolzam/react-social-network">React Social Network</a>
|
<a href="https://github.com/Qolzam/react-social-network">React Social Network </a>:rocket:<span style="font-variant-caps: petite-caps;font-size: 30px;font-weight: 100;"> Version NEXT! </span>:rocket:
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
[](https://gitter.im/react-social-network/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/react-social-network/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
The React Social Network is an open source project relying on [React](https://facebook.github.io/react/docs/hello-world.html) a powerful javascript library for building the user interface. In this project, I tried to show some features of react/react components as a social network.
|
The React Social Network is an open source project relying on [React](https://facebook.github.io/react/docs/hello-world.html) a powerful javascript library for building the user interface. In this project, I tried to show some features of react/react components as a social network.
|
||||||
|
The structure of this project give the ability to devoloper to develop their project on thier own idea and environment.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="http://greensocial.herokuapp.com/">
|
<a href="http://greensocial.herokuapp.com/">
|
||||||
@@ -27,9 +28,9 @@ For those who prefer writing code by typescript, now React Social Network suppor
|
|||||||
This project adheres to the Contributor Covenant [code of conduct](https://github.com/Qolzam/react-social-network/blob/master/CODE_OF_CONDUCT.md).
|
This project adheres to the Contributor Covenant [code of conduct](https://github.com/Qolzam/react-social-network/blob/master/CODE_OF_CONDUCT.md).
|
||||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to amir.gholzam@live.com.
|
By participating, you are expected to uphold this code. Please report unacceptable behavior to amir.gholzam@live.com.
|
||||||
|
|
||||||
## DEMO
|
## Example
|
||||||
|
|
||||||
[Green Open Social](http://greensocial.herokuapp.com)
|
[Love Open Social](https://love-social.firebaseapp.com)
|
||||||
|
|
||||||
## Required Knowledge
|
## Required Knowledge
|
||||||
|
|
||||||
@@ -39,44 +40,37 @@ I recommend that you get to know React before using React Social Network. React
|
|||||||
|
|
||||||
## Document
|
## Document
|
||||||
|
|
||||||
Use [Documentation](https://qolzam.gitbooks.io/react-social-network/) to find out more details about this project.
|
Comming soon :) ...
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
* [TypeScript](https://www.typescriptlang.org/) TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
|
|
||||||
* [React](https://facebook.github.io/react/docs/hello-world.html) A javascript library for building user interfaces.
|
|
||||||
* [Redux](http://redux.js.org/) is a predictable state container for JavaScript apps.
|
|
||||||
* [Material-UI](http://www.material-ui.com/#/) A Set of React Components that Implement Google's Material Design.
|
|
||||||
* [react-redux](https://github.com/reactjs/react-redux) Official React bindings for Redux.
|
|
||||||
* [Firebase](https://firebase.google.com/) products like Analytics, Realtime Database, Messaging, and Crash Reporting let you move quickly and focus on your users.
|
|
||||||
* [redux-thunk](https://github.com/gaearon/redux-thunk) Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.
|
|
||||||
* [Express](https://expressjs.com/) Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
|
|
||||||
* [React Router V4](https://github.com/ReactTraining/react-router) for routing website location
|
|
||||||
* [Sass](http://sass-lang.com/) CSS with superpowers. Sass boasts more features and abilities than any other CSS extension language out there.
|
|
||||||
* [Webpack](https://webpack.js.org/) for bundling code
|
|
||||||
|
|
||||||
## In my todo list
|
|
||||||
|
|
||||||
* Documentation
|
|
||||||
* Testing
|
|
||||||
* Security issues
|
|
||||||
* Performance
|
|
||||||
* Add some features and solving bugs
|
|
||||||
* Sharing post in social itself and other socials
|
|
||||||
* Add link feature to post
|
|
||||||
* Add vido post
|
|
||||||
* Add image gallery post
|
|
||||||
* Search post and people
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# Prerequisites
|
## Road map
|
||||||
|
1. Support Firebase/Firestore -> on developing
|
||||||
|
2. Support AWS -> on developing
|
||||||
|
3. Support Azure
|
||||||
|
4. Support ASP.NET -> on developing
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
Install [NodeJs](https://nodejs.org/en/)
|
Install [NodeJs](https://nodejs.org/en/)
|
||||||
|
|
||||||
|
#### Note
|
||||||
|
|
||||||
# Installing
|
- If you're using Windows you should install all node-gyp dependencies with following commands:
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=E12PNKKjzqA)
|
`$ npm install --global --production windows-build-tools`
|
||||||
|
and then install the package
|
||||||
|
|
||||||
|
`$ npm install --global node-gyp`
|
||||||
|
|
||||||
|
|
||||||
|
### Installing
|
||||||
|
|
||||||
|
## Install back-end server/serverless
|
||||||
|
Comming soon :) ...
|
||||||
|
|
||||||
1. Fork the [react-social-network](https://github.com/Qolzam/react-social-network) repository on Github
|
1. Fork the [react-social-network](https://github.com/Qolzam/react-social-network) repository on Github
|
||||||
2. Clone your fork to your local machine `git clone git@github.com:<yourname>/react-social-network.git`
|
2. Clone your fork to your local machine `git clone git@github.com:<yourname>/react-social-network.git`
|
||||||
@@ -101,31 +95,56 @@ I recommend that you get to know React before using React Social Network. React
|
|||||||
|
|
||||||
5. Installing all nodejs modules:
|
5. Installing all nodejs modules:
|
||||||
`npm install`
|
`npm install`
|
||||||
6. Rub webpack to build bundle file
|
6. Go ahead ;)
|
||||||
`webpack`
|
`npm start`
|
||||||
5. Running server:
|
|
||||||
`node server.js`
|
|
||||||
|
|
||||||
# Warning
|
|
||||||
|
|
||||||
- If you're using Windows you should install all node-gyp dependencies with following commands:
|
|
||||||
|
|
||||||
`$ npm install --global --production windows-build-tools`
|
|
||||||
and then install the package
|
|
||||||
|
|
||||||
`$ npm install --global node-gyp`
|
## Deployment
|
||||||
|
Follow [firebase instruction](https://firebase.google.com/docs/hosting/deploying)
|
||||||
|
`firebase deploy`
|
||||||
|
|
||||||
## Contribute
|
## Built With
|
||||||
|
|
||||||
[React Social Network](http://greensocial.herokuapp.com/) has been made by love. I planed to build a back-end for this project and improve the performance as I process all procedures on the front-end side. If you'd like to help,
|
* [TypeScript](https://www.typescriptlang.org/) TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
|
||||||
|
* [JSX/TSX](https://jsx.github.io/) This project support both *.jsx and *.tsx files. JSX is a statically-typed, object-oriented programming language designed to run on modern web browsers. Being developed at DeNA as a research project, the language has following characteristics.
|
||||||
|
* [React](https://facebook.github.io/react/docs/hello-world.html) A javascript library for building user interfaces.
|
||||||
|
* [Redux](http://redux.js.org/) is a predictable state container for JavaScript apps.
|
||||||
|
* [Material-UI](http://www.material-ui.com/#/) A Set of React Components that Implement Google's Material Design.
|
||||||
|
* [react-redux](https://github.com/reactjs/react-redux) Official React bindings for Redux.
|
||||||
|
* [Firebase](https://firebase.google.com/) products like Analytics, Realtime Database, Messaging, and Crash Reporting let you move quickly and focus on your users.
|
||||||
|
* [redux-thunk](https://github.com/gaearon/redux-thunk) Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.
|
||||||
|
* [Express](https://expressjs.com/) Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
|
||||||
|
* [React Router V4](https://github.com/ReactTraining/react-router) for routing website location
|
||||||
|
* [Sass](http://sass-lang.com/) CSS with superpowers. Sass boasts more features and abilities than any other CSS extension language out there.
|
||||||
|
* [Webpack](https://webpack.js.org/) for bundling code
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
[React Social Network](https://love-social.firebaseapp.com) has been made by love. I planed to build a back-end for this project and improve the performance as I process all procedures on the front-end side. If you'd like to help,
|
||||||
check out the [document](https://qolzam.gitbooks.io/react-social-network/).
|
check out the [document](https://qolzam.gitbooks.io/react-social-network/).
|
||||||
I'd greatly appreciate any [contribution](https://github.com/Qolzam/react-social-network/blob/master/CONTRIBUTING.md)
|
I'd greatly appreciate any [contribution](https://github.com/Qolzam/react-social-network/blob/master/CONTRIBUTING.md)
|
||||||
you make. :)
|
|
||||||
|
|
||||||
# Authors
|
## Versioning
|
||||||
|
|
||||||
|
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/Qolzam/react-social-network/tags).
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
- Amir Movahedi
|
- Amir Movahedi
|
||||||
|
- See also the list of [contributors](https://github.com/Qolzam/react-social-network/contributors) who participated in this project.
|
||||||
|
|
||||||
# License
|
## License
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the [LICENSE](https://github.com/Qolzam/react-social-network/blob/master/LICENSE) file for details
|
This project is licensed under the MIT License - see the [LICENSE](https://github.com/Qolzam/react-social-network/blob/master/LICENSE) file for details
|
||||||
|
|
||||||
|
|
||||||
|
## Acknowledgments
|
||||||
|
|
||||||
|
* React
|
||||||
|
* Firebase
|
||||||
|
* JavaScript
|
||||||
|
* TypeScript
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
119
docs/README.md
119
docs/README.md
@@ -6,12 +6,13 @@
|
|||||||
</p>
|
</p>
|
||||||
<!-- Name -->
|
<!-- Name -->
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
<a href="https://github.com/Qolzam/react-social-network">React Social Network</a>
|
<a href="https://github.com/Qolzam/react-social-network">React Social Network </a>:rocket:<span style="font-variant-caps: petite-caps;font-size: 30px;font-weight: 100;"> Version NEXT! </span>:rocket:
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
[](https://gitter.im/react-social-network/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/react-social-network/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
The React Social Network is an open source project relying on [React](https://facebook.github.io/react/docs/hello-world.html) a powerful javascript library for building the user interface. In this project, I tried to show some features of react/react components as a social network.
|
The React Social Network is an open source project relying on [React](https://facebook.github.io/react/docs/hello-world.html) a powerful javascript library for building the user interface. In this project, I tried to show some features of react/react components as a social network.
|
||||||
|
The structure of this project give the ability to devoloper to develop their project on thier own idea and environment.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="http://greensocial.herokuapp.com/">
|
<a href="http://greensocial.herokuapp.com/">
|
||||||
@@ -27,9 +28,9 @@ For those who prefer writing code by typescript, now React Social Network suppor
|
|||||||
This project adheres to the Contributor Covenant [code of conduct](https://github.com/Qolzam/react-social-network/blob/master/CODE_OF_CONDUCT.md).
|
This project adheres to the Contributor Covenant [code of conduct](https://github.com/Qolzam/react-social-network/blob/master/CODE_OF_CONDUCT.md).
|
||||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to amir.gholzam@live.com.
|
By participating, you are expected to uphold this code. Please report unacceptable behavior to amir.gholzam@live.com.
|
||||||
|
|
||||||
## DEMO
|
## Example
|
||||||
|
|
||||||
[Green Open Social](http://greensocial.herokuapp.com)
|
[Love Open Social](https://love-social.firebaseapp.com)
|
||||||
|
|
||||||
## Required Knowledge
|
## Required Knowledge
|
||||||
|
|
||||||
@@ -39,44 +40,37 @@ I recommend that you get to know React before using React Social Network. React
|
|||||||
|
|
||||||
## Document
|
## Document
|
||||||
|
|
||||||
Use [Documentation](https://qolzam.gitbooks.io/react-social-network/) to find out more details about this project.
|
Comming soon :) ...
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
* [TypeScript](https://www.typescriptlang.org/) TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
|
|
||||||
* [React](https://facebook.github.io/react/docs/hello-world.html) A javascript library for building user interfaces.
|
|
||||||
* [Redux](http://redux.js.org/) is a predictable state container for JavaScript apps.
|
|
||||||
* [Material-UI](http://www.material-ui.com/#/) A Set of React Components that Implement Google's Material Design.
|
|
||||||
* [react-redux](https://github.com/reactjs/react-redux) Official React bindings for Redux.
|
|
||||||
* [Firebase](https://firebase.google.com/) products like Analytics, Realtime Database, Messaging, and Crash Reporting let you move quickly and focus on your users.
|
|
||||||
* [redux-thunk](https://github.com/gaearon/redux-thunk) Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.
|
|
||||||
* [Express](https://expressjs.com/) Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
|
|
||||||
* [React Router V4](https://github.com/ReactTraining/react-router) for routing website location
|
|
||||||
* [Sass](http://sass-lang.com/) CSS with superpowers. Sass boasts more features and abilities than any other CSS extension language out there.
|
|
||||||
* [Webpack](https://webpack.js.org/) for bundling code
|
|
||||||
|
|
||||||
## In my todo list
|
|
||||||
|
|
||||||
* Documentation
|
|
||||||
* Testing
|
|
||||||
* Security issues
|
|
||||||
* Performance
|
|
||||||
* Add some features and solving bugs
|
|
||||||
* Sharing post in social itself and other socials
|
|
||||||
* Add link feature to post
|
|
||||||
* Add vido post
|
|
||||||
* Add image gallery post
|
|
||||||
* Search post and people
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# Prerequisites
|
## Road map
|
||||||
|
1. Support Firebase/Firestore -> on developing
|
||||||
|
2. Support AWS -> on developing
|
||||||
|
3. Support Azure
|
||||||
|
4. Support ASP.NET -> on developing
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
Install [NodeJs](https://nodejs.org/en/)
|
Install [NodeJs](https://nodejs.org/en/)
|
||||||
|
|
||||||
|
#### Note
|
||||||
|
|
||||||
# Installing
|
- If you're using Windows you should install all node-gyp dependencies with following commands:
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=E12PNKKjzqA)
|
`$ npm install --global --production windows-build-tools`
|
||||||
|
and then install the package
|
||||||
|
|
||||||
|
`$ npm install --global node-gyp`
|
||||||
|
|
||||||
|
|
||||||
|
### Installing
|
||||||
|
|
||||||
|
## Install back-end server/serverless
|
||||||
|
Comming soon :) ...
|
||||||
|
|
||||||
1. Fork the [react-social-network](https://github.com/Qolzam/react-social-network) repository on Github
|
1. Fork the [react-social-network](https://github.com/Qolzam/react-social-network) repository on Github
|
||||||
2. Clone your fork to your local machine `git clone git@github.com:<yourname>/react-social-network.git`
|
2. Clone your fork to your local machine `git clone git@github.com:<yourname>/react-social-network.git`
|
||||||
@@ -101,31 +95,56 @@ I recommend that you get to know React before using React Social Network. React
|
|||||||
|
|
||||||
5. Installing all nodejs modules:
|
5. Installing all nodejs modules:
|
||||||
`npm install`
|
`npm install`
|
||||||
6. Rub webpack to build bundle file
|
6. Go ahead ;)
|
||||||
`webpack`
|
`npm start`
|
||||||
5. Running server:
|
|
||||||
`node server.js`
|
|
||||||
|
|
||||||
# Warning
|
|
||||||
|
|
||||||
- If you're using Windows you should install all node-gyp dependencies with following commands:
|
|
||||||
|
|
||||||
`$ npm install --global --production windows-build-tools`
|
|
||||||
and then install the package
|
|
||||||
|
|
||||||
`$ npm install --global node-gyp`
|
## Deployment
|
||||||
|
Follow [firebase instruction](https://firebase.google.com/docs/hosting/deploying)
|
||||||
|
`firebase deploy`
|
||||||
|
|
||||||
## Contribute
|
## Built With
|
||||||
|
|
||||||
[React Social Network](http://greensocial.herokuapp.com/) has been made by love. I planed to build a back-end for this project and improve the performance as I process all procedures on the front-end side. If you'd like to help,
|
* [TypeScript](https://www.typescriptlang.org/) TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
|
||||||
|
* [JSX/TSX](https://jsx.github.io/) This project support both *.jsx and *.tsx files. JSX is a statically-typed, object-oriented programming language designed to run on modern web browsers. Being developed at DeNA as a research project, the language has following characteristics.
|
||||||
|
* [React](https://facebook.github.io/react/docs/hello-world.html) A javascript library for building user interfaces.
|
||||||
|
* [Redux](http://redux.js.org/) is a predictable state container for JavaScript apps.
|
||||||
|
* [Material-UI](http://www.material-ui.com/#/) A Set of React Components that Implement Google's Material Design.
|
||||||
|
* [react-redux](https://github.com/reactjs/react-redux) Official React bindings for Redux.
|
||||||
|
* [Firebase](https://firebase.google.com/) products like Analytics, Realtime Database, Messaging, and Crash Reporting let you move quickly and focus on your users.
|
||||||
|
* [redux-thunk](https://github.com/gaearon/redux-thunk) Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.
|
||||||
|
* [Express](https://expressjs.com/) Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
|
||||||
|
* [React Router V4](https://github.com/ReactTraining/react-router) for routing website location
|
||||||
|
* [Sass](http://sass-lang.com/) CSS with superpowers. Sass boasts more features and abilities than any other CSS extension language out there.
|
||||||
|
* [Webpack](https://webpack.js.org/) for bundling code
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
[React Social Network](https://love-social.firebaseapp.com) has been made by love. I planed to build a back-end for this project and improve the performance as I process all procedures on the front-end side. If you'd like to help,
|
||||||
check out the [document](https://qolzam.gitbooks.io/react-social-network/).
|
check out the [document](https://qolzam.gitbooks.io/react-social-network/).
|
||||||
I'd greatly appreciate any [contribution](https://github.com/Qolzam/react-social-network/blob/master/CONTRIBUTING.md)
|
I'd greatly appreciate any [contribution](https://github.com/Qolzam/react-social-network/blob/master/CONTRIBUTING.md)
|
||||||
you make. :)
|
|
||||||
|
|
||||||
# Authors
|
## Versioning
|
||||||
|
|
||||||
|
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/Qolzam/react-social-network/tags).
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
- Amir Movahedi
|
- Amir Movahedi
|
||||||
|
- See also the list of [contributors](https://github.com/Qolzam/react-social-network/contributors) who participated in this project.
|
||||||
|
|
||||||
# License
|
## License
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the [LICENSE](https://github.com/Qolzam/react-social-network/blob/master/LICENSE) file for details
|
This project is licensed under the MIT License - see the [LICENSE](https://github.com/Qolzam/react-social-network/blob/master/LICENSE) file for details
|
||||||
|
|
||||||
|
|
||||||
|
## Acknowledgments
|
||||||
|
|
||||||
|
* React
|
||||||
|
* Firebase
|
||||||
|
* JavaScript
|
||||||
|
* TypeScript
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,22 +2,6 @@
|
|||||||
|
|
||||||
Is a decoupled layer of interfaces to data and/or functionality of one or more components.
|
Is a decoupled layer of interfaces to data and/or functionality of one or more components.
|
||||||
|
|
||||||
## CircleAPI.jsx
|
|
||||||
|
|
||||||
We provided some functions for doing some procedures on user circles.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
getUserBelongCircles = (circles,followingId) => {}
|
|
||||||
```
|
|
||||||
|
|
||||||
To get circles which the user is added in. `circles` is the parameter that we want to know if user is exist in any of them or not. `followingId` is the parameter that show the use identifier who we are looking for in `circles` parameter.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
getFollowingUsers = (circles) => {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Get the user who are in circles. `circles` is the paramater that we get users from.
|
|
||||||
|
|
||||||
## FileAPI.jsx
|
## FileAPI.jsx
|
||||||
|
|
||||||
A set of functions for working with files.
|
A set of functions for working with files.
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
"node-sass": "^4.5.2",
|
"node-sass": "^4.5.2",
|
||||||
"npm": "^5.6.0",
|
"npm": "^5.6.0",
|
||||||
"prop-types": "^15.6.0",
|
"prop-types": "^15.6.0",
|
||||||
"react": "^16.0.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.0.0",
|
||||||
@@ -68,6 +68,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash": "^4.14.77",
|
"@types/lodash": "^4.14.77",
|
||||||
"@types/material-ui": "^0.18.2",
|
"@types/material-ui": "^0.18.2",
|
||||||
|
"@types/moment": "^2.13.0",
|
||||||
"@types/node": "^8.0.33",
|
"@types/node": "^8.0.33",
|
||||||
"@types/prop-types": "^15.5.2",
|
"@types/prop-types": "^15.5.2",
|
||||||
"@types/react": "^16.0.10",
|
"@types/react": "^16.0.10",
|
||||||
|
|||||||
@@ -14,12 +14,17 @@ import * as globalActions from 'actions/globalActions'
|
|||||||
import * as postActions from 'actions/postActions'
|
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 { IServiceProvider, ServiceProvide } from 'core/factories'
|
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'
|
||||||
import { IUserTieService } from 'core/services/circles'
|
import { IUserTieService } from 'core/services/circles'
|
||||||
|
import StringAPI from 'api/StringAPI'
|
||||||
|
import { ServerRequestStatusType } from 'actions/serverRequestStatusType'
|
||||||
|
import { ServerRequestType } from 'constants/serverRequestType'
|
||||||
|
import { ServerRequestModel } from 'models/server/serverRequestModel'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get service providers
|
* Get service providers
|
||||||
@@ -39,7 +44,9 @@ export let dbAddCircle = (circleName: string) => {
|
|||||||
let uid: string = getState().authorize.uid
|
let uid: string = getState().authorize.uid
|
||||||
let circle: Circle = {
|
let circle: Circle = {
|
||||||
creationDate: moment().unix(),
|
creationDate: moment().unix(),
|
||||||
name: circleName
|
name: circleName,
|
||||||
|
isSystem : false,
|
||||||
|
ownerId: uid
|
||||||
}
|
}
|
||||||
return circleService.addCircle(uid, circle).then((circleKey: string) => {
|
return circleService.addCircle(uid, circle).then((circleKey: string) => {
|
||||||
circle.id = circleKey
|
circle.id = circleKey
|
||||||
@@ -51,6 +58,60 @@ export let dbAddCircle = (circleName: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add referer user to the `Following` circle of current user
|
||||||
|
*/
|
||||||
|
export const dbFollowUser = (followingCircleId: string, userFollowing: UserTie) => {
|
||||||
|
return (dispatch: Function, getState: Function) => {
|
||||||
|
const state = getState()
|
||||||
|
let uid: string = state.authorize.uid
|
||||||
|
let user: User = { ...state.user.info[uid], userId: uid }
|
||||||
|
|
||||||
|
// Set server request status to {Sent} for following user
|
||||||
|
const followReqestModel = createFollowRequest(userFollowing.userId!)
|
||||||
|
dispatch(serverActions.sendRequest(followReqestModel))
|
||||||
|
|
||||||
|
// Call server API
|
||||||
|
return userTieService.tieUseres(
|
||||||
|
{ userId: user.userId!, fullName: user.fullName, avatar: user.avatar, approved: false },
|
||||||
|
{ userId: userFollowing.userId!, fullName: userFollowing.fullName, avatar: userFollowing.avatar, approved: false },
|
||||||
|
[followingCircleId]
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
dispatch(addFollowingUser(
|
||||||
|
new UserTie(
|
||||||
|
userFollowing.userId!,
|
||||||
|
moment().unix(),
|
||||||
|
userFollowing.fullName,
|
||||||
|
userFollowing.avatar,
|
||||||
|
false,
|
||||||
|
[followingCircleId]
|
||||||
|
)))
|
||||||
|
|
||||||
|
// Set server request status to {OK} for following user
|
||||||
|
followReqestModel.status = ServerRequestStatusType.OK
|
||||||
|
dispatch(serverActions.sendRequest(followReqestModel))
|
||||||
|
|
||||||
|
// Send notification
|
||||||
|
dispatch(notifyActions.dbAddNotification(
|
||||||
|
{
|
||||||
|
description: `${user.fullName} follow you.`,
|
||||||
|
url: `/${uid}`,
|
||||||
|
notifyRecieverUserId: userFollowing.userId as string,
|
||||||
|
notifierUserId: uid,
|
||||||
|
isSeen: false
|
||||||
|
}))
|
||||||
|
|
||||||
|
}, (error: SocialError) => {
|
||||||
|
dispatch(globalActions.showErrorMessage(error.message))
|
||||||
|
|
||||||
|
// Set server request status to {Error} for following user
|
||||||
|
followReqestModel.status = ServerRequestStatusType.Error
|
||||||
|
dispatch(serverActions.sendRequest(followReqestModel))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update user in circle/circles
|
* Update user in circle/circles
|
||||||
*/
|
*/
|
||||||
@@ -60,7 +121,14 @@ export let dbUpdateUserInCircles = (circleIdList: string[], userFollowing: UserT
|
|||||||
let uid: string = state.authorize.uid
|
let uid: string = state.authorize.uid
|
||||||
let user: User = { ...state.user.info[uid], userId: uid }
|
let user: User = { ...state.user.info[uid], userId: uid }
|
||||||
|
|
||||||
return userTieService.tieUseres(
|
// Set server request status to {Sent}
|
||||||
|
const addToCircleRequest = createAddToCircleRequest(userFollowing.userId!)
|
||||||
|
dispatch(serverActions.sendRequest(addToCircleRequest))
|
||||||
|
|
||||||
|
dispatch(globalActions.showMasterLoading())
|
||||||
|
|
||||||
|
// Call server API
|
||||||
|
return userTieService.updateUsersTie(
|
||||||
{ userId: user.userId!, fullName: user.fullName, avatar: user.avatar, approved: false },
|
{ userId: user.userId!, fullName: user.fullName, avatar: user.avatar, approved: false },
|
||||||
{ userId: userFollowing.userId!, fullName: userFollowing.fullName, avatar: userFollowing.avatar, approved: false },
|
{ userId: userFollowing.userId!, fullName: userFollowing.fullName, avatar: userFollowing.avatar, approved: false },
|
||||||
circleIdList
|
circleIdList
|
||||||
@@ -76,17 +144,23 @@ export let dbUpdateUserInCircles = (circleIdList: string[], userFollowing: UserT
|
|||||||
circleIdList
|
circleIdList
|
||||||
)))
|
)))
|
||||||
|
|
||||||
dispatch(notifyActions.dbAddNotification(
|
// Set server request status to {OK}
|
||||||
{
|
addToCircleRequest.status = ServerRequestStatusType.OK
|
||||||
description: `${user.fullName} follow you.`,
|
dispatch(serverActions.sendRequest(addToCircleRequest))
|
||||||
url: `/${uid}`,
|
|
||||||
notifyRecieverUserId: userFollowing.userId as string,
|
dispatch(globalActions.hideMasterLoading())
|
||||||
notifierUserId: uid,
|
|
||||||
isSeen: false
|
// Close select circle box
|
||||||
}))
|
dispatch(closeSelectCircleBox(userFollowing.userId!))
|
||||||
|
|
||||||
}, (error: SocialError) => {
|
}, (error: SocialError) => {
|
||||||
dispatch(globalActions.showErrorMessage(error.message))
|
dispatch(globalActions.showErrorMessage(error.message))
|
||||||
|
|
||||||
|
dispatch(globalActions.hideMasterLoading())
|
||||||
|
|
||||||
|
// Set server request status to {Error}
|
||||||
|
addToCircleRequest.status = ServerRequestStatusType.Error
|
||||||
|
dispatch(serverActions.sendRequest(addToCircleRequest))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,11 +173,36 @@ export let dbDeleteFollowingUser = (userFollowingId: string) => {
|
|||||||
|
|
||||||
let uid: string = getState().authorize.uid
|
let uid: string = getState().authorize.uid
|
||||||
|
|
||||||
|
// Set server request status to {Sent}
|
||||||
|
const deleteFollowingUserRequest = createdeleteFollowingUserRequest(userFollowingId)
|
||||||
|
dispatch(serverActions.sendRequest(deleteFollowingUserRequest))
|
||||||
|
|
||||||
|
dispatch(globalActions.showMasterLoading())
|
||||||
|
|
||||||
|
// Call server API
|
||||||
return userTieService.removeUsersTie(uid, userFollowingId)
|
return userTieService.removeUsersTie(uid, userFollowingId)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
dispatch(deleteFollowingUser(userFollowingId))
|
dispatch(deleteFollowingUser(userFollowingId))
|
||||||
|
|
||||||
|
dispatch(globalActions.hideMasterLoading())
|
||||||
|
|
||||||
|
// Close select circle box
|
||||||
|
dispatch(closeSelectCircleBox(userFollowingId))
|
||||||
|
|
||||||
|
// Set server request status to {OK}
|
||||||
|
deleteFollowingUserRequest.status = ServerRequestStatusType.OK
|
||||||
|
dispatch(serverActions.sendRequest(deleteFollowingUserRequest))
|
||||||
}, (error: SocialError) => {
|
}, (error: SocialError) => {
|
||||||
dispatch(globalActions.showErrorMessage(error.message))
|
dispatch(globalActions.showErrorMessage(error.message))
|
||||||
|
|
||||||
|
dispatch(globalActions.hideMasterLoading())
|
||||||
|
|
||||||
|
// Close select circle box
|
||||||
|
dispatch(closeSelectCircleBox(userFollowingId))
|
||||||
|
|
||||||
|
// Set server request status to {Error}
|
||||||
|
deleteFollowingUserRequest.status = ServerRequestStatusType.Error
|
||||||
|
dispatch(serverActions.sendRequest(deleteFollowingUserRequest))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +219,8 @@ export const dbUpdateCircle = (newCircle: Circle) => {
|
|||||||
// Write the new data simultaneously in the list
|
// Write the new data simultaneously in the list
|
||||||
let circle: Circle = getState().circle.userTies[uid][newCircle.id!]
|
let circle: Circle = getState().circle.userTies[uid][newCircle.id!]
|
||||||
let updatedCircle: Circle = {
|
let updatedCircle: Circle = {
|
||||||
name: newCircle.name || circle.name
|
name: newCircle.name || circle.name,
|
||||||
|
isSystem : false
|
||||||
}
|
}
|
||||||
return circleService.updateCircle(uid, newCircle.id!, circle)
|
return circleService.updateCircle(uid, newCircle.id!, circle)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -198,10 +298,10 @@ export const dbGetFollowers = () => {
|
|||||||
return (dispatch: any, getState: Function) => {
|
return (dispatch: any, getState: Function) => {
|
||||||
let uid: string = getState().authorize.uid
|
let uid: string = getState().authorize.uid
|
||||||
if (uid) {
|
if (uid) {
|
||||||
userTieService.getUserTies(uid).then((result) => {
|
userTieService.getUserTieSender(uid).then((result) => {
|
||||||
|
|
||||||
dispatch(userActions.addPeopleInfo(result as any))
|
dispatch(userActions.addPeopleInfo(result as any))
|
||||||
dispatch(addUserTies(result))
|
dispatch(addUserTieds(result))
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((error: SocialError) => {
|
.catch((error: SocialError) => {
|
||||||
@@ -230,6 +330,45 @@ export const dbGetCirclesByUserId = (uid: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create follow user serevr request model
|
||||||
|
*/
|
||||||
|
const createFollowRequest = (userFollowingId: string) => {
|
||||||
|
const requestId = StringAPI.createServerRequestId(ServerRequestType.CircleFollowUser, userFollowingId)
|
||||||
|
return new ServerRequestModel(
|
||||||
|
ServerRequestType.CircleFollowUser,
|
||||||
|
requestId,
|
||||||
|
'',
|
||||||
|
ServerRequestStatusType.Sent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create add referer user to circle serevr request model
|
||||||
|
*/
|
||||||
|
const createAddToCircleRequest = (userFollowingId: string) => {
|
||||||
|
const requestId = StringAPI.createServerRequestId(ServerRequestType.CircleAddToCircle, userFollowingId)
|
||||||
|
return new ServerRequestModel(
|
||||||
|
ServerRequestType.CircleAddToCircle,
|
||||||
|
requestId,
|
||||||
|
'',
|
||||||
|
ServerRequestStatusType.Sent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create delete referer user serevr request model
|
||||||
|
*/
|
||||||
|
const createdeleteFollowingUserRequest = (userFollowingId: string) => {
|
||||||
|
const requestId = StringAPI.createServerRequestId(ServerRequestType.CircleDeleteFollowingUser, userFollowingId)
|
||||||
|
return new ServerRequestModel(
|
||||||
|
ServerRequestType.CircleDeleteFollowingUser,
|
||||||
|
requestId,
|
||||||
|
'',
|
||||||
|
ServerRequestStatusType.Sent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/* _____________ CRUD State _____________ */
|
/* _____________ CRUD State _____________ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,6 +535,49 @@ export const showFollowingUserLoading = (userId: string) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set current user selected circles for referer user
|
||||||
|
*/
|
||||||
|
export const setSelectedCircles = (userId: string, circleList: string[]) => {
|
||||||
|
return {
|
||||||
|
type: CircleActionType.SET_SELECTED_CIRCLES_USER_BOX_COMPONENT,
|
||||||
|
payload: { userId, circleList }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove current user selected circles for referer user
|
||||||
|
*/
|
||||||
|
export const removeSelectedCircles = (userId: string) => {
|
||||||
|
return {
|
||||||
|
type: CircleActionType.REMOVE_SELECTED_CIRCLES_USER_BOX_COMPONENT,
|
||||||
|
payload: { userId }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open select circle box
|
||||||
|
*/
|
||||||
|
export const openSelectCircleBox = (userId: string) => {
|
||||||
|
return {
|
||||||
|
type: CircleActionType.OPEN_SELECT_CIRCLES_USER_BOX_COMPONENT,
|
||||||
|
payload: { userId}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close select circle box
|
||||||
|
*/
|
||||||
|
export const closeSelectCircleBox = (userId: string) => {
|
||||||
|
return {
|
||||||
|
type: CircleActionType.CLOSE_SELECT_CIRCLES_USER_BOX_COMPONENT,
|
||||||
|
payload: { userId}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide loading on following user
|
* Hide loading on following user
|
||||||
*/
|
*/
|
||||||
@@ -405,4 +587,4 @@ export const hideFollowingUserLoading = (userId: string) => {
|
|||||||
payload: { userId }
|
payload: { userId }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export const dbGetComments = (ownerUserId: string, postId: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const desiredComments = comments[postId]
|
const desiredComments = comments[postId]
|
||||||
if (desiredComments && Object.keys(desiredComments).length > 0) {
|
if (desiredComments) {
|
||||||
commentsCount = Object.keys(desiredComments).length
|
commentsCount = Object.keys(desiredComments).length
|
||||||
let sortedObjects = desiredComments as any
|
let sortedObjects = desiredComments as any
|
||||||
// Sort posts with creation date
|
// Sort posts with creation date
|
||||||
|
|||||||
@@ -5,6 +5,50 @@ import { GlobalActionType } from 'constants/globalActionType'
|
|||||||
import * as postActions from 'actions/postActions'
|
import * as postActions from 'actions/postActions'
|
||||||
import * as commentActions from 'actions/commentActions'
|
import * as commentActions from 'actions/commentActions'
|
||||||
import * as userActions from 'actions/userActions'
|
import * as userActions from 'actions/userActions'
|
||||||
|
import * as serverActions from 'actions/serverActions'
|
||||||
|
|
||||||
|
import { ICommonService } from 'core/services/common/ICommonService'
|
||||||
|
import { provider } from 'src/socialEngine'
|
||||||
|
import { SocialProviderTypes } from 'core/socialProviderTypes'
|
||||||
|
import { Feed, SocialError } from 'core/domain/common'
|
||||||
|
import { ServerRequestType } from 'constants/serverRequestType'
|
||||||
|
import StringAPI from 'api/StringAPI'
|
||||||
|
import { ServerRequestModel } from 'models/server'
|
||||||
|
import { ServerRequestStatusType } from 'actions/serverRequestStatusType'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get service providers
|
||||||
|
*/
|
||||||
|
const commonService: ICommonService = provider.get<ICommonService>(SocialProviderTypes.CommonService)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a normal feed
|
||||||
|
* @param {any} newFeed
|
||||||
|
* @param {Function} callBack
|
||||||
|
*/
|
||||||
|
export let dbSendFeed = (newFeed: Feed) => {
|
||||||
|
return (dispatch: any, getState: Function) => {
|
||||||
|
|
||||||
|
let uid: string = getState().authorize.uid
|
||||||
|
|
||||||
|
// Set server request status to {Sent}
|
||||||
|
const feedbackRequest = createFeedbackRequest(uid)
|
||||||
|
dispatch(serverActions.sendRequest(feedbackRequest))
|
||||||
|
|
||||||
|
return commonService.addFeed(newFeed).then(() => {
|
||||||
|
// Set server request status to {OK}
|
||||||
|
feedbackRequest.status = ServerRequestStatusType.OK
|
||||||
|
dispatch(serverActions.sendRequest(feedbackRequest))
|
||||||
|
})
|
||||||
|
.catch((error: SocialError) => {
|
||||||
|
dispatch(showErrorMessage(error.message))
|
||||||
|
|
||||||
|
// Set server request status to {Error}
|
||||||
|
feedbackRequest.status = ServerRequestStatusType.Error
|
||||||
|
dispatch(serverActions.sendRequest(feedbackRequest))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Progress change
|
* Progress change
|
||||||
@@ -14,7 +58,7 @@ import * as userActions from 'actions/userActions'
|
|||||||
export const progressChange = (percent: number, visible: Boolean) => {
|
export const progressChange = (percent: number, visible: Boolean) => {
|
||||||
return {
|
return {
|
||||||
type: GlobalActionType.PROGRESS_CHANGE,
|
type: GlobalActionType.PROGRESS_CHANGE,
|
||||||
payload: {percent, visible}
|
payload: { percent, visible }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -23,7 +67,7 @@ export const progressChange = (percent: number, visible: Boolean) => {
|
|||||||
* Default data loaded status will be true
|
* Default data loaded status will be true
|
||||||
*/
|
*/
|
||||||
export const defaultDataEnable = () => {
|
export const defaultDataEnable = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.DEFAULT_DATA_ENABLE
|
type: GlobalActionType.DEFAULT_DATA_ENABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,21 +77,21 @@ export const defaultDataEnable = () => {
|
|||||||
* @param {boolean} status
|
* @param {boolean} status
|
||||||
*/
|
*/
|
||||||
export const defaultDataDisable = () => {
|
export const defaultDataDisable = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.DEFAULT_DATA_DISABLE
|
type: GlobalActionType.DEFAULT_DATA_DISABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - Show notification of request
|
// - Show notification of request
|
||||||
export const showNotificationRequest = () => {
|
export const showNotificationRequest = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.SHOW_SEND_REQUEST_MESSAGE_GLOBAL
|
type: GlobalActionType.SHOW_SEND_REQUEST_MESSAGE_GLOBAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - Show notification of success
|
// - Show notification of success
|
||||||
export const showNotificationSuccess = () => {
|
export const showNotificationSuccess = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.SHOW_REQUEST_SUCCESS_MESSAGE_GLOBAL
|
type: GlobalActionType.SHOW_REQUEST_SUCCESS_MESSAGE_GLOBAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,7 +101,7 @@ export const showNotificationSuccess = () => {
|
|||||||
*/
|
*/
|
||||||
export const hideMessage = () => {
|
export const hideMessage = () => {
|
||||||
hideTopLoading()
|
hideTopLoading()
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.HIDE_MESSAGE_GLOBAL
|
type: GlobalActionType.HIDE_MESSAGE_GLOBAL
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,23 +112,6 @@ export const hideMessage = () => {
|
|||||||
* @param {string} message
|
* @param {string} message
|
||||||
*/
|
*/
|
||||||
export const showErrorMessage = (message: string) => {
|
export const showErrorMessage = (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)
|
|
||||||
return {
|
return {
|
||||||
type: GlobalActionType.SHOW_ERROR_MESSAGE_GLOBAL,
|
type: GlobalActionType.SHOW_ERROR_MESSAGE_GLOBAL,
|
||||||
payload: message
|
payload: message
|
||||||
@@ -95,8 +122,8 @@ export const showErrorMessage = (message: string) => {
|
|||||||
/**
|
/**
|
||||||
* Set header title
|
* Set header title
|
||||||
*/
|
*/
|
||||||
export const setHeaderTitleOpt = (callerKey: string,payload: any) => {
|
export const setHeaderTitleOpt = (callerKey: string, payload: any) => {
|
||||||
return (dispatch: any,getState: Function) => {
|
return (dispatch: any, getState: Function) => {
|
||||||
switch (callerKey) {
|
switch (callerKey) {
|
||||||
case 'profile':
|
case 'profile':
|
||||||
const userName = getState().user.info && getState().user.info[payload] ? getState().user.info[payload].fullName : ''
|
const userName = getState().user.info && getState().user.info[payload] ? getState().user.info[payload].fullName : ''
|
||||||
@@ -114,7 +141,7 @@ export const setHeaderTitleOpt = (callerKey: string,payload: any) => {
|
|||||||
* Set header title
|
* Set header title
|
||||||
*/
|
*/
|
||||||
export const setHeaderTitle = (text: string) => {
|
export const setHeaderTitle = (text: string) => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.SET_HEADER_TITLE,
|
type: GlobalActionType.SET_HEADER_TITLE,
|
||||||
payload: text
|
payload: text
|
||||||
}
|
}
|
||||||
@@ -125,7 +152,7 @@ export const setHeaderTitle = (text: string) => {
|
|||||||
* Open post write
|
* Open post write
|
||||||
*/
|
*/
|
||||||
export const openPostWrite = () => {
|
export const openPostWrite = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.OPEN_POST_WRITE
|
type: GlobalActionType.OPEN_POST_WRITE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +162,7 @@ export const openPostWrite = () => {
|
|||||||
* Close post write
|
* Close post write
|
||||||
*/
|
*/
|
||||||
export const closePostWrite = () => {
|
export const closePostWrite = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.CLOSE_POST_WRITE
|
type: GlobalActionType.CLOSE_POST_WRITE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +172,7 @@ export const closePostWrite = () => {
|
|||||||
* Show top loading
|
* Show top loading
|
||||||
*/
|
*/
|
||||||
export const showTopLoading = () => {
|
export const showTopLoading = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.SHOW_TOP_LOADING
|
type: GlobalActionType.SHOW_TOP_LOADING
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,17 +182,57 @@ export const showTopLoading = () => {
|
|||||||
* Hide top loading
|
* Hide top loading
|
||||||
*/
|
*/
|
||||||
export const hideTopLoading = () => {
|
export const hideTopLoading = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.HIDE_TOP_LOADING
|
type: GlobalActionType.HIDE_TOP_LOADING
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show master loading
|
||||||
|
*/
|
||||||
|
export const showMasterLoading = () => {
|
||||||
|
return {
|
||||||
|
type: GlobalActionType.SHOW_MASTER_LOADING
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show send feedback
|
||||||
|
*/
|
||||||
|
export const showSendFeedback = () => {
|
||||||
|
return {
|
||||||
|
type: GlobalActionType.SHOW_SEND_FEEDBACK
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide send feedback
|
||||||
|
*/
|
||||||
|
export const hideSendFeedback = () => {
|
||||||
|
return {
|
||||||
|
type: GlobalActionType.HIDE_SEND_FEEDBACK
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide master loading
|
||||||
|
*/
|
||||||
|
export const hideMasterLoading = () => {
|
||||||
|
return {
|
||||||
|
type: GlobalActionType.HIDE_MASTER_LOADING
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store temp data
|
* Store temp data
|
||||||
*/
|
*/
|
||||||
export const temp = (data: any) => {
|
export const temp = (data: any) => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.TEMP,
|
type: GlobalActionType.TEMP,
|
||||||
payload: data
|
payload: data
|
||||||
}
|
}
|
||||||
@@ -176,7 +243,7 @@ export const temp = (data: any) => {
|
|||||||
* Clear temp data
|
* Clear temp data
|
||||||
*/
|
*/
|
||||||
export const clearTemp = () => {
|
export const clearTemp = () => {
|
||||||
return{
|
return {
|
||||||
type: GlobalActionType.CLEAR_TEMP
|
type: GlobalActionType.CLEAR_TEMP
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +252,43 @@ export const clearTemp = () => {
|
|||||||
// - Load data for guest
|
// - Load data for guest
|
||||||
export const loadDataGuest = () => {
|
export const loadDataGuest = () => {
|
||||||
// tslint:disable-next-line:no-empty
|
// tslint:disable-next-line:no-empty
|
||||||
return (dispatch: any,getState: Function) => {
|
return (dispatch: any, getState: Function) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
const createFeedbackRequest = (userId: string) => {
|
||||||
|
const requestId = StringAPI.createServerRequestId(ServerRequestType.CommonSendFeedback, userId)
|
||||||
|
return new ServerRequestModel(
|
||||||
|
ServerRequestType.CommonSendFeedback,
|
||||||
|
requestId,
|
||||||
|
'',
|
||||||
|
ServerRequestStatusType.Sent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { SocialError } from 'core/domain/common/socialError'
|
|||||||
* @param {Request} request
|
* @param {Request} request
|
||||||
*/
|
*/
|
||||||
export const sendRequest = (request: ServerRequestModel) => {
|
export const sendRequest = (request: ServerRequestModel) => {
|
||||||
return { type: ServerActionType.ADD_REQUEST, payload: request }
|
return { type: ServerActionType.ADD_REQUEST, payload: {request} }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import { Circle, UserTie } from 'core/domain/circles'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the circles' id which the specify users is in that circle
|
|
||||||
* @param {object} circles
|
|
||||||
* @param {string} followingId
|
|
||||||
*/
|
|
||||||
export const getUserBelongCircles = (circles: {[circleId: string]: Circle},followingId: string) => {
|
|
||||||
let userBelongCircles: string[] = []
|
|
||||||
Object.keys(circles).forEach((cid) => {
|
|
||||||
if (cid.trim() !== '-Followers' && circles[cid].users) {
|
|
||||||
let isExist = Object.keys(circles[cid].users).indexOf(followingId) > -1
|
|
||||||
if (isExist) {
|
|
||||||
userBelongCircles.push(cid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return userBelongCircles
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the following users
|
|
||||||
* @param {object} circles
|
|
||||||
*/
|
|
||||||
export const getFollowingUsers = (circles: {[circleId: string]: Circle}) => {
|
|
||||||
let followingUsers: {[userId: string]: UserTie} = {}
|
|
||||||
Object.keys(circles).forEach((cid) => {
|
|
||||||
if (cid.trim() !== '-Followers' && circles[cid].users) {
|
|
||||||
Object.keys(circles[cid].users).forEach((userId) => {
|
|
||||||
let isExist = Object.keys(followingUsers).indexOf(userId) > -1
|
|
||||||
if (!isExist) {
|
|
||||||
followingUsers[userId] = {
|
|
||||||
...circles[cid].users[userId]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return followingUsers
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getUserBelongCircles,
|
|
||||||
getFollowingUsers
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,15 @@
|
|||||||
|
import * as moment from 'moment'
|
||||||
/**
|
/**
|
||||||
* Log the data
|
* Log the data
|
||||||
* @param title log title
|
* @param title log title
|
||||||
* @param data log data object
|
* @param data log data object
|
||||||
*/
|
*/
|
||||||
const logger = (title: string, data: any, trace?: boolean) => {
|
const logger = (title: string, data: any) => {
|
||||||
const randomColor = getRandomColor()
|
const randomColor = getRandomColor()
|
||||||
if (trace) {
|
|
||||||
console.trace()
|
console.log(`\n\n%c ======= ${title} ======= %c${moment().format('HH:mm:ss SSS')} \n`, `color:${getRandomColor()};font-size:15`
|
||||||
}
|
, `color:${getRandomColor()};font-size:15`, data,`\n\n =========================================`)
|
||||||
console.log(`\n\n\n%c ${title} :\n`, `color:${getRandomColor()};font-size:15`)
|
|
||||||
console.log('%c =========================================', `color:${randomColor}`)
|
|
||||||
console.log(data)
|
|
||||||
console.log('%c =========================================', `color:${randomColor}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
BIN
src/assets/fonts/Flaticon.eot
Normal file
BIN
src/assets/fonts/Flaticon.eot
Normal file
Binary file not shown.
BIN
src/assets/fonts/Flaticon.ttf
Normal file
BIN
src/assets/fonts/Flaticon.ttf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Flaticon.woff
Normal file
BIN
src/assets/fonts/Flaticon.woff
Normal file
Binary file not shown.
65
src/assets/images/Flaticon.svg
Normal file
65
src/assets/images/Flaticon.svg
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||||
|
<!--
|
||||||
|
2018-1-14: Created with FontForge (http://fontforge.org)
|
||||||
|
-->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
||||||
|
<metadata>
|
||||||
|
Created by FontForge 20160405 at Sun Jan 14 05:05:09 2018
|
||||||
|
By Apache
|
||||||
|
Copyright (c) 2018, Apache
|
||||||
|
</metadata>
|
||||||
|
<defs>
|
||||||
|
<font id="Flaticon" horiz-adv-x="512" >
|
||||||
|
<font-face
|
||||||
|
font-family="Flaticon"
|
||||||
|
font-weight="400"
|
||||||
|
font-stretch="normal"
|
||||||
|
units-per-em="512"
|
||||||
|
panose-1="2 0 5 3 0 0 0 0 0 0"
|
||||||
|
ascent="448"
|
||||||
|
descent="-64"
|
||||||
|
bbox="0 -63.999 512 448"
|
||||||
|
underline-thickness="25.6"
|
||||||
|
underline-position="-51.2"
|
||||||
|
unicode-range="U+0020-F106"
|
||||||
|
/>
|
||||||
|
<missing-glyph />
|
||||||
|
<glyph glyph-name="space" unicode=" " horiz-adv-x="200"
|
||||||
|
/>
|
||||||
|
<glyph glyph-name="uniF100" unicode=""
|
||||||
|
d="M345.6 217.601c-21.248 0 -38.3994 17.1514 -38.3994 38.3994s17.1514 38.4004 38.3994 38.4004s38.4004 -17.1523 38.4004 -38.4004s-17.1523 -38.3994 -38.4004 -38.3994zM166.4 217.601c-21.248 0 -38.4004 17.1514 -38.4004 38.3994s17.1523 38.4004 38.4004 38.4004
|
||||||
|
s38.3994 -17.1523 38.3994 -38.4004s-17.1514 -38.3994 -38.3994 -38.3994zM255.999 140.8c59.6484 0 110.208 -37.2471 130.688 -89.5996h-261.376c20.4795 52.3525 71.0391 89.5996 130.688 89.5996zM255.872 448c141.439 0 256.128 -114.561 256.128 -255.999
|
||||||
|
c0 -141.439 -114.688 -256 -256.128 -256s-255.872 114.561 -255.872 256c0 141.438 114.432 255.999 255.872 255.999zM255.999 -12.7998c113.153 0 204.801 91.6484 204.801 204.801c0 113.151 -91.6484 204.799 -204.801 204.799
|
||||||
|
c-113.151 0 -204.8 -91.6465 -204.8 -204.799c0 -113.153 91.6484 -204.801 204.8 -204.801z" />
|
||||||
|
<glyph glyph-name="uniF106" unicode=""
|
||||||
|
d="M255.999 51.2002c-59.6465 0 -110.335 37.376 -130.815 89.5996h261.631c-20.4785 -52.2236 -71.167 -89.5996 -130.815 -89.5996zM255.872 448c141.439 0 256.128 -114.561 256.128 -255.999c0 -141.439 -114.688 -256 -256.128 -256s-255.872 114.561 -255.872 256
|
||||||
|
c0 141.438 114.432 255.999 255.872 255.999zM255.999 -12.7998c113.153 0 204.801 91.6484 204.801 204.801c0 113.151 -91.6484 204.799 -204.801 204.799c-113.151 0 -204.8 -91.6465 -204.8 -204.799c0 -113.153 91.6484 -204.801 204.8 -204.801zM176.128 244.735
|
||||||
|
l-27.1357 -27.1348l-27.2646 27.1348l54.4004 54.2725l54.2715 -54.2725l-27.1348 -27.1348zM281.601 244.735l54.2705 54.2725l54.4014 -54.2725l-27.2646 -27.1348l-27.1367 27.1348l-27.1357 -27.1348z" />
|
||||||
|
<glyph glyph-name="uniF104" unicode=""
|
||||||
|
d="M166.4 217.601c-21.248 0 -38.4004 17.1514 -38.4004 38.3994s17.1523 38.4004 38.4004 38.4004s38.3994 -17.1523 38.3994 -38.4004s-17.1514 -38.3994 -38.3994 -38.3994zM345.6 217.601c-21.248 0 -38.3994 17.1514 -38.3994 38.3994s17.1514 38.4004 38.3994 38.4004
|
||||||
|
s38.4004 -17.1523 38.4004 -38.4004s-17.1523 -38.3994 -38.4004 -38.3994zM255.744 448c141.567 0 256.256 -114.688 256.256 -255.999c0 -141.312 -114.688 -256 -256.256 -256c-141.312 0 -255.744 114.688 -255.744 256c0 141.312 114.432 255.999 255.744 255.999z
|
||||||
|
M255.999 -12.7998c113.153 0 204.801 91.6484 204.801 204.801c0 113.151 -91.6484 204.799 -204.801 204.799c-113.151 0 -204.8 -91.6465 -204.8 -204.799c0 -113.153 91.6484 -204.801 204.8 -204.801zM255.999 140.8c59.6484 0 110.593 -37.2471 131.071 -89.5996
|
||||||
|
h-42.8789c-17.792 30.4639 -50.4326 51.2002 -88.1924 51.2002c-37.7588 0 -70.3984 -20.7363 -88.1924 -51.2002h-42.8799c20.4805 52.3525 71.4238 89.5996 131.072 89.5996z" />
|
||||||
|
<glyph glyph-name="uniF101" unicode=""
|
||||||
|
d="M148.992 192.001l-27.2646 27.1348l27.2646 27.1357l-27.2646 27.1367l27.2646 27.2646l27.1357 -27.2646l27.1367 27.2646l27.1348 -27.2646l-27.1348 -27.1367l27.1348 -27.1357l-27.1348 -27.1348l-27.1367 27.1348zM255.999 140.8
|
||||||
|
c59.6484 0 110.337 -37.376 130.817 -89.5996h-261.633c20.4795 52.2236 71.167 89.5996 130.815 89.5996zM363.008 300.673l27.2646 -27.2646l-27.2646 -27.1367l27.2646 -27.1357l-27.2646 -27.1348l-27.1367 27.1348l-27.1357 -27.1348l-27.1348 27.1348l27.1348 27.1357
|
||||||
|
l-27.1348 27.1367l27.1348 27.2646l27.1357 -27.2646zM255.872 448c141.439 0 256.128 -114.561 256.128 -255.999c0 -141.439 -114.688 -256 -256.128 -256s-255.872 114.561 -255.872 256c0 141.438 114.432 255.999 255.872 255.999zM255.999 -12.7998
|
||||||
|
c113.153 0 204.801 91.6484 204.801 204.801c0 113.151 -91.6484 204.799 -204.801 204.799c-113.151 0 -204.8 -91.6465 -204.8 -204.799c0 -113.153 91.6484 -204.801 204.8 -204.801z" />
|
||||||
|
<glyph glyph-name="uniF102" unicode=""
|
||||||
|
d="M255.744 448c141.567 0 256.256 -114.688 256.256 -255.999c0 -141.312 -114.688 -256 -256.256 -256c-141.312 0 -255.744 114.688 -255.744 256c0 141.312 114.432 255.999 255.744 255.999zM255.999 -12.7998c113.153 0 204.801 91.6484 204.801 204.801
|
||||||
|
c0 113.151 -91.6484 204.799 -204.801 204.799c-113.151 0 -204.8 -91.6465 -204.8 -204.799c0 -113.153 91.6484 -204.801 204.8 -204.801zM179.199 102.4v38.3994h153.601v-38.3994h-153.601zM204.8 256c0 -21.248 -17.1514 -38.3994 -38.3994 -38.3994
|
||||||
|
s-38.4004 17.1514 -38.4004 38.3994s17.1523 38.4004 38.4004 38.4004s38.3994 -17.1523 38.3994 -38.4004zM345.6 294.4c21.248 0 38.4004 -17.1523 38.4004 -38.4004s-17.1523 -38.3994 -38.4004 -38.3994s-38.3994 17.1514 -38.3994 38.3994
|
||||||
|
s17.1514 38.4004 38.3994 38.4004z" />
|
||||||
|
<glyph glyph-name="uniF105" unicode=""
|
||||||
|
d="M166.4 217.601c-21.248 0 -38.4004 17.1514 -38.4004 38.3994s17.1523 38.4004 38.4004 38.4004s38.3994 -17.1523 38.3994 -38.4004s-17.1514 -38.3994 -38.3994 -38.3994zM345.6 217.601c-21.248 0 -38.3994 17.1514 -38.3994 38.3994s17.1514 38.4004 38.3994 38.4004
|
||||||
|
s38.4004 -17.1523 38.4004 -38.4004s-17.1523 -38.3994 -38.4004 -38.3994zM255.999 89.5996c37.7607 0 70.4004 20.7363 88.1943 51.2002h42.8799c-20.4805 -52.3516 -71.4238 -89.5996 -131.072 -89.5996s-110.593 37.248 -131.072 89.5996h42.8789
|
||||||
|
c17.791 -30.4639 50.4316 -51.2002 88.1914 -51.2002zM255.744 448c141.567 0 256.256 -114.688 256.256 -255.999c0 -141.312 -114.688 -256 -256.256 -256c-141.312 0 -255.744 114.688 -255.744 256c0 141.312 114.432 255.999 255.744 255.999zM255.999 -12.7998
|
||||||
|
c113.153 0 204.801 91.6484 204.801 204.801c0 113.151 -91.6484 204.799 -204.801 204.799c-113.151 0 -204.8 -91.6465 -204.8 -204.799c0 -113.153 91.6484 -204.801 204.8 -204.801z" />
|
||||||
|
<glyph glyph-name="uniF103" unicode=""
|
||||||
|
d="M345.6 217.601c-21.248 0 -38.3994 17.1514 -38.3994 38.3994s17.1514 38.4004 38.3994 38.4004s38.4004 -17.1523 38.4004 -38.4004s-17.1523 -38.3994 -38.4004 -38.3994zM255.872 448c141.439 0 256.128 -114.561 256.128 -255.999
|
||||||
|
c0 -141.439 -114.688 -256 -256.128 -256s-255.872 114.561 -255.872 256c0 141.438 114.432 255.999 255.872 255.999zM255.999 -12.7998c113.153 0 204.801 91.6484 204.801 204.801c0 113.151 -91.6484 204.799 -204.801 204.799
|
||||||
|
c-113.151 0 -204.8 -91.6465 -204.8 -204.799c0 -113.153 91.6484 -204.801 204.8 -204.801zM166.4 217.601c-21.248 0 -38.4004 17.1514 -38.4004 38.3994s17.1523 38.4004 38.4004 38.4004s38.3994 -17.1523 38.3994 -38.4004s-17.1514 -38.3994 -38.3994 -38.3994z
|
||||||
|
M255.999 51.2002c-59.6465 0 -110.208 37.248 -130.687 89.5996h261.375c-20.4805 -52.3516 -71.04 -89.5996 -130.688 -89.5996z" />
|
||||||
|
</font>
|
||||||
|
</defs></svg>
|
||||||
|
After Width: | Height: | Size: 6.9 KiB |
@@ -29,7 +29,7 @@ import * as circleActions from 'actions/circleActions'
|
|||||||
|
|
||||||
import { ICircleComponentProps } from './ICircleComponentProps'
|
import { ICircleComponentProps } from './ICircleComponentProps'
|
||||||
import { ICircleComponentState } from './ICircleComponentState'
|
import { ICircleComponentState } from './ICircleComponentState'
|
||||||
import { Circle } from 'core/domain/circles'
|
import { Circle, UserTie } from 'core/domain/circles'
|
||||||
import { Profile } from 'core/domain/users/profile'
|
import { Profile } from 'core/domain/users/profile'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,21 +135,21 @@ export class CircleComponent extends Component<ICircleComponentProps, ICircleCom
|
|||||||
}
|
}
|
||||||
|
|
||||||
userList = () => {
|
userList = () => {
|
||||||
const { users } = this.props.circle
|
const { usersOfCircle } = this.props
|
||||||
const { userInfo } = this.props
|
|
||||||
let usersParsed: any = []
|
let usersParsed: any = []
|
||||||
|
|
||||||
if (users) {
|
if (usersOfCircle) {
|
||||||
Object.keys(users).forEach((key, index) => {
|
console.trace('usersOfCircle',usersOfCircle)
|
||||||
const { fullName } = users[key]
|
Object.keys(usersOfCircle).forEach((userId, index) => {
|
||||||
let avatar = userInfo && userInfo[key] ? userInfo[key].avatar || '' : ''
|
const { fullName } = usersOfCircle[userId]
|
||||||
|
let avatar = usersOfCircle && usersOfCircle[userId] ? usersOfCircle[userId].avatar || '' : ''
|
||||||
usersParsed.push(<ListItem
|
usersParsed.push(<ListItem
|
||||||
key={`${this.props.id}.${key}`}
|
key={`${this.props.id}.${userId}`}
|
||||||
style={this.styles.userListItem as any}
|
style={this.styles.userListItem as any}
|
||||||
value={2}
|
value={2}
|
||||||
primaryText={fullName}
|
primaryText={fullName}
|
||||||
leftAvatar={<UserAvatar fullName={fullName} fileName={avatar as any} />}
|
leftAvatar={<UserAvatar fullName={fullName!} fileName={avatar} />}
|
||||||
onClick={() => this.props.goTo!(`/${key}`)}
|
onClick={() => this.props.goTo!(`/${userId}`)}
|
||||||
/>)
|
/>)
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -176,6 +176,7 @@ export class CircleComponent extends Component<ICircleComponentProps, ICircleCom
|
|||||||
*/
|
*/
|
||||||
render () {
|
render () {
|
||||||
|
|
||||||
|
const {circle} = this.props
|
||||||
const circleTitle = (
|
const circleTitle = (
|
||||||
<div>
|
<div>
|
||||||
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
|
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||||
@@ -203,7 +204,7 @@ export class CircleComponent extends Component<ICircleComponentProps, ICircleCom
|
|||||||
style={{ backgroundColor: '#fff', borderBottom: '1px solid rgba(0,0,0,0.12)', height: '72px', padding: '12px 0' }}
|
style={{ backgroundColor: '#fff', borderBottom: '1px solid rgba(0,0,0,0.12)', height: '72px', padding: '12px 0' }}
|
||||||
primaryText={<span style={{ color: 'rgba(0,0,0,0.87)', fontSize: '16px', marginRight: '8px', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }}>{this.props.circle.name}</span>}
|
primaryText={<span style={{ color: 'rgba(0,0,0,0.87)', fontSize: '16px', marginRight: '8px', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }}>{this.props.circle.name}</span>}
|
||||||
leftIcon={<SvgGroup style={{ width: '40px', height: '40px', transform: 'translate(0px, -9px)', fill: '#bdbdbd' }} />}
|
leftIcon={<SvgGroup style={{ width: '40px', height: '40px', transform: 'translate(0px, -9px)', fill: '#bdbdbd' }} />}
|
||||||
rightIconButton={this.rightIconMenu}
|
rightIconButton={!circle.isSystem ? this.rightIconMenu : null}
|
||||||
initiallyOpen={false}
|
initiallyOpen={false}
|
||||||
onClick={this.handleToggleCircle}
|
onClick={this.handleToggleCircle}
|
||||||
open={this.state.open}
|
open={this.state.open}
|
||||||
@@ -259,10 +260,23 @@ const mapDispatchToProps = (dispatch: any, ownProps: ICircleComponentProps) => {
|
|||||||
*/
|
*/
|
||||||
const mapStateToProps = (state: any, ownProps: ICircleComponentProps) => {
|
const mapStateToProps = (state: any, ownProps: ICircleComponentProps) => {
|
||||||
const {circle, authorize, server} = state
|
const {circle, authorize, server} = state
|
||||||
|
const {userTies} = circle
|
||||||
const { uid } = state.authorize
|
const { uid } = state.authorize
|
||||||
const circles: { [circleId: string]: Circle } = circle ? (circle.circleList || {}) : {}
|
const circles: { [circleId: string]: Circle } = circle ? (circle.circleList || {}) : {}
|
||||||
const currentCircle = (circles ? circles[ownProps.id] : {}) as Circle
|
const currentCircle = (circles ? circles[ownProps.id] : {}) as Circle
|
||||||
|
|
||||||
|
let usersOfCircle: {[userId: string]: UserTie} = {}
|
||||||
|
Object.keys(userTies).forEach((userTieId) => {
|
||||||
|
const theUserTie = userTies[userTieId] as UserTie
|
||||||
|
if (theUserTie.circleIdList!.indexOf(ownProps.id) > -1) {
|
||||||
|
usersOfCircle = {
|
||||||
|
...usersOfCircle,
|
||||||
|
[userTieId]: theUserTie
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
return {
|
return {
|
||||||
|
usersOfCircle,
|
||||||
openSetting: state.circle ? (currentCircle ? (currentCircle.openCircleSettings || false) : false) : false,
|
openSetting: state.circle ? (currentCircle ? (currentCircle.openCircleSettings || false) : false) : false,
|
||||||
userInfo: state.user.info
|
userInfo: state.user.info
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Comment } from 'core/domain/comments'
|
import { Comment } from 'core/domain/comments'
|
||||||
import { Profile } from 'core/domain/users'
|
import { Profile } from 'core/domain/users'
|
||||||
import { Circle } from 'core/domain/circles'
|
import { Circle, UserTie } from 'core/domain/circles'
|
||||||
|
|
||||||
export interface ICircleComponentProps {
|
export interface ICircleComponentProps {
|
||||||
|
|
||||||
@@ -45,12 +45,9 @@ export interface ICircleComponentProps {
|
|||||||
deleteCircle?: Function
|
deleteCircle?: Function
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Users profile
|
* Users of current circle
|
||||||
*
|
|
||||||
* @type {{[userId: string]: Profile}}
|
|
||||||
* @memberof ICircleComponentProps
|
|
||||||
*/
|
*/
|
||||||
userInfo?: {[userId: string]: Profile}
|
usersOfCircle?: {[userId: string]: UserTie}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close setting box of circle
|
* Close setting box of circle
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ export interface IFindPeopleComponentProps {
|
|||||||
/**
|
/**
|
||||||
* If there are more people {true} or not {false}
|
* If there are more people {true} or not {false}
|
||||||
*/
|
*/
|
||||||
hasMorePeople: boolean
|
hasMorePeople?: boolean
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,8 +83,9 @@ const mapStateToProps = (state: any,ownProps: IFollowersComponentProps) => {
|
|||||||
const {circle, authorize, server} = state
|
const {circle, authorize, server} = state
|
||||||
const { uid } = state.authorize
|
const { uid } = state.authorize
|
||||||
const circles: { [circleId: string]: Circle } = circle ? (circle.circleList || {}) : {}
|
const circles: { [circleId: string]: Circle } = circle ? (circle.circleList || {}) : {}
|
||||||
|
const followers = circle ? circle.userTieds : {}
|
||||||
return{
|
return{
|
||||||
followers: circles ? circles.userTieds : {}
|
followers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import PropTypes from 'prop-types'
|
|||||||
// - Import app components
|
// - Import app components
|
||||||
import UserBoxList from 'components/userBoxList'
|
import UserBoxList from 'components/userBoxList'
|
||||||
|
|
||||||
|
import { Circle } from 'core/domain/circles'
|
||||||
|
|
||||||
// - Import API
|
// - Import API
|
||||||
import CircleAPI from 'api/CircleAPI'
|
|
||||||
import { IFollowingComponentProps } from './IFollowingComponentProps'
|
import { IFollowingComponentProps } from './IFollowingComponentProps'
|
||||||
import { IFollowingComponentState } from './IFollowingComponentState'
|
import { IFollowingComponentState } from './IFollowingComponentState'
|
||||||
import { Circle } from 'core/domain/circles';
|
|
||||||
|
|
||||||
// - Import actions
|
// - Import actions
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import PostPage from 'components/postPage'
|
|||||||
import People from 'components/people'
|
import People from 'components/people'
|
||||||
|
|
||||||
// - Import API
|
// - Import API
|
||||||
import CircleAPI from 'api/CircleAPI'
|
|
||||||
|
|
||||||
// - Import actions
|
// - Import actions
|
||||||
// - Import actions
|
// - Import actions
|
||||||
@@ -130,7 +129,7 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
|
|||||||
* @memberof Home
|
* @memberof Home
|
||||||
*/
|
*/
|
||||||
render () {
|
render () {
|
||||||
const {loaded, authed, loadDataStream, mergedPosts, hasMorePosts} = this.props
|
const {loaded, authed, loadDataStream, mergedPosts, hasMorePosts, showSendFeedback} = this.props
|
||||||
return (
|
return (
|
||||||
<div id='home'>
|
<div id='home'>
|
||||||
<HomeHeader sidebar={this.state.sidebarOpen} sidebarStatus={this.state.sidebarStatus} />
|
<HomeHeader sidebar={this.state.sidebarOpen} sidebarStatus={this.state.sidebarStatus} />
|
||||||
@@ -147,7 +146,7 @@ export class HomeComponent extends Component<IHomeComponentProps, IHomeComponent
|
|||||||
<NavLink to='/people'><MenuItem primaryText='People' style={{ color: 'rgb(117, 117, 117)' }} leftIcon={<SvgPeople />} /></NavLink>
|
<NavLink to='/people'><MenuItem primaryText='People' style={{ color: 'rgb(117, 117, 117)' }} leftIcon={<SvgPeople />} /></NavLink>
|
||||||
<Divider />
|
<Divider />
|
||||||
<NavLink to='/settings'><MenuItem primaryText='Settings' style={{ color: 'rgb(117, 117, 117)' }} leftIcon={<SvgSettings />} /></NavLink>
|
<NavLink to='/settings'><MenuItem primaryText='Settings' style={{ color: 'rgb(117, 117, 117)' }} leftIcon={<SvgSettings />} /></NavLink>
|
||||||
<NavLink to='#'><MenuItem primaryText='Send feedback' style={{ color: 'rgb(117, 117, 117)' }} leftIcon={<SvgFeedback />} /></NavLink>
|
<MenuItem primaryText='Send feedback' onClick={() => showSendFeedback()} style={{ color: 'rgb(117, 117, 117)' }} leftIcon={<SvgFeedback />} />
|
||||||
</Menu>
|
</Menu>
|
||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
|
|
||||||
@@ -175,6 +174,7 @@ const mapDispatchToProps = (dispatch: any, ownProps: IHomeComponentProps) => {
|
|||||||
dispatch(notifyActions.dbGetNotifications())
|
dispatch(notifyActions.dbGetNotifications())
|
||||||
dispatch(circleActions.dbGetCircles())
|
dispatch(circleActions.dbGetCircles())
|
||||||
dispatch(circleActions.dbGetUserTies())
|
dispatch(circleActions.dbGetUserTies())
|
||||||
|
dispatch(circleActions.dbGetFollowers())
|
||||||
|
|
||||||
},
|
},
|
||||||
clearData: () => {
|
clearData: () => {
|
||||||
@@ -192,7 +192,10 @@ const mapDispatchToProps = (dispatch: any, ownProps: IHomeComponentProps) => {
|
|||||||
defaultDataEnable: () => {
|
defaultDataEnable: () => {
|
||||||
dispatch(globalActions.defaultDataEnable())
|
dispatch(globalActions.defaultDataEnable())
|
||||||
},
|
},
|
||||||
goTo: (url: string) => dispatch(push(url))
|
goTo: (url: string) => dispatch(push(url)),
|
||||||
|
showSendFeedback: () => dispatch(globalActions.showSendFeedback()),
|
||||||
|
hideSendFeedback: () => dispatch(globalActions.hideSendFeedback())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -223,7 +226,7 @@ const mapStateToProps = (state: any, ownProps: IHomeComponentProps) => {
|
|||||||
mergedPosts,
|
mergedPosts,
|
||||||
global,
|
global,
|
||||||
hasMorePosts,
|
hasMorePosts,
|
||||||
loaded: user.loaded && post.loaded && imageGallery.loaded && notify.loaded && circle.loaded
|
loaded: user.loaded && imageGallery.loaded && notify.loaded && circle.loaded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,4 +98,14 @@ export interface IHomeComponentProps {
|
|||||||
*/
|
*/
|
||||||
loaded?: boolean
|
loaded?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show send feedback form
|
||||||
|
*/
|
||||||
|
showSendFeedback: () => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide send feedback form
|
||||||
|
*/
|
||||||
|
hideSendFeedback: () => any
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { User } from 'core/domain/users';
|
import { User } from 'core/domain/users'
|
||||||
export interface IMasterComponentProps {
|
export interface IMasterComponentProps {
|
||||||
/**
|
/**
|
||||||
* Close gloal message
|
* Close gloal message
|
||||||
@@ -98,4 +98,15 @@ export interface IMasterComponentProps {
|
|||||||
* @memberof IMasterProps
|
* @memberof IMasterProps
|
||||||
*/
|
*/
|
||||||
uid: string
|
uid: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show master loading
|
||||||
|
*/
|
||||||
|
showMasterLoading?: () => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide master loading
|
||||||
|
*/
|
||||||
|
hideMasterLoading?: () => any
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import LinearProgress from 'material-ui/LinearProgress'
|
|||||||
// - Import components
|
// - Import components
|
||||||
|
|
||||||
import MasterLoading from 'components/masterLoading'
|
import MasterLoading from 'components/masterLoading'
|
||||||
|
import SendFeedback from 'components/sendFeedback'
|
||||||
import MasterRouter from 'routes/MasterRouter'
|
import MasterRouter from 'routes/MasterRouter'
|
||||||
import { IMasterComponentProps } from './IMasterComponentProps'
|
import { IMasterComponentProps } from './IMasterComponentProps'
|
||||||
import { IMasterComponentState } from './IMasterComponentState'
|
import { IMasterComponentState } from './IMasterComponentState'
|
||||||
@@ -79,9 +80,20 @@ export class MasterComponent extends Component<IMasterComponentProps, IMasterCom
|
|||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
|
|
||||||
this._authourizeService.onAuthStateChanged((isVerifide: boolean, user: any) => {
|
this._authourizeService.onAuthStateChanged((isVerifide: boolean, user: any) => {
|
||||||
const {global, clearData, loadDataGuest, defaultDataDisable, defaultDataEnable, login, logout } = this.props
|
const {
|
||||||
|
global,
|
||||||
|
clearData,
|
||||||
|
loadDataGuest,
|
||||||
|
defaultDataDisable,
|
||||||
|
defaultDataEnable,
|
||||||
|
login,
|
||||||
|
logout,
|
||||||
|
showMasterLoading,
|
||||||
|
hideMasterLoading
|
||||||
|
} = this.props
|
||||||
if (user) {
|
if (user) {
|
||||||
login(user.uid,isVerifide)
|
login(user.uid,isVerifide)
|
||||||
|
hideMasterLoading!()
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
isVerifide: true
|
isVerifide: true
|
||||||
@@ -89,6 +101,7 @@ export class MasterComponent extends Component<IMasterComponentProps, IMasterCom
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
logout()
|
logout()
|
||||||
|
hideMasterLoading!()
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
isVerifide: false
|
isVerifide: false
|
||||||
@@ -117,14 +130,14 @@ export class MasterComponent extends Component<IMasterComponentProps, IMasterCom
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div id='master'>
|
<div id='master'>
|
||||||
|
<SendFeedback />
|
||||||
<div className='master__progress' style={{ display: (progress.visible ? 'block' : 'none') }}>
|
<div className='master__progress' style={{ display: (progress.visible ? 'block' : 'none') }}>
|
||||||
<LinearProgress mode='determinate' value={progress.percent} />
|
<LinearProgress mode='determinate' value={progress.percent} />
|
||||||
</div>
|
</div>
|
||||||
<div className='master__loading animate-fading2' style={{ display: (global.showTopLoading ? 'flex' : 'none') }}>
|
<div className='master__loading animate-fading2' style={{ display: (global.showTopLoading ? 'flex' : 'none') }}>
|
||||||
<div className='title'>Loading ... </div>
|
<div className='title'>Loading ... </div>
|
||||||
</div>
|
</div>
|
||||||
<MasterLoading activeLoading={loading} handleLoading={this.handleLoading} />
|
<MasterLoading activeLoading={global.showMasterLoading} handleLoading={this.handleLoading} />
|
||||||
<MasterRouter enabled={!loading} data={{uid}} />
|
<MasterRouter enabled={!loading} data={{uid}} />
|
||||||
<Snackbar
|
<Snackbar
|
||||||
open={this.props.global.messageOpen}
|
open={this.props.global.messageOpen}
|
||||||
@@ -170,7 +183,9 @@ const mapDispatchToProps = (dispatch: any, ownProps: IMasterComponentProps) => {
|
|||||||
},
|
},
|
||||||
loadDataGuest: () => {
|
loadDataGuest: () => {
|
||||||
dispatch(globalActions.loadDataGuest())
|
dispatch(globalActions.loadDataGuest())
|
||||||
}
|
},
|
||||||
|
showMasterLoading: () => dispatch(globalActions.showMasterLoading()),
|
||||||
|
hideMasterLoading: () => dispatch(globalActions.hideMasterLoading())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import CircularProgress from 'material-ui/CircularProgress'
|
import CircularProgress from 'material-ui/CircularProgress'
|
||||||
import Dialog from 'material-ui/Dialog'
|
import Dialog from 'material-ui/Dialog'
|
||||||
|
import RefreshIndicator from 'material-ui/RefreshIndicator'
|
||||||
import { IMasterLoadingComponentProps } from './IMasterLoadingComponentProps'
|
import { IMasterLoadingComponentProps } from './IMasterLoadingComponentProps'
|
||||||
import { IMasterLoadingComponentState } from './IMasterLoadingComponentState'
|
import { IMasterLoadingComponentState } from './IMasterLoadingComponentState'
|
||||||
|
|
||||||
// - Import app components
|
// - Import app components
|
||||||
|
|
||||||
// - Create MasterLoading component class
|
// - Create MasterLoading component class
|
||||||
export default class MasterLoadingComponent extends Component<IMasterLoadingComponentProps,IMasterLoadingComponentState> {
|
export default class MasterLoadingComponent extends Component<IMasterLoadingComponentProps, IMasterLoadingComponentState> {
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
constructor (props: IMasterLoadingComponentProps) {
|
constructor (props: IMasterLoadingComponentProps) {
|
||||||
@@ -19,27 +20,19 @@ export default class MasterLoadingComponent extends Component<IMasterLoadingComp
|
|||||||
|
|
||||||
// Render app DOM component
|
// Render app DOM component
|
||||||
render () {
|
render () {
|
||||||
|
const {activeLoading} = this.props
|
||||||
return (
|
return (
|
||||||
<Dialog
|
|
||||||
modal={true}
|
|
||||||
open={this.props.activeLoading}
|
|
||||||
autoDetectWindowHeight={false}
|
|
||||||
overlayStyle={{backgroundColor: 'white'}}
|
|
||||||
contentClassName='mLoading__content'
|
|
||||||
bodyStyle={{backgroundColor: ''}}
|
|
||||||
bodyClassName='mLoading__body'
|
|
||||||
>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div className='mLoading__context'>
|
|
||||||
|
|
||||||
<CircularProgress color='white' size={80} thickness={7} />
|
|
||||||
<h1 style={{float: 'right', color: '#fff'}}>Green</h1>
|
|
||||||
|
|
||||||
|
<div className='mLoading__loading' style={{ display: (activeLoading ? 'flex' : 'none') }}>
|
||||||
|
<RefreshIndicator
|
||||||
|
size={50}
|
||||||
|
left={70}
|
||||||
|
top={0}
|
||||||
|
status='loading'
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/components/sendFeedback/ISendFeedbackComponentProps.ts
Normal file
30
src/components/sendFeedback/ISendFeedbackComponentProps.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { Feed } from 'core/domain/common/feed'
|
||||||
|
import { ServerRequestModel } from 'models/server/serverRequestModel'
|
||||||
|
import { Profile } from 'core/domain/users'
|
||||||
|
|
||||||
|
export interface ISendFeedbackComponentProps {
|
||||||
|
/**
|
||||||
|
* Whether send feedback is diplayed
|
||||||
|
*/
|
||||||
|
sendFeedbackStatus?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send feedback
|
||||||
|
*/
|
||||||
|
sendFeed?: (feed: Feed) => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide feedback form
|
||||||
|
*/
|
||||||
|
hideFeedback: () => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server request of send feedback
|
||||||
|
*/
|
||||||
|
sendFeedbackRequest: ServerRequestModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current user profile
|
||||||
|
*/
|
||||||
|
currentUser: Profile
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
export interface ISendFeedbackComponentState {
|
||||||
|
/**
|
||||||
|
* Feedback text
|
||||||
|
*/
|
||||||
|
feedText: string
|
||||||
|
}
|
||||||
232
src/components/sendFeedback/SendFeedbackComponent.tsx
Normal file
232
src/components/sendFeedback/SendFeedbackComponent.tsx
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
// - Import react components
|
||||||
|
import React, { Component } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import Paper from 'material-ui/Paper'
|
||||||
|
import TextField from 'material-ui/TextField'
|
||||||
|
import IconButton from 'material-ui/IconButton'
|
||||||
|
import SvgHappy from 'material-ui/svg-icons/image/tag-faces'
|
||||||
|
import SvgSad from 'material-ui/svg-icons/action/face'
|
||||||
|
import SvgClose from 'material-ui/svg-icons/content/clear'
|
||||||
|
import RefreshIndicator from 'material-ui/RefreshIndicator'
|
||||||
|
|
||||||
|
// - Import app components
|
||||||
|
|
||||||
|
// - Import API
|
||||||
|
|
||||||
|
// - Import actions
|
||||||
|
import { globalActions } from 'actions'
|
||||||
|
|
||||||
|
import { Feed } from 'core/domain/common'
|
||||||
|
import { ISendFeedbackComponentProps } from './ISendFeedbackComponentProps'
|
||||||
|
import { ISendFeedbackComponentState } from './ISendFeedbackComponentState'
|
||||||
|
import { FeedType } from 'core/domain/common/feedType'
|
||||||
|
import { ServerRequestModel } from 'models/server'
|
||||||
|
import { Profile } from 'core/domain/users'
|
||||||
|
import StringAPI from 'api/StringAPI'
|
||||||
|
import { ServerRequestType } from 'constants/serverRequestType'
|
||||||
|
import { User } from 'core/domain/users'
|
||||||
|
import { ServerRequestStatusType } from 'actions/serverRequestStatusType'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create component class
|
||||||
|
*/
|
||||||
|
export class SendFeedbackComponent extends Component<ISendFeedbackComponentProps, ISendFeedbackComponentState> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component constructor
|
||||||
|
* @param {object} props is an object properties of component
|
||||||
|
*/
|
||||||
|
constructor(props: ISendFeedbackComponentProps) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
// Defaul state
|
||||||
|
this.state = {
|
||||||
|
feedText: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// Binding functions to `this`
|
||||||
|
this.handleFeedText = this.handleFeedText.bind(this)
|
||||||
|
this.getFeedbackForm = this.getFeedbackForm.bind(this)
|
||||||
|
this.mainForm = this.mainForm.bind(this)
|
||||||
|
this.loadingForm = this.loadingForm.bind(this)
|
||||||
|
this.successForm = this.successForm.bind(this)
|
||||||
|
this.errorForm = this.errorForm.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFeedText = (event: any) => {
|
||||||
|
const target = event ? event.target : {}
|
||||||
|
const value = target ? target.value : ''
|
||||||
|
if (value) {
|
||||||
|
this.setState({
|
||||||
|
feedText: value
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSendFeed = (feedType: FeedType) => {
|
||||||
|
const { sendFeed, currentUser } = this.props
|
||||||
|
const { feedText } = this.state
|
||||||
|
sendFeed!(new Feed('', feedText, feedType, currentUser))
|
||||||
|
}
|
||||||
|
|
||||||
|
mainForm = () => {
|
||||||
|
const { sendFeedbackStatus, hideFeedback, sendFeed, sendFeedbackRequest } = this.props
|
||||||
|
const { feedText } = this.state
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TextField
|
||||||
|
hintText='What do you feel?'
|
||||||
|
multiLine={true}
|
||||||
|
onChange={this.handleFeedText}
|
||||||
|
rows={2}
|
||||||
|
rowsMax={4}
|
||||||
|
/><br />
|
||||||
|
<div className='buttons'>
|
||||||
|
<IconButton
|
||||||
|
tooltip='sad'
|
||||||
|
iconClassName='flaticon-sad-2 icon__svg'
|
||||||
|
tooltipPosition='bottom-left'
|
||||||
|
onClick={() => this.handleSendFeed(FeedType.Sad)}
|
||||||
|
>
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
tooltip='acceptable'
|
||||||
|
iconClassName='flaticon-neutral icon__svg'
|
||||||
|
tooltipPosition='bottom-left'
|
||||||
|
onClick={() => this.handleSendFeed(FeedType.Acceptable)}
|
||||||
|
>
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
tooltip='happy'
|
||||||
|
iconClassName='flaticon-happy-2 icon__svg'
|
||||||
|
tooltipPosition='bottom-left'
|
||||||
|
onClick={() => this.handleSendFeed(FeedType.Happy)}
|
||||||
|
>
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
tooltip='awesome'
|
||||||
|
iconClassName='flaticon-happy icon__svg'
|
||||||
|
tooltipPosition='bottom-left'
|
||||||
|
onClick={() => this.handleSendFeed(FeedType.Awesome)}
|
||||||
|
>
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div >)
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingForm = () => {
|
||||||
|
return (<div className='loading'>
|
||||||
|
<p>
|
||||||
|
Your feedback is sending!
|
||||||
|
</p>
|
||||||
|
<div className='icon'>
|
||||||
|
<RefreshIndicator
|
||||||
|
size={50}
|
||||||
|
left={70}
|
||||||
|
top={0}
|
||||||
|
status='loading'
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
successForm = () => {
|
||||||
|
return (<div className='success'>We appreciate your kind support as always ;)</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
errorForm = () => {
|
||||||
|
return (<div className='error'>Error in sending feedback :(</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
getFeedbackForm = () => {
|
||||||
|
const { sendFeedbackStatus, hideFeedback, sendFeed, sendFeedbackRequest } = this.props
|
||||||
|
const { feedText } = this.state
|
||||||
|
|
||||||
|
if (sendFeedbackRequest) {
|
||||||
|
switch (sendFeedbackRequest.status) {
|
||||||
|
case ServerRequestStatusType.Sent:
|
||||||
|
return this.loadingForm()
|
||||||
|
|
||||||
|
case ServerRequestStatusType.OK:
|
||||||
|
return this.successForm()
|
||||||
|
|
||||||
|
case ServerRequestStatusType.Error:
|
||||||
|
return this.errorForm()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return this.mainForm()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this.mainForm()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reneder component DOM
|
||||||
|
* @return {react element} return the DOM which rendered by component
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { sendFeedbackStatus, hideFeedback, sendFeed, sendFeedbackRequest } = this.props
|
||||||
|
const { feedText } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='sendFeedback__content animate__up' style={{ display: (sendFeedbackStatus ? 'block' : 'none') }}>
|
||||||
|
<Paper className='paper' >
|
||||||
|
<div className='close'>
|
||||||
|
<IconButton
|
||||||
|
tooltip='cancel'
|
||||||
|
tooltipPosition='bottom-left'
|
||||||
|
onClick={() => hideFeedback()}
|
||||||
|
>
|
||||||
|
<SvgClose />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
{this.getFeedbackForm()}
|
||||||
|
|
||||||
|
</Paper>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map dispatch to props
|
||||||
|
* @param {func} dispatch is the function to dispatch action to reducers
|
||||||
|
* @param {object} ownProps is the props belong to component
|
||||||
|
* @return {object} props of component
|
||||||
|
*/
|
||||||
|
const mapDispatchToProps = (dispatch: Function, ownProps: ISendFeedbackComponentProps) => {
|
||||||
|
return {
|
||||||
|
sendFeed: (feed: Feed) => (dispatch(globalActions.dbSendFeed(feed))),
|
||||||
|
hideFeedback: () => dispatch(globalActions.hideSendFeedback())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map state to props
|
||||||
|
* @param {object} state is the obeject from redux store
|
||||||
|
* @param {object} ownProps is the props belong to component
|
||||||
|
* @return {object} props of component
|
||||||
|
*/
|
||||||
|
const mapStateToProps = (state: any, ownProps: ISendFeedbackComponentProps) => {
|
||||||
|
|
||||||
|
const { server, global, authorize, user } = state
|
||||||
|
const { request } = server
|
||||||
|
const { uid } = authorize
|
||||||
|
const currentUser: User = user.info && user.info[uid] ? { ...user.info[uid], userId: uid } : {}
|
||||||
|
const { sendFeedbackStatus } = global
|
||||||
|
const sendFeedbackRequest: ServerRequestModel = request ? request[StringAPI.createServerRequestId(ServerRequestType.CommonSendFeedback, uid)] : null
|
||||||
|
|
||||||
|
return {
|
||||||
|
sendFeedbackStatus,
|
||||||
|
sendFeedbackRequest,
|
||||||
|
currentUser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Connect component to redux store
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(SendFeedbackComponent as any)
|
||||||
2
src/components/sendFeedback/index.ts
Normal file
2
src/components/sendFeedback/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import SendFeedbackComponent from './SendFeedbackComponent'
|
||||||
|
export default SendFeedbackComponent
|
||||||
@@ -281,4 +281,4 @@ const mapStateToProps = (state: any,ownProps: ISignupComponentProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// - Connect component to redux store
|
// - Connect component to redux store
|
||||||
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(SignupComponent as any))
|
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(SignupComponent as any) as any)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { User } from 'core/domain/users'
|
import { User } from 'core/domain/users'
|
||||||
import { Circle } from 'core/domain/circles/circle'
|
import { Circle } from 'core/domain/circles/circle'
|
||||||
import { UserTie } from 'core/domain/circles'
|
import { UserTie } from 'core/domain/circles'
|
||||||
|
import { ServerRequestStatusType } from 'actions/serverRequestStatusType'
|
||||||
|
import { ServerRequestModel } from 'models/server/serverRequestModel'
|
||||||
|
|
||||||
export interface IUserBoxComponentProps {
|
export interface IUserBoxComponentProps {
|
||||||
|
|
||||||
@@ -73,6 +75,11 @@ export interface IUserBoxComponentProps {
|
|||||||
*/
|
*/
|
||||||
fullName?: string
|
fullName?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `Following` circle identifier of current user
|
||||||
|
*/
|
||||||
|
followingCircleId?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a circle
|
* Create a circle
|
||||||
*
|
*
|
||||||
@@ -85,14 +92,37 @@ export interface IUserBoxComponentProps {
|
|||||||
*
|
*
|
||||||
* @memberof IUserBoxComponentProps
|
* @memberof IUserBoxComponentProps
|
||||||
*/
|
*/
|
||||||
addFollowingUser?: (cid: string,user: UserTie) => any
|
addUserToCircle?: (circleIds: string[],user: UserTie) => any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete
|
* Add referer user to the `Following` circle of current user
|
||||||
*
|
|
||||||
* @memberof IUserBoxComponentProps
|
|
||||||
*/
|
*/
|
||||||
deleteFollowingUser?: (cid: string ,followingId: string) => any
|
followUser?: (circleId: string, userFollowing: UserTie) => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete following user
|
||||||
|
*/
|
||||||
|
deleteFollowingUser?: (followingId: string) => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set current user selected circles for referer user
|
||||||
|
*/
|
||||||
|
setSelectedCircles?: (userId: string, circleList: string[]) => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove current user selected circles for referer user
|
||||||
|
*/
|
||||||
|
removeSelectedCircles?: (userId: string, circleList: string[]) => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open select circle box
|
||||||
|
*/
|
||||||
|
openSelectCircles?: (userId: string) => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close select circle box
|
||||||
|
*/
|
||||||
|
closeSelectCircles?: (userId: string) => any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect page to [url]
|
* Redirect page to [url]
|
||||||
@@ -100,4 +130,29 @@ export interface IUserBoxComponentProps {
|
|||||||
* @memberof IUserBoxComponentProps
|
* @memberof IUserBoxComponentProps
|
||||||
*/
|
*/
|
||||||
goTo?: (url: string) => any
|
goTo?: (url: string) => any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of following user server request
|
||||||
|
*/
|
||||||
|
followRequest?: ServerRequestModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of add to circle user server request
|
||||||
|
*/
|
||||||
|
addToCircleRequest?: ServerRequestModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of deleting following user server request
|
||||||
|
*/
|
||||||
|
deleteFollowingUserRequest?: ServerRequestModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep selected circles for refere user
|
||||||
|
*/
|
||||||
|
selectedCircles?: string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the select circles box for referer user is open
|
||||||
|
*/
|
||||||
|
isSelecteCirclesOpen?: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,22 +33,10 @@ export interface IUserBoxComponentState {
|
|||||||
*/
|
*/
|
||||||
anchorEl?: any
|
anchorEl?: any
|
||||||
|
|
||||||
/**
|
|
||||||
* Circle list popover is open {true} or not {false}
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
* @memberof IUserBoxComponentState
|
|
||||||
*/
|
|
||||||
open: boolean
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether current user changed the selected circles for referer user
|
* Whether current user changed the selected circles for referer user
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
disabledDoneCircles: boolean
|
disabledDoneCircles: boolean
|
||||||
|
|
||||||
/**
|
|
||||||
* Keep selected circles for refere user
|
|
||||||
*/
|
|
||||||
selectedCircles: string[]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// - Import react components
|
// - Import react components
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
|
import moment from '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'
|
||||||
@@ -20,7 +21,6 @@ import { grey400, grey800, darkBlack, lightBlack } from 'material-ui/styles/colo
|
|||||||
import UserAvatar from 'components/userAvatar'
|
import UserAvatar from 'components/userAvatar'
|
||||||
|
|
||||||
// - Import API
|
// - Import API
|
||||||
import CircleAPI from 'api/CircleAPI'
|
|
||||||
import StringAPI from 'api/StringAPI'
|
import StringAPI from 'api/StringAPI'
|
||||||
|
|
||||||
// - Import actions
|
// - Import actions
|
||||||
@@ -31,12 +31,16 @@ import { IUserBoxComponentState } from './IUserBoxComponentState'
|
|||||||
import { User } from 'core/domain/users'
|
import { User } from 'core/domain/users'
|
||||||
import { UserTie, Circle } from 'core/domain/circles'
|
import { UserTie, Circle } from 'core/domain/circles'
|
||||||
import { ServerRequestType } from 'constants/serverRequestType'
|
import { ServerRequestType } from 'constants/serverRequestType'
|
||||||
|
import { ServerRequestStatusType } from 'actions/serverRequestStatusType'
|
||||||
|
import { ServerRequestModel } from 'models/server'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create component class
|
* Create component class
|
||||||
*/
|
*/
|
||||||
export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBoxComponentState> {
|
export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBoxComponentState> {
|
||||||
|
/**
|
||||||
|
* Fields
|
||||||
|
*/
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
/**
|
/**
|
||||||
* User identifier
|
* User identifier
|
||||||
@@ -69,6 +73,7 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
borderRadius: '4px'
|
borderRadius: '4px'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
selectedCircles: string[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component constructor
|
* Component constructor
|
||||||
@@ -76,17 +81,13 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
*/
|
*/
|
||||||
constructor (props: IUserBoxComponentProps) {
|
constructor (props: IUserBoxComponentProps) {
|
||||||
super(props)
|
super(props)
|
||||||
const { userBelongCircles, circles } = this.props
|
const { userBelongCircles, circles,userId } = this.props
|
||||||
// Defaul state
|
// Defaul state
|
||||||
this.state = {
|
this.state = {
|
||||||
/**
|
|
||||||
* It will be true if user follow popover is open
|
|
||||||
*/
|
|
||||||
open: false,
|
|
||||||
/**
|
/**
|
||||||
* The value of circle input
|
* The value of circle input
|
||||||
*/
|
*/
|
||||||
circleName: '',
|
circleName: ``,
|
||||||
/**
|
/**
|
||||||
* It will be true if the text field for adding group is empty
|
* It will be true if the text field for adding group is empty
|
||||||
*/
|
*/
|
||||||
@@ -95,34 +96,52 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
* The button of add user in a circle is disabled {true} or not {false}
|
* The button of add user in a circle is disabled {true} or not {false}
|
||||||
*/
|
*/
|
||||||
disabledAddToCircle: true,
|
disabledAddToCircle: true,
|
||||||
/**
|
|
||||||
* Keep selected circles for refere user
|
|
||||||
*/
|
|
||||||
selectedCircles: userBelongCircles ? userBelongCircles!.slice() : [],
|
|
||||||
/**
|
/**
|
||||||
* Whether current user changed the selected circles for referer user
|
* Whether current user changed the selected circles for referer user
|
||||||
*/
|
*/
|
||||||
disabledDoneCircles: true
|
disabledDoneCircles: true
|
||||||
}
|
}
|
||||||
|
this.selectedCircles = userBelongCircles!.slice()
|
||||||
// Binding functions to `this`
|
// Binding functions to `this`
|
||||||
this.handleChangeName = this.handleChangeName.bind(this)
|
this.handleChangeName = this.handleChangeName.bind(this)
|
||||||
this.onCreateCircle = this.onCreateCircle.bind(this)
|
this.onCreateCircle = this.onCreateCircle.bind(this)
|
||||||
this.handleFollowUser = this.handleFollowUser.bind(this)
|
this.handleDoneAddCircle = this.handleDoneAddCircle.bind(this)
|
||||||
this.handleFollowUser = this.handleFollowUser.bind(this)
|
this.circleList = this.circleList.bind(this)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle follow user
|
* Handle follow user
|
||||||
*/
|
*/
|
||||||
handleFollowUser = (checked: boolean, cid: string) => {
|
handleDoneAddCircle = () => {
|
||||||
const { userId, user } = this.props
|
const { userId, user , addUserToCircle, selectedCircles, deleteFollowingUser} = this.props
|
||||||
const { avatar, fullName } = user
|
const { avatar, fullName } = user
|
||||||
if (checked) {
|
const {disabledDoneCircles} = this.state
|
||||||
this.props.addFollowingUser!(cid, { avatar, userId, fullName })
|
if (!disabledDoneCircles) {
|
||||||
|
if (selectedCircles!.length > 0) {
|
||||||
|
addUserToCircle!(selectedCircles!, { avatar, userId, fullName })
|
||||||
|
} else {
|
||||||
|
deleteFollowingUser!(userId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle follow user
|
||||||
|
*/
|
||||||
|
onFollowUser = (event: any) => {
|
||||||
|
// This prevents ghost click
|
||||||
|
event.preventDefault()
|
||||||
|
const {isFollowed, followUser, followingCircleId, userId, user, followRequest } = this.props
|
||||||
|
|
||||||
|
if (followRequest && followRequest.status === ServerRequestStatusType.Sent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { avatar, fullName } = user
|
||||||
|
if (!isFollowed) {
|
||||||
|
followUser!(followingCircleId!, { avatar, userId, fullName })
|
||||||
} else {
|
} else {
|
||||||
this.props.deleteFollowingUser!(cid, userId)
|
this.onRequestOpenAddCircle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +149,14 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
* Handle request close for add circle box
|
* Handle request close for add circle box
|
||||||
*/
|
*/
|
||||||
onRequestCloseAddCircle = () => {
|
onRequestCloseAddCircle = () => {
|
||||||
|
const {setSelectedCircles, userId, userBelongCircles, closeSelectCircles} = this.props
|
||||||
|
setSelectedCircles!(userId, userBelongCircles!)
|
||||||
|
closeSelectCircles!(userId)
|
||||||
this.setState({
|
this.setState({
|
||||||
open: false
|
circleName: ``,
|
||||||
|
disabledCreateCircle: true,
|
||||||
|
disabledAddToCircle: true,
|
||||||
|
disabledDoneCircles: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,9 +164,8 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
* Handle request open for add circle box
|
* Handle request open for add circle box
|
||||||
*/
|
*/
|
||||||
onRequestOpenAddCircle = () => {
|
onRequestOpenAddCircle = () => {
|
||||||
this.setState({
|
const { openSelectCircles, userId} = this.props
|
||||||
open: true
|
openSelectCircles!(userId)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,54 +194,40 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleSelectCircle = (event: object, isInputChecked: boolean, circleId: string) => {
|
handleSelectCircle = (event: object, isInputChecked: boolean, circleId: string) => {
|
||||||
const { userBelongCircles, circles } = this.props
|
const { userBelongCircles, circles, setSelectedCircles, selectedCircles, userId } = this.props
|
||||||
let selectedCircles = this.state.selectedCircles
|
let newSelectedCircles = selectedCircles!.slice()
|
||||||
if (isInputChecked) {
|
if (isInputChecked) {
|
||||||
selectedCircles = [
|
|
||||||
...selectedCircles,
|
newSelectedCircles = [
|
||||||
|
...selectedCircles!,
|
||||||
circleId
|
circleId
|
||||||
]
|
]
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const circleIndex = selectedCircles.indexOf(circleId)
|
const circleIndex = selectedCircles!.indexOf(circleId)
|
||||||
selectedCircles.splice(circleIndex, 1)
|
newSelectedCircles.splice(circleIndex, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSelectedCircles!(userId, newSelectedCircles)
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedCircles: selectedCircles,
|
disabledDoneCircles: !this.selectedCircleChange(newSelectedCircles)
|
||||||
disabledDoneCircles: !this.selectedCircleChange(selectedCircles)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle follow user
|
|
||||||
*/
|
|
||||||
onFollowUser = (event: any) => {
|
|
||||||
// This prevents ghost click
|
|
||||||
event.preventDefault()
|
|
||||||
this.onRequestOpenAddCircle()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add user to the circle/circles
|
|
||||||
*/
|
|
||||||
onAddToCircle = () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a circle list of user which belong to
|
* Create a circle list of user which belong to
|
||||||
*/
|
*/
|
||||||
circleList = () => {
|
circleList = () => {
|
||||||
let { circles, userId, userBelongCircles } = this.props
|
let { circles, userId, userBelongCircles, selectedCircles } = this.props
|
||||||
|
|
||||||
if (circles) {
|
if (circles) {
|
||||||
|
|
||||||
return Object.keys(circles).map((circleId, index) => {
|
const parsedDate = Object.keys(circles).map((circleId, index) => {
|
||||||
const {selectedCircles} = this.state
|
let isBelong = selectedCircles ? selectedCircles!.indexOf(circleId) > -1 : false
|
||||||
let isBelong = selectedCircles!.indexOf(circleId) > -1
|
|
||||||
// Create checkbox for selected/unselected circle
|
// Create checkbox for selected/unselected circle
|
||||||
return <Checkbox
|
return <Checkbox
|
||||||
key={circleId}
|
key={`${circleId}-${userId}`}
|
||||||
style={{ padding: '10px' }}
|
style={{ padding: '10px' }}
|
||||||
label={circles![circleId].name}
|
label={circles![circleId].name}
|
||||||
labelStyle={{
|
labelStyle={{
|
||||||
@@ -230,6 +240,8 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
checked={isBelong}
|
checked={isBelong}
|
||||||
/>
|
/>
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return parsedDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,6 +272,7 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
*/
|
*/
|
||||||
render () {
|
render () {
|
||||||
const {disabledDoneCircles} = this.state
|
const {disabledDoneCircles} = this.state
|
||||||
|
const { isFollowed, followRequest, userId, isSelecteCirclesOpen, addToCircleRequest, deleteFollowingUserRequest } = this.props
|
||||||
const writeActions = [
|
const writeActions = [
|
||||||
<FlatButton
|
<FlatButton
|
||||||
label='Cancel'
|
label='Cancel'
|
||||||
@@ -272,15 +285,14 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
label='Done'
|
label='Done'
|
||||||
primary={true}
|
primary={true}
|
||||||
keyboardFocused={false}
|
keyboardFocused={false}
|
||||||
disabled={disabledDoneCircles}
|
disabled={disabledDoneCircles || (addToCircleRequest ? addToCircleRequest!.status === ServerRequestStatusType.Sent : false)}
|
||||||
onTouchTap={this.onCreateCircle}
|
onTouchTap={this.handleDoneAddCircle}
|
||||||
/>
|
/>
|
||||||
]
|
]
|
||||||
|
|
||||||
const { isFollowed } = this.props
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper style={this.styles.paper} zDepth={1} className='grid-cell'>
|
<Paper key={userId} style={this.styles.paper} zDepth={1} className='grid-cell'>
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
@@ -309,6 +321,10 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
: (this.props.belongCirclesCount! > 1 ? `${this.props.belongCirclesCount} Circles` : ((this.props.firstBelongCircle) ? this.props.firstBelongCircle.name : 'Follow'))}
|
: (this.props.belongCirclesCount! > 1 ? `${this.props.belongCirclesCount} Circles` : ((this.props.firstBelongCircle) ? this.props.firstBelongCircle.name : 'Follow'))}
|
||||||
primary={true}
|
primary={true}
|
||||||
onTouchTap={this.onFollowUser}
|
onTouchTap={this.onFollowUser}
|
||||||
|
disabled={
|
||||||
|
(followRequest ? followRequest.status === ServerRequestStatusType.Sent : false) ||
|
||||||
|
(deleteFollowingUserRequest ? deleteFollowingUserRequest.status === ServerRequestStatusType.Sent : false)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -316,7 +332,7 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
key={this.props.userId || 0}
|
key={this.props.userId || 0}
|
||||||
actions={writeActions}
|
actions={writeActions}
|
||||||
modal={false}
|
modal={false}
|
||||||
open={this.state.open}
|
open={isSelecteCirclesOpen === true}
|
||||||
contentStyle={this.styles.dialog}
|
contentStyle={this.styles.dialog}
|
||||||
onRequestClose={this.onRequestCloseAddCircle}
|
onRequestClose={this.onRequestCloseAddCircle}
|
||||||
overlayStyle={{ background: 'rgba(0,0,0,0.12)' }}
|
overlayStyle={{ background: 'rgba(0,0,0,0.12)' }}
|
||||||
@@ -363,8 +379,13 @@ export class UserBoxComponent extends Component<IUserBoxComponentProps, IUserBox
|
|||||||
const mapDispatchToProps = (dispatch: Function, ownProps: IUserBoxComponentProps) => {
|
const mapDispatchToProps = (dispatch: Function, ownProps: IUserBoxComponentProps) => {
|
||||||
return {
|
return {
|
||||||
createCircle: (name: string) => dispatch(circleActions.dbAddCircle(name)),
|
createCircle: (name: string) => dispatch(circleActions.dbAddCircle(name)),
|
||||||
addFollowingUser: (circleIds: string[], user: UserTie) => dispatch(circleActions.dbUpdateUserInCircles(circleIds, user)),
|
addUserToCircle: (circleIds: string[], user: UserTie) => dispatch(circleActions.dbUpdateUserInCircles(circleIds, user)),
|
||||||
deleteFollowingUser: (cid: string, followingId: string) => dispatch(circleActions.dbDeleteFollowingUser(followingId)),
|
followUser: (circleId: string, userFollowing: UserTie) => dispatch(circleActions.dbFollowUser(circleId, userFollowing)),
|
||||||
|
deleteFollowingUser: (followingId: string) => dispatch(circleActions.dbDeleteFollowingUser(followingId)),
|
||||||
|
setSelectedCircles: (userId: string, circleList: string[]) => dispatch(circleActions.setSelectedCircles(userId, circleList)),
|
||||||
|
removeSelectedCircles: (userId: string, circleList: string[]) => dispatch(circleActions.removeSelectedCircles(userId)),
|
||||||
|
openSelectCircles: (userId: string) => dispatch(circleActions.openSelectCircleBox(userId)),
|
||||||
|
closeSelectCircles: (userId: string) => dispatch(circleActions.closeSelectCircleBox(userId)),
|
||||||
goTo: (url: string) => dispatch(push(url))
|
goTo: (url: string) => dispatch(push(url))
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -381,13 +402,26 @@ const mapStateToProps = (state: any, ownProps: IUserBoxComponentProps) => {
|
|||||||
const { circle, authorize, server } = state
|
const { circle, authorize, server } = state
|
||||||
const { uid } = authorize
|
const { uid } = authorize
|
||||||
const { request } = server
|
const { request } = server
|
||||||
|
|
||||||
const circles: { [circleId: string]: Circle } = circle ? (circle.circleList || {}) : {}
|
const circles: { [circleId: string]: Circle } = circle ? (circle.circleList || {}) : {}
|
||||||
const userBelongCircles = circle ? (circle.userTies[ownProps.userId] ? circle.userTies[ownProps.userId].circleIdList : []) : []
|
const userBelongCircles = circle ? (circle.userTies[ownProps.userId] ? circle.userTies[ownProps.userId].circleIdList : []) : []
|
||||||
const isFollowed = userBelongCircles.length > 0
|
const isFollowed = userBelongCircles.length > 0
|
||||||
|
const followingCircleId = circles ? Object.keys(circles)
|
||||||
|
.filter((circleId) => circles[circleId].isSystem && circles[circleId].name === `Following`)[0] : ''
|
||||||
|
const followRequest: ServerRequestModel = request ? request[StringAPI.createServerRequestId(ServerRequestType.CircleFollowUser, ownProps.userId)] : null
|
||||||
|
const addToCircleRequest: ServerRequestModel = request ? request[StringAPI.createServerRequestId(ServerRequestType.CircleAddToCircle, ownProps.userId)] : null
|
||||||
|
const deleteFollowingUserRequest: ServerRequestModel = request ? request[StringAPI.createServerRequestId(ServerRequestType.CircleDeleteFollowingUser, ownProps.userId)] : null
|
||||||
|
const selectedCircles = circle.selectedCircles ? circle.selectedCircles[ownProps.userId] : []
|
||||||
|
const isSelecteCirclesOpen = circle.openSelecteCircles ? circle.openSelecteCircles[ownProps.userId] : []
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
isSelecteCirclesOpen,
|
||||||
isFollowed,
|
isFollowed,
|
||||||
|
selectedCircles,
|
||||||
circles,
|
circles,
|
||||||
|
followingCircleId,
|
||||||
userBelongCircles,
|
userBelongCircles,
|
||||||
|
followRequest,
|
||||||
belongCirclesCount: userBelongCircles.length || 0,
|
belongCirclesCount: userBelongCircles.length || 0,
|
||||||
firstBelongCircle: userBelongCircles ? (circles ? circles[userBelongCircles[0]] : {}) : {},
|
firstBelongCircle: userBelongCircles ? (circles ? circles[userBelongCircles[0]] : {}) : {},
|
||||||
avatar: state.user.info && state.user.info[ownProps.userId] ? state.user.info[ownProps.userId].avatar || '' : '',
|
avatar: state.user.info && state.user.info[ownProps.userId] ? state.user.info[ownProps.userId].avatar || '' : '',
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ export class YourCirclesComponent extends Component<IYourCirclesComponentProps,I
|
|||||||
|
|
||||||
if (circles) {
|
if (circles) {
|
||||||
Object.keys(circles).map((key, index) => {
|
Object.keys(circles).map((key, index) => {
|
||||||
if (key.trim() !== '-Followers') {
|
|
||||||
parsedCircles.push(<CircleComponent key={key} circle={circles![key]} id={key} uid={uid!} />)
|
parsedCircles.push(<CircleComponent key={key} circle={circles![key]} id={key} uid={uid!} />)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return parsedCircles
|
return parsedCircles
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export enum CircleActionType {
|
|||||||
DELETE_USER_FROM_CIRCLE = 'DELETE_USER_FROM_CIRCLE',
|
DELETE_USER_FROM_CIRCLE = 'DELETE_USER_FROM_CIRCLE',
|
||||||
SHOW_SELECT_CIRCLE_BOX = 'SHOW_SELECT_CIRCLE_BOX',
|
SHOW_SELECT_CIRCLE_BOX = 'SHOW_SELECT_CIRCLE_BOX',
|
||||||
HIDE_SELECT_CIRCLE_BOX = 'HIDE_SELECT_CIRCLE_BOX',
|
HIDE_SELECT_CIRCLE_BOX = 'HIDE_SELECT_CIRCLE_BOX',
|
||||||
|
SET_SELECTED_CIRCLES_USER_BOX_COMPONENT = 'SET_SELECTED_CIRCLES_USER_BOX_COMPONENT',
|
||||||
|
REMOVE_SELECTED_CIRCLES_USER_BOX_COMPONENT = 'REMOVE_SELECTED_CIRCLES_USER_BOX_COMPONENT',
|
||||||
|
OPEN_SELECT_CIRCLES_USER_BOX_COMPONENT = 'OPEN_SELECT_CIRCLES_USER_BOX_COMPONENT',
|
||||||
|
CLOSE_SELECT_CIRCLES_USER_BOX_COMPONENT = 'CLOSE_SELECT_CIRCLES_USER_BOX_COMPONENT',
|
||||||
SHOW_FOLLOWING_USER_LOADING = 'SHOW_FOLLOWING_USER_LOADING',
|
SHOW_FOLLOWING_USER_LOADING = 'SHOW_FOLLOWING_USER_LOADING',
|
||||||
HIDE_FOLLOWING_USER_LOADING = 'HIDE_FOLLOWING_USER_LOADING'
|
HIDE_FOLLOWING_USER_LOADING = 'HIDE_FOLLOWING_USER_LOADING'
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ export enum GlobalActionType {
|
|||||||
SET_HEADER_TITLE = 'SET_HEADER_TITLE',
|
SET_HEADER_TITLE = 'SET_HEADER_TITLE',
|
||||||
SHOW_TOP_LOADING = 'SHOW_TOP_LOADING',
|
SHOW_TOP_LOADING = 'SHOW_TOP_LOADING',
|
||||||
HIDE_TOP_LOADING = 'HIDE_TOP_LOADING',
|
HIDE_TOP_LOADING = 'HIDE_TOP_LOADING',
|
||||||
|
SHOW_MASTER_LOADING = 'SHOW_MASTER_LOADING',
|
||||||
|
HIDE_MASTER_LOADING = 'HIDE_MASTER_LOADING',
|
||||||
|
SHOW_SEND_FEEDBACK = 'SHOW_SEND_FEEDBACK',
|
||||||
|
HIDE_SEND_FEEDBACK = 'HIDE_SEND_FEEDBACK',
|
||||||
TEMP = 'TEMP',
|
TEMP = 'TEMP',
|
||||||
CLEAR_TEMP = 'CLEAR_TEMP',
|
CLEAR_TEMP = 'CLEAR_TEMP',
|
||||||
OPEN_POST_WRITE = 'OPEN_POST_WRITE',
|
OPEN_POST_WRITE = 'OPEN_POST_WRITE',
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
export enum ServerRequestType {
|
export enum ServerRequestType {
|
||||||
CircleAddToCircle = 'CircleAddToCircle',
|
CircleAddToCircle = 'CircleAddToCircle',
|
||||||
CircleFollowUser = 'CircleFollowUser',
|
CircleFollowUser = 'CircleFollowUser',
|
||||||
CircleCreateTieUser = 'CircleCreateTieUser'
|
CircleCreateTieUser = 'CircleCreateTieUser',
|
||||||
|
CircleDeleteFollowingUser = 'CircleDeleteFollowingUser',
|
||||||
|
CommonSendFeedback = 'CommonSendFeedback'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ export class Circle extends BaseDomain {
|
|||||||
public name: string
|
public name: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether circle setting is open
|
* Whether it's configured by system
|
||||||
*/
|
*/
|
||||||
public openCircleSettings?: boolean
|
public isSystem: boolean
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
34
src/core/domain/common/feed.ts
Normal file
34
src/core/domain/common/feed.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { BaseDomain } from 'core/domain/common'
|
||||||
|
import { FeedType } from './feedType'
|
||||||
|
import { User } from 'core/domain/users'
|
||||||
|
|
||||||
|
export class Feed {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
constructor (
|
||||||
|
/**
|
||||||
|
* Feed identifier
|
||||||
|
*/
|
||||||
|
public id?: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feed text
|
||||||
|
*/
|
||||||
|
public text?: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feed type
|
||||||
|
*/
|
||||||
|
public feedType?: FeedType,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user who send the feedback
|
||||||
|
*/
|
||||||
|
public user?: User
|
||||||
|
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
8
src/core/domain/common/feedType.ts
Normal file
8
src/core/domain/common/feedType.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export enum FeedType {
|
||||||
|
Awesome = 'Awesome',
|
||||||
|
Happy = 'Happey',
|
||||||
|
Acceptable = 'Acceptable',
|
||||||
|
Sad = 'Sad',
|
||||||
|
Bug = 'Bug'
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import { SocialError } from './socialError'
|
import { SocialError } from './socialError'
|
||||||
import { BaseDomain } from './baseDomain'
|
import { BaseDomain } from './baseDomain'
|
||||||
|
import { Feed } from './feed'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
SocialError,
|
SocialError,
|
||||||
BaseDomain
|
BaseDomain,
|
||||||
}
|
Feed
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ export interface IUserTieService {
|
|||||||
tieUseres: (userTieSenderInfo: UserTie, userTieReceiveInfo: UserTie, circleIds: string[])
|
tieUseres: (userTieSenderInfo: UserTie, userTieReceiveInfo: UserTie, circleIds: string[])
|
||||||
=> Promise<void>
|
=> Promise<void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update users tie
|
||||||
|
*/
|
||||||
|
updateUsersTie: (userTieSenderInfo: UserTie, userTieReceiveInfo: UserTie, circleIds: string[])
|
||||||
|
=> Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove users' tie
|
* Remove users' tie
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { User } from 'core/domain/users'
|
import { User } from 'core/domain/users'
|
||||||
|
import { Feed } from 'core/domain/common';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common service interface
|
* Common service interface
|
||||||
@@ -8,4 +9,8 @@ import { User } from 'core/domain/users'
|
|||||||
*/
|
*/
|
||||||
export interface ICommonService {
|
export interface ICommonService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post feedback
|
||||||
|
*/
|
||||||
|
addFeed: (feed: Feed) => Promise<string>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,32 @@ export class UserTieService implements IUserTieService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update users tie
|
||||||
|
*/
|
||||||
|
public updateUsersTie: (userTieSenderInfo: UserTie, userTieReceiveInfo: UserTie, circleIds: string[])
|
||||||
|
=> Promise<void> = (userTieSenderInfo, userTieReceiveInfo, circleIds) => {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
|
||||||
|
this._graphService
|
||||||
|
.updateGraph(
|
||||||
|
new Graph(
|
||||||
|
userTieSenderInfo.userId!,
|
||||||
|
'TIE',
|
||||||
|
userTieReceiveInfo.userId!,
|
||||||
|
{...userTieSenderInfo},
|
||||||
|
{...userTieReceiveInfo},
|
||||||
|
{creationDate: Date.now(), circleIds}
|
||||||
|
)
|
||||||
|
,'users'
|
||||||
|
).then(() => {
|
||||||
|
resolve()
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch((error: any) => reject(new SocialError(error.code, 'firestore/updateUsersTie :' + error.message)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove users' tie
|
* Remove users' tie
|
||||||
*/
|
*/
|
||||||
@@ -89,7 +115,7 @@ export class UserTieService implements IUserTieService {
|
|||||||
parsedData = {
|
parsedData = {
|
||||||
...parsedData,
|
...parsedData,
|
||||||
[rightUserInfo.userId!] : {
|
[rightUserInfo.userId!] : {
|
||||||
...node.rightMetadata,
|
...rightUserInfo,
|
||||||
circleIdList: metadata ? metadata.circleIds : []
|
circleIdList: metadata ? metadata.circleIds : []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,7 +149,7 @@ export class UserTieService implements IUserTieService {
|
|||||||
parsedData = {
|
parsedData = {
|
||||||
...parsedData,
|
...parsedData,
|
||||||
[leftUserInfo.userId!] : {
|
[leftUserInfo.userId!] : {
|
||||||
...parsedData[leftUserInfo.userId!],
|
...leftUserInfo,
|
||||||
circleIdList: []
|
circleIdList: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// - Import react components
|
// - Import react components
|
||||||
import { firebaseRef, firebaseAuth } from 'data/firebaseClient'
|
import { firebaseRef, firebaseAuth, db } from 'data/firestoreClient'
|
||||||
|
|
||||||
import { SocialError } from 'core/domain/common'
|
import { SocialError, Feed } from 'core/domain/common'
|
||||||
import { ICommonService } from 'core/services/common'
|
import { ICommonService } from 'core/services/common'
|
||||||
import { injectable } from 'inversify'
|
import { injectable } from 'inversify'
|
||||||
|
|
||||||
@@ -15,4 +15,20 @@ import { injectable } from 'inversify'
|
|||||||
@injectable()
|
@injectable()
|
||||||
export class CommonService implements ICommonService {
|
export class CommonService implements ICommonService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post feedback
|
||||||
|
*/
|
||||||
|
public addFeed: (feed: Feed)
|
||||||
|
=> Promise<string> = (feed) => {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
let feedRef = db.collection(`feeds`).doc()
|
||||||
|
feedRef.set({ ...feed, id: feedRef.id })
|
||||||
|
.then(() => {
|
||||||
|
resolve(feedRef.id)
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
reject(new SocialError(error.code, error.message))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,17 +34,19 @@ export class GraphService implements IGraphService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add graph
|
* Update graph
|
||||||
*/
|
*/
|
||||||
public updateGraph: (graph: Graph, collection: string)
|
public updateGraph: (graph: Graph, collection: string)
|
||||||
=> Promise<string> = (graph, collection) => {
|
=> Promise<string> = (graph, collection) => {
|
||||||
return new Promise<string>((resolve,reject) => {
|
return new Promise<string>((resolve,reject) => {
|
||||||
|
const graphData = this.getGraphs(collection, graph.leftNode, graph.edgeType, graph.rightNode)
|
||||||
let graphRef = db.collection(`graphs:${collection}`).doc()
|
.then((result) => {
|
||||||
.set({...graph}).then((result) => {
|
graph.nodeId = result[0].nodeId
|
||||||
resolve()
|
let graphRef = db.collection(`graphs:${collection}`).doc(result[0].nodeId)
|
||||||
})
|
.set({...graph}).then((result) => {
|
||||||
.catch((error: any) => {
|
resolve()
|
||||||
|
})
|
||||||
|
}).catch((error: any) => {
|
||||||
reject(new SocialError(error.code,error.message))
|
reject(new SocialError(error.code,error.message))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -114,19 +116,22 @@ export class GraphService implements IGraphService {
|
|||||||
=> 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}`)
|
||||||
let query
|
|
||||||
if (leftNode) {
|
if (leftNode != null) {
|
||||||
query = graphsRef.where('leftNode', '==', leftNode)
|
graphsRef = graphsRef.where('leftNode', '==', leftNode)
|
||||||
}
|
}
|
||||||
if (rightNode && rightNode != null) {
|
if (rightNode && rightNode != null) {
|
||||||
query = graphsRef.where('rightNode', '==', rightNode)
|
console.trace('getGraphsQuery', {collection, leftNode, edgeType, rightNode})
|
||||||
|
|
||||||
|
graphsRef = graphsRef.where('rightNode', '==', rightNode)
|
||||||
}
|
}
|
||||||
if (edgeType) {
|
if (edgeType) {
|
||||||
query = graphsRef.where('edgeType', '==', edgeType)
|
graphsRef = graphsRef.where('edgeType', '==', edgeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query) {
|
if (graphsRef) {
|
||||||
query.get().then((result) => {
|
graphsRef.get().then((result) => {
|
||||||
|
|
||||||
resolve(result)
|
resolve(result)
|
||||||
}).catch((error) => reject(error))
|
}).catch((error) => reject(error))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ export class PostService implements IPostService {
|
|||||||
// a = current item in array
|
// a = current item in array
|
||||||
// b = next item in array
|
// b = next item in array
|
||||||
return b[bKey].creationDate! - a[aKey].creationDate!
|
return b[bKey].creationDate! - a[aKey].creationDate!
|
||||||
});
|
})
|
||||||
if (lastPostId && lastPostId !== '') {
|
if (lastPostId && lastPostId !== '') {
|
||||||
const lastPostIndex = sortedObjects.findIndex((arg) => {
|
const lastPostIndex = sortedObjects.findIndex((arg) => {
|
||||||
return Object.keys(arg)[0] === lastPostId
|
return Object.keys(arg)[0] === lastPostId
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export class UserService implements IUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
});
|
})
|
||||||
resolve({ users: parsedData, newLastUserId })
|
resolve({ users: parsedData, newLastUserId })
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
@@ -107,11 +107,15 @@ export class UserService implements IUserService {
|
|||||||
return new Promise<UserProvider>((resolve,reject) => {
|
return new Promise<UserProvider>((resolve,reject) => {
|
||||||
let userProviderRef = db.doc(`userProviderInfo/${userId}`)
|
let userProviderRef = db.doc(`userProviderInfo/${userId}`)
|
||||||
userProviderRef.get().then((snapshot) => {
|
userProviderRef.get().then((snapshot) => {
|
||||||
let userProvider: UserProvider = snapshot.data() as UserProvider || {}
|
if (snapshot.exists) {
|
||||||
resolve(userProvider)
|
let userProvider: UserProvider = snapshot.data() as UserProvider || {}
|
||||||
|
resolve(userProvider)
|
||||||
|
} else {
|
||||||
|
throw new SocialError(`firestore/getUserProviderData/notExist `, `document of userProviderRef is not exist `)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
reject(new SocialError(error.code, 'firestore/getUserProviderData' + error.message))
|
reject(new SocialError(error.code, 'firestore/getUserProviderData ' + error.message))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -7,39 +7,49 @@ import { Circle, UserTie } from 'core/domain/circles'
|
|||||||
* @class CircleState
|
* @class CircleState
|
||||||
*/
|
*/
|
||||||
export class CircleState {
|
export class CircleState {
|
||||||
/**
|
/**
|
||||||
* The list of users belong to users circle
|
* The list of users belong to users circle
|
||||||
*
|
*
|
||||||
* @memberof CircleState
|
* @memberof CircleState
|
||||||
*/
|
*/
|
||||||
userTies: {[userId: string]: UserTie }= {}
|
userTies: { [userId: string]: UserTie } = {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of users belong to users circle
|
* The list of users belong to users circle
|
||||||
*
|
*
|
||||||
* @memberof CircleState
|
* @memberof CircleState
|
||||||
*/
|
*/
|
||||||
userTieds: {[userId: string]: UserTie }= {}
|
userTieds: { [userId: string]: UserTie } = {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of circle of current user
|
* The list of circle of current user
|
||||||
*/
|
*/
|
||||||
circleList: {[circleId: string]: Circle}
|
circleList: { [circleId: string]: Circle }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether select circle box is open for the selected user
|
* Whether select circle box is open for the selected user
|
||||||
*/
|
*/
|
||||||
selectCircleStatus: {[userId: string]: boolean}
|
selectCircleStatus: { [userId: string]: boolean }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether following loading is shown for the selected user
|
* Whether following loading is shown for the selected user
|
||||||
*/
|
*/
|
||||||
followingLoadingStatus: {[userId: string]: boolean}
|
followingLoadingStatus: { [userId: string]: boolean }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If user circles are loaded {true} or not {false}
|
* Keep selected circles for refere user
|
||||||
*
|
*/
|
||||||
* @memberof CircleState
|
selectedCircles: { [userId: string]: string[] }
|
||||||
*/
|
|
||||||
|
/**
|
||||||
|
* Whether the select circles box for referer user is open
|
||||||
|
*/
|
||||||
|
openSelecteCircles: { [userId: string]: boolean }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If user circles are loaded {true} or not {false}
|
||||||
|
*
|
||||||
|
* @memberof CircleState
|
||||||
|
*/
|
||||||
loaded: boolean = false
|
loaded: boolean = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,9 +75,13 @@ export let circleReducer = (state: CircleState = new CircleState(), action: ICir
|
|||||||
...state,
|
...state,
|
||||||
userTies: {
|
userTies: {
|
||||||
...state.userTies,
|
...state.userTies,
|
||||||
[payload.userTie.user.userId]: {
|
[payload.userTie.userId]: {
|
||||||
...payload.userTie
|
...payload.userTie
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
selectedCircles: {
|
||||||
|
...state.selectedCircles,
|
||||||
|
[payload.userTie.userId]: payload.userTie.circleIdList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +102,8 @@ export let circleReducer = (state: CircleState = new CircleState(), action: ICir
|
|||||||
userTies: {
|
userTies: {
|
||||||
...state.userTies,
|
...state.userTies,
|
||||||
...payload.userTies
|
...payload.userTies
|
||||||
}
|
},
|
||||||
|
selectedCircles : getSelectedCircles(payload.userTies)
|
||||||
}
|
}
|
||||||
|
|
||||||
case CircleActionType.ADD_USER_TIED_LIST:
|
case CircleActionType.ADD_USER_TIED_LIST:
|
||||||
@@ -139,9 +144,9 @@ export let circleReducer = (state: CircleState = new CircleState(), action: ICir
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
userTies: {
|
userTies: {
|
||||||
...state.userTies,
|
|
||||||
...filteredUserTies
|
...filteredUserTies
|
||||||
}
|
},
|
||||||
|
selectedCircles : getSelectedCircles(filteredUserTies)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -208,8 +213,65 @@ export let circleReducer = (state: CircleState = new CircleState(), action: ICir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User box component
|
||||||
|
*/
|
||||||
|
case CircleActionType.SET_SELECTED_CIRCLES_USER_BOX_COMPONENT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
selectedCircles: {
|
||||||
|
...state.selectedCircles,
|
||||||
|
[payload.userId]: payload.circleList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* User box component
|
||||||
|
*/
|
||||||
|
case CircleActionType.REMOVE_SELECTED_CIRCLES_USER_BOX_COMPONENT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
selectedCircles: {
|
||||||
|
...state.selectedCircles,
|
||||||
|
[payload.userId]: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* User box component
|
||||||
|
*/
|
||||||
|
case CircleActionType.OPEN_SELECT_CIRCLES_USER_BOX_COMPONENT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
openSelecteCircles: {
|
||||||
|
...state.openSelecteCircles,
|
||||||
|
[payload.userId]: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case CircleActionType.CLOSE_SELECT_CIRCLES_USER_BOX_COMPONENT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
openSelecteCircles: {
|
||||||
|
...state.openSelecteCircles,
|
||||||
|
[payload.userId]: false
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map user ties selected to selected circles
|
||||||
|
*/
|
||||||
|
const getSelectedCircles = (userTies: {[userId: string]: UserTie }) => {
|
||||||
|
let selectedCircles: {[userId: string]: string[]} = {}
|
||||||
|
Object.keys(userTies).forEach((userId: string) => {
|
||||||
|
const userTie = (userTies as {[userId: string]: UserTie })[userId]
|
||||||
|
selectedCircles = {
|
||||||
|
...selectedCircles,
|
||||||
|
[userTie.userId!]: userTie.circleIdList!
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return selectedCircles
|
||||||
|
}
|
||||||
@@ -6,101 +6,122 @@
|
|||||||
*/
|
*/
|
||||||
export class GlobalState {
|
export class GlobalState {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set percent of loading progress and visibility for Master component
|
* Set percent of loading progress and visibility for Master component
|
||||||
*
|
*
|
||||||
* @type {{
|
* @type {{
|
||||||
* percent: number,
|
* percent: number,
|
||||||
* visible: Boolean
|
* visible: boolean
|
||||||
* }}
|
* }}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
progress: {
|
progress: {
|
||||||
percent: number
|
percent: number
|
||||||
visible: Boolean
|
visible: boolean
|
||||||
} = {
|
} = {
|
||||||
percent: 0,
|
percent: 0,
|
||||||
visible: false
|
visible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If loading is enabled {true} or not false
|
* If loading is enabled {true} or not false
|
||||||
*
|
*
|
||||||
* @type {Boolean}
|
* @type {boolean}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
loadingStatus: Boolean = true
|
loadingStatus: boolean = true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If user date is loaded {true} or not {false}
|
* Whether send feedback is diplayed
|
||||||
*
|
*/
|
||||||
* @type {Boolean}
|
sendFeedbackStatus: boolean = false
|
||||||
* @memberof IGlobalState
|
|
||||||
*/
|
|
||||||
defaultLoadDataStatus: Boolean = false
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If message popup is open {true} or not {false}
|
* If user date is loaded {true} or not {false}
|
||||||
*
|
*
|
||||||
* @type {Boolean}
|
* @type {boolean}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
messageOpen: Boolean = false
|
defaultLoadDataStatus: boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text of popup global message
|
* If message popup is open {true} or not {false}
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {boolean}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
|
messageOpen: boolean = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The text of popup global message
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof IGlobalState
|
||||||
|
*/
|
||||||
message: string = ''
|
message: string = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Window size
|
* Window size
|
||||||
*
|
*
|
||||||
* @type {number}
|
* @type {number}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
windowWidth: number = 0
|
windowWidth: number = 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Window height
|
* Window height
|
||||||
*
|
*
|
||||||
* @type {number}
|
* @type {number}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
windowHeight: number = 0
|
windowHeight: number = 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text of website header
|
* The text of website header
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
headerTitle: string = ''
|
headerTitle: string = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top loading is visible {true} or not {false}
|
* Top loading is visible {true} or not {false}
|
||||||
*
|
*
|
||||||
* @type {Boolean}
|
* @type {boolean}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
showTopLoading: Boolean = false
|
showTopLoading: boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top loading message queue
|
* Top loading message queue
|
||||||
*
|
*
|
||||||
* @type {number}
|
* @type {number}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
topLoadingQueue: number = 0
|
topLoadingQueue: number = 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temp date storage
|
* Master loading is visible {true} or not {false}
|
||||||
*
|
*
|
||||||
* @type {*}
|
* @type {boolean}
|
||||||
* @memberof IGlobalState
|
* @memberof IGlobalState
|
||||||
*/
|
*/
|
||||||
|
showMasterLoading: boolean = true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Master loading message queue
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof IGlobalState
|
||||||
|
*/
|
||||||
|
masterLoadingQueue: number = 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temp date storage
|
||||||
|
*
|
||||||
|
* @type {*}
|
||||||
|
* @memberof IGlobalState
|
||||||
|
*/
|
||||||
temp: any = {
|
temp: any = {
|
||||||
caller: []
|
caller: []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,12 +67,22 @@ export const globalReducer = (state: GlobalState = new GlobalState(), action: IG
|
|||||||
...state,
|
...state,
|
||||||
headerTitle: action.payload
|
headerTitle: action.payload
|
||||||
}
|
}
|
||||||
case GlobalActionType.HIDE_TOP_LOADING:
|
case GlobalActionType.SHOW_SEND_FEEDBACK:
|
||||||
const queue = state.topLoadingQueue > 0 ? (state.topLoadingQueue - 1) : 0
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
topLoadingQueue: queue,
|
sendFeedbackStatus: true
|
||||||
showTopLoading: (queue > 0 ? true : false)
|
}
|
||||||
|
case GlobalActionType.HIDE_SEND_FEEDBACK:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
sendFeedbackStatus: false
|
||||||
|
}
|
||||||
|
case GlobalActionType.HIDE_TOP_LOADING:
|
||||||
|
const queueTopLoading = state.topLoadingQueue > 0 ? (state.topLoadingQueue - 1) : 0
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
topLoadingQueue: queueTopLoading,
|
||||||
|
showTopLoading: (queueTopLoading > 0 ? true : false)
|
||||||
|
|
||||||
}
|
}
|
||||||
case GlobalActionType.SHOW_TOP_LOADING:
|
case GlobalActionType.SHOW_TOP_LOADING:
|
||||||
@@ -81,6 +91,20 @@ export const globalReducer = (state: GlobalState = new GlobalState(), action: IG
|
|||||||
topLoadingQueue: (state.topLoadingQueue + 1),
|
topLoadingQueue: (state.topLoadingQueue + 1),
|
||||||
showTopLoading: true
|
showTopLoading: true
|
||||||
}
|
}
|
||||||
|
case GlobalActionType.HIDE_MASTER_LOADING:
|
||||||
|
const queueMasterLoading = state.masterLoadingQueue > 0 ? (state.masterLoadingQueue - 1) : 0
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
masterLoadingQueue: queueMasterLoading,
|
||||||
|
showMasterLoading: (queueMasterLoading > 0 ? true : false)
|
||||||
|
|
||||||
|
}
|
||||||
|
case GlobalActionType.SHOW_MASTER_LOADING:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
masterLoadingQueue: (state.masterLoadingQueue + 1),
|
||||||
|
showMasterLoading: true
|
||||||
|
}
|
||||||
case GlobalActionType.TEMP:
|
case GlobalActionType.TEMP:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export let serverReducer = (state: ServerState = new ServerState(), action: ISer
|
|||||||
request: {
|
request: {
|
||||||
...state.request,
|
...state.request,
|
||||||
[request.id]: {
|
[request.id]: {
|
||||||
request
|
...request
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import CommonAPI from 'api/CommonAPI'
|
|||||||
/**
|
/**
|
||||||
* Developer tools
|
* Developer tools
|
||||||
*/
|
*/
|
||||||
(window as any).logger = CommonAPI.logger
|
console.trace = CommonAPI.logger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize container
|
* Initialize container
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
@import 'base/grid';
|
@import 'base/grid';
|
||||||
@import 'base/animate';
|
@import 'base/animate';
|
||||||
@import 'base/icon';
|
@import 'base/icon';
|
||||||
|
@import 'base/flaticon';
|
||||||
// Component styles
|
// Component styles
|
||||||
@import 'components/global';
|
@import 'components/global';
|
||||||
@import 'components/master';
|
@import 'components/master';
|
||||||
@import 'components/post';
|
@import 'components/post';
|
||||||
@import 'components/profile';
|
@import 'components/profile';
|
||||||
|
@import 'components/sendFeedback';
|
||||||
@import 'components/userBox';
|
@import 'components/userBox';
|
||||||
@import 'components/imageGallery';
|
@import 'components/imageGallery';
|
||||||
@import 'components/postWrite';
|
@import 'components/postWrite';
|
||||||
|
|||||||
52
src/styles/base/_flaticon.scss
Normal file
52
src/styles/base/_flaticon.scss
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
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"; }
|
||||||
|
|
||||||
|
$font-Flaticon-sad-2: "\f100";
|
||||||
|
$font-Flaticon-sad-1: "\f101";
|
||||||
|
$font-Flaticon-neutral: "\f102";
|
||||||
|
$font-Flaticon-happy-2: "\f103";
|
||||||
|
$font-Flaticon-sad: "\f104";
|
||||||
|
$font-Flaticon-happy-1: "\f105";
|
||||||
|
$font-Flaticon-happy: "\f106";
|
||||||
@@ -35,4 +35,14 @@
|
|||||||
background-image: icon(facebook, #4267b2);
|
background-image: icon(facebook, #4267b2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon__svg {
|
||||||
|
padding: 10px;
|
||||||
|
display: block;
|
||||||
|
font-family: "Flaticon";
|
||||||
|
font-size: 64px;
|
||||||
|
line-height: 1;
|
||||||
|
transform: translate(-10px, -9px);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// .icon-dashstroke { background-image: icon(heart, red, black, 2, 'stroke-dasharray : 2px, 1px;'); }
|
// .icon-dashstroke { background-image: icon(heart, red, black, 2, 'stroke-dasharray : 2px, 1px;'); }
|
||||||
@@ -65,8 +65,7 @@
|
|||||||
outline: none !important;
|
outline: none !important;
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, .2) !important;
|
box-shadow: 0 2px 10px rgba(0, 0, 0, .2) !important;
|
||||||
div.container {
|
div.container {
|
||||||
padding: 10px;
|
padding: 10px 0px 10px 0px;
|
||||||
padding: 10px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -86,16 +85,18 @@
|
|||||||
padding: 10px 0px;
|
padding: 10px 0px;
|
||||||
div.item {
|
div.item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 68px;
|
height: 54px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 10px;
|
padding: 10px 0px 10px 0px;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
div.avatar {}
|
div.avatar {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
div.info {
|
div.info {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -2,11 +2,37 @@
|
|||||||
background-color: rgb(216, 216, 216);
|
background-color: rgb(216, 216, 216);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mLoading__content {
|
.mLoading__loading {
|
||||||
max-width: 338px !important;
|
position: fixed;
|
||||||
}
|
z-index: 2001;
|
||||||
|
height: 2em;
|
||||||
.mLoading__context{
|
width: 2em;
|
||||||
display: flex;
|
overflow: show;
|
||||||
justify-content: space-around;
|
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;
|
||||||
|
}
|
||||||
37
src/styles/components/_sendFeedback.scss
Normal file
37
src/styles/components/_sendFeedback.scss
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.sendFeedback__content {
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
right: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
z-index: 1;
|
||||||
|
.paper {
|
||||||
|
width: 350px;
|
||||||
|
height: 100%;
|
||||||
|
margin: 20px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
.buttons {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
top: 13px;
|
||||||
|
right: 13px;
|
||||||
|
}
|
||||||
|
.success {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
.loading{
|
||||||
|
padding: 18px 0px 0px 0px;
|
||||||
|
.icon {
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user