root.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import React from 'react';
  2. import { connect } from 'react-redux';
  3. import Avatar from 'misago/components/avatar'; // jshint ignore:line
  4. import Header from 'misago/components/profile/Header'; // jshint ignore:line
  5. import ModerationNav from 'misago/components/profile/moderation/nav'; // jshint ignore:line
  6. import { SideNav, CompactNav } from 'misago/components/profile/navs'; // jshint ignore:line
  7. import misago from 'misago/index';
  8. import { dehydrate } from 'misago/reducers/profile'; // jshint ignore:line
  9. import polls from 'misago/services/polls';
  10. import store from 'misago/services/store'; // jshint ignore:line
  11. export default class extends React.Component {
  12. constructor(props) {
  13. super(props);
  14. this.state = {
  15. dropdown: false
  16. };
  17. this.startPolling(props.profile.api_url.root);
  18. }
  19. startPolling(api) {
  20. polls.start({
  21. poll: 'user-profile',
  22. url: api,
  23. frequency: 90 * 1000,
  24. update: this.update
  25. });
  26. }
  27. /* jshint ignore:start */
  28. update = (data) => {
  29. store.dispatch(dehydrate(data));
  30. };
  31. /* jshint ignore:end */
  32. /* jshint ignore:start */
  33. toggleNav = () => {
  34. if (this.state.dropdown === 'pages') {
  35. this.setState({
  36. dropdown: false
  37. });
  38. } else {
  39. this.setState({
  40. dropdown: 'pages'
  41. });
  42. }
  43. };
  44. toggleModeration = () => {
  45. if (this.state.dropdown === 'moderation') {
  46. this.setState({
  47. dropdown: false
  48. });
  49. } else {
  50. console.log('show moderation!');
  51. this.setState({
  52. dropdown: 'moderation'
  53. });
  54. }
  55. };
  56. hideNav = () => {
  57. this.setState({
  58. dropdown: false
  59. });
  60. };
  61. /* jshint ignore:end */
  62. getToggleNavClassName() {
  63. if (this.state.dropdown) {
  64. return 'btn btn-default btn-icon open';
  65. } else {
  66. return 'btn btn-default btn-icon';
  67. }
  68. }
  69. getCompactNavClassName() {
  70. if (this.state.dropdown) {
  71. return 'compact-nav open';
  72. } else {
  73. return 'compact-nav';
  74. }
  75. }
  76. getNavDropdown() {
  77. if (this.state.dropdown === 'pages') {
  78. /* jshint ignore:start */
  79. return <CompactNav pages={misago.get('PROFILE_PAGES')}
  80. baseUrl={misago.get('PROFILE').absolute_url}
  81. profile={this.props.profile}
  82. toggleModeration={this.toggleModeration}
  83. hideNav={this.hideNav} />;
  84. /* jshint ignore:end */
  85. } else if (this.state.dropdown === 'moderation') {
  86. /* jshint ignore:start */
  87. return <ModerationNav profile={this.props.profile}
  88. toggleNav={this.toggleNav}
  89. hideNav={this.hideNav} />;
  90. /* jshint ignore:end */
  91. } else {
  92. return null;
  93. }
  94. }
  95. getClassName() {
  96. const baseClass = 'page page-user-profile';
  97. if (false && this.props.profile.rank.css_class) {
  98. return baseClass + ' page-user-profile-' + this.props.profile.rank.css_class;
  99. } else {
  100. return baseClass;
  101. }
  102. }
  103. render() {
  104. /* jshint ignore:start */
  105. return <div className={this.getClassName()}>
  106. <Header user={this.props.user}
  107. profile={this.props.profile}
  108. toggleNav={this.toggleNav}
  109. toggleModeration={this.toggleModeration} />
  110. <div className={this.getCompactNavClassName()}>
  111. {this.getNavDropdown()}
  112. </div>
  113. <div className="container">
  114. <div className="row">
  115. <div className="col-md-3 hidden-xs hidden-sm">
  116. <div className="profile-side-avatar">
  117. <Avatar user={this.props.profile} size="400" />
  118. </div>
  119. <SideNav pages={misago.get('PROFILE_PAGES')}
  120. baseUrl={misago.get('PROFILE').absolute_url}
  121. profile={this.props.profile} />
  122. </div>
  123. <div className="col-md-9">
  124. {this.props.children}
  125. </div>
  126. </div>
  127. </div>
  128. </div>;
  129. /* jshint ignore:end */
  130. }
  131. }
  132. export function select(store) {
  133. return {
  134. 'tick': store.tick.tick,
  135. 'user': store.auth.user,
  136. 'users': store.users,
  137. 'profile': store.profile,
  138. 'username-history': store['username-history']
  139. };
  140. }
  141. class Placeholder extends React.Component {
  142. render() {
  143. // jshint ignore:start
  144. return <div className="container">
  145. <p>{"Hello, I'm placeholder for " + this.props.route.name}</p>
  146. </div>;
  147. // jshint ignore:end
  148. }
  149. }
  150. const COMPONENTS = {
  151. 'posts': Placeholder,
  152. 'threads': Placeholder,
  153. 'followers': Placeholder,
  154. 'follows': Placeholder,
  155. 'username-history': Placeholder,
  156. 'ban-details': Placeholder
  157. };
  158. export function paths() {
  159. let paths = [];
  160. misago.get('PROFILE_PAGES').forEach(function(item) {
  161. paths.push(Object.assign({}, item, {
  162. path: misago.get('PROFILE').absolute_url + item.component + '/',
  163. component: connect(select)(COMPONENTS[item.component]),
  164. }));
  165. });
  166. return paths;
  167. }