bottom.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* jshint ignore:start */
  2. import React from 'react';
  3. import { OptionsXs } from '../options';
  4. export default function({category, isBusy, showOptions, isSelected, thread}) {
  5. let className = 'col-xs-12 col-sm-12';
  6. if (showOptions) {
  7. if (thread.moderation.length) {
  8. className = 'col-xs-6 col-sm-12';
  9. } else {
  10. className = 'col-xs-9 col-sm-12';
  11. }
  12. }
  13. let statusFlags = 0;
  14. if (thread.is_hidden) statusFlags += 1;
  15. if (thread.is_closed) statusFlags += 1;
  16. if (thread.has_poll) statusFlags += 1;
  17. let allFlagsVisible = showOptions && statusFlags === 3;
  18. let textClassName = 'detail-text hidden-xs';
  19. if (allFlagsVisible) {
  20. textClassName += ' hidden-sm'
  21. }
  22. return (
  23. <div className="row thread-details-bottom">
  24. <div className={className}>
  25. <a
  26. className="item-title thread-detail-category hidden-xs"
  27. href={category.absolute_url}
  28. >
  29. {category.name}
  30. </a>
  31. <HiddenLabel
  32. textClassName={textClassName}
  33. display={thread.is_hidden}
  34. />
  35. <ClosedLabel
  36. textClassName={textClassName}
  37. display={thread.is_closed}
  38. />
  39. <PollLabel
  40. textClassName={textClassName}
  41. display={thread.has_poll}
  42. />
  43. <RepliesLabel
  44. forceFullText={!showOptions || statusFlags < 2}
  45. replies={thread.replies}
  46. />
  47. <LastReplyLabel
  48. datetime={thread.last_post_on}
  49. url={thread.url.last_post}
  50. />
  51. <LastPoster
  52. posterName={thread.last_poster_name}
  53. url={thread.url.last_poster}
  54. />
  55. </div>
  56. <OptionsXs
  57. disabled={isBusy}
  58. display={showOptions}
  59. isSelected={isSelected}
  60. thread={thread}
  61. />
  62. </div>
  63. );
  64. }
  65. export function HiddenLabel({ display, textClassName }) {
  66. if (!display) return null;
  67. return (
  68. <span className="thread-detail-hidden">
  69. <span className="material-icon">
  70. visibility_off
  71. </span>
  72. <span className={textClassName}>
  73. {gettext("Hidden")}
  74. </span>
  75. </span>
  76. )
  77. }
  78. export function ClosedLabel({ display, textClassName }) {
  79. if (!display) return null;
  80. return (
  81. <span className="thread-detail-closed">
  82. <span className="material-icon">
  83. lock_outline
  84. </span>
  85. <span className={textClassName}>
  86. {gettext("Closed")}
  87. </span>
  88. </span>
  89. )
  90. }
  91. export function PollLabel({ display, textClassName }) {
  92. if (!display) return null;
  93. return (
  94. <span className="thread-detail-poll">
  95. <span className="material-icon">
  96. assessment
  97. </span>
  98. <span className={textClassName}>
  99. {gettext("Poll")}
  100. </span>
  101. </span>
  102. )
  103. }
  104. export function RepliesLabel({ replies, forceFullText }) {
  105. const text = ngettext(
  106. "%(replies)s reply",
  107. "%(replies)s replies",
  108. replies);
  109. let compactClassName = '';
  110. let fullClassName = '';
  111. if (forceFullText) {
  112. compactClassName = 'detail-text hide';
  113. fullClassName = 'detail-text';
  114. } else {
  115. compactClassName = 'detail-text visible-xs-inline-block';
  116. fullClassName = 'detail-text hidden-xs';
  117. }
  118. return (
  119. <span className="thread-detail-replies">
  120. <span className="material-icon">
  121. forum
  122. </span>
  123. <span className={compactClassName}>
  124. {replies}
  125. </span>
  126. <span className={fullClassName}>
  127. {interpolate(text, { replies }, true)}
  128. </span>
  129. </span>
  130. )
  131. }
  132. export function LastReplyLabel({ datetime, url }) {
  133. return (
  134. <a
  135. className="visible-sm-inline-block thread-detail-last-reply"
  136. href={url}
  137. title={datetime.format('LLL')}
  138. >
  139. {datetime.fromNow(true)}
  140. </a>
  141. )
  142. }
  143. export function LastPoster(props) {
  144. const { posterName, url } = props;
  145. if (url) {
  146. return (
  147. <a
  148. className="visible-sm-inline-block item-title thread-last-poster"
  149. href={url}
  150. >
  151. {posterName}
  152. </a>
  153. );
  154. }
  155. return (
  156. <span className="visible-sm-inline-block item-title thread-last-poster">
  157. {posterName}
  158. </span>
  159. );
  160. }