logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://anongit.hacktivis.me/git/pleroma-fe.git/

status.vue (20080B)


  1. <template>
  2. <div
  3. v-if="!hideStatus"
  4. ref="root"
  5. class="Status"
  6. :class="[{ '-focused': isFocused }, { '-conversation': inlineExpanded }]"
  7. >
  8. <div
  9. v-if="error"
  10. class="alert error"
  11. >
  12. {{ error }}
  13. <span
  14. class="fa-scale-110 fa-old-padding"
  15. @click="clearError"
  16. >
  17. <FAIcon icon="times" />
  18. </span>
  19. </div>
  20. <template v-if="muted && !isPreview">
  21. <div class="status-container muted">
  22. <small class="status-username">
  23. <FAIcon
  24. v-if="muted && retweet"
  25. class="fa-scale-110 fa-old-padding repeat-icon"
  26. icon="retweet"
  27. />
  28. <user-link
  29. :user="status.user"
  30. :at="false"
  31. />
  32. </small>
  33. <small
  34. v-if="muteSensitiveStatuses && status.nsfw"
  35. class="mute-thread"
  36. >
  37. {{ $t('status.sensitive_muted') }}
  38. </small>
  39. <small
  40. v-if="showReasonMutedThread"
  41. class="mute-thread"
  42. >
  43. {{ $t('status.thread_muted') }}
  44. </small>
  45. <small
  46. v-if="showReasonMutedThread && muteWordHits.length > 0"
  47. class="mute-thread"
  48. >
  49. {{ $t('status.thread_muted_and_words') }}
  50. </small>
  51. <small
  52. class="mute-words"
  53. :title="muteWordHits.join(', ')"
  54. >
  55. {{ muteWordHits.join(', ') }}
  56. </small>
  57. <button
  58. class="unmute button-unstyled"
  59. @click.prevent="toggleMute"
  60. >
  61. <FAIcon
  62. icon="eye-slash"
  63. class="fa-scale-110 fa-old-padding"
  64. />
  65. </button>
  66. </div>
  67. </template>
  68. <template v-else>
  69. <div
  70. v-if="showPinned"
  71. class="pin"
  72. >
  73. <FAIcon
  74. icon="thumbtack"
  75. class="faint"
  76. />
  77. <span class="faint">{{ $t('status.pinned') }}</span>
  78. </div>
  79. <div
  80. v-if="retweet && !noHeading && !inConversation"
  81. :class="[repeaterClass, { highlighted: repeaterStyle }]"
  82. :style="[repeaterStyle]"
  83. class="status-container repeat-info"
  84. >
  85. <UserAvatar
  86. v-if="retweet"
  87. class="left-side repeater-avatar"
  88. :show-actor-type-indicator="showActorTypeIndicator"
  89. :better-shadow="betterShadow"
  90. :user="statusoid.user"
  91. />
  92. <div class="right-side faint">
  93. <bdi
  94. class="status-username repeater-name"
  95. :title="retweeter"
  96. >
  97. <router-link
  98. v-if="retweeterHtml"
  99. :to="retweeterProfileLink"
  100. >
  101. <RichContent
  102. :html="retweeterHtml"
  103. :emoji="retweeterUser.emoji"
  104. />
  105. </router-link>
  106. <router-link
  107. v-else
  108. :to="retweeterProfileLink"
  109. >{{ retweeter }}</router-link>
  110. </bdi>
  111. {{ ' ' }}
  112. <FAIcon
  113. icon="retweet"
  114. class="repeat-icon"
  115. :title="$t('tool_tip.repeat')"
  116. />
  117. {{ $t('timeline.repeated') }}
  118. </div>
  119. </div>
  120. <div
  121. v-if="!deleted"
  122. :class="[userClass, { highlighted: userStyle, '-repeat': retweet && !inConversation }]"
  123. :style="[ userStyle ]"
  124. class="status-container"
  125. :data-tags="tags"
  126. >
  127. <div
  128. v-if="!noHeading"
  129. class="left-side"
  130. >
  131. <a
  132. :href="$router.resolve(userProfileLink).href"
  133. @click.prevent
  134. >
  135. <UserPopover
  136. :user-id="status.user.id"
  137. :overlay-centers="true"
  138. >
  139. <UserAvatar
  140. class="post-avatar"
  141. :show-actor-type-indicator="showActorTypeIndicator"
  142. :compact="compact"
  143. :better-shadow="betterShadow"
  144. :user="status.user"
  145. />
  146. </UserPopover>
  147. </a>
  148. </div>
  149. <div class="right-side">
  150. <div
  151. v-if="!noHeading"
  152. class="status-heading"
  153. >
  154. <div class="heading-name-row">
  155. <div class="heading-left">
  156. <h4
  157. v-if="status.user.name_html"
  158. class="status-username"
  159. :title="status.user.name"
  160. >
  161. <RichContent
  162. :html="status.user.name"
  163. :emoji="status.user.emoji"
  164. />
  165. </h4>
  166. <h4
  167. v-else
  168. class="status-username"
  169. :title="status.user.name"
  170. >
  171. {{ status.user.name }}
  172. </h4>
  173. <user-link
  174. class="account-name"
  175. :title="status.user.screen_name_ui"
  176. :user="status.user"
  177. :at="false"
  178. />
  179. <img
  180. v-if="!!(status.user && status.user.favicon)"
  181. class="status-favicon"
  182. :src="status.user.favicon"
  183. >
  184. </div>
  185. <span class="heading-right">
  186. <router-link
  187. class="timeago faint"
  188. :to="{ name: 'conversation', params: { id: status.id } }"
  189. >
  190. <Timeago
  191. :time="status.created_at"
  192. :auto-update="60"
  193. />
  194. </router-link>
  195. <span
  196. v-if="status.visibility"
  197. class="visibility-icon"
  198. :title="visibilityLocalized"
  199. >
  200. <FAIcon
  201. fixed-width
  202. class="fa-scale-110"
  203. :icon="visibilityIcon(status.visibility)"
  204. />
  205. </span>
  206. <button
  207. v-if="expandable && !isPreview"
  208. class="button-unstyled"
  209. :title="$t('status.expand')"
  210. @click.prevent="toggleExpanded"
  211. >
  212. <FAIcon
  213. fixed-width
  214. class="fa-scale-110"
  215. icon="plus-square"
  216. />
  217. </button>
  218. <button
  219. v-if="unmuted"
  220. class="button-unstyled"
  221. @click.prevent="toggleMute"
  222. >
  223. <FAIcon
  224. fixed-width
  225. icon="eye-slash"
  226. class="fa-scale-110"
  227. />
  228. </button>
  229. <button
  230. v-if="inThreadForest && replies && replies.length && !simpleTree"
  231. class="button-unstyled"
  232. :title="threadShowing ? $t('status.thread_hide') : $t('status.thread_show')"
  233. :aria-expanded="threadShowing ? 'true' : 'false'"
  234. @click.prevent="toggleThreadDisplay"
  235. >
  236. <FAIcon
  237. fixed-width
  238. class="fa-scale-110"
  239. :icon="threadShowing ? 'chevron-up' : 'chevron-down'"
  240. />
  241. </button>
  242. <button
  243. v-if="dive && !simpleTree"
  244. class="button-unstyled"
  245. :title="$t('status.show_only_conversation_under_this')"
  246. @click.prevent="dive"
  247. >
  248. <FAIcon
  249. fixed-width
  250. class="fa-scale-110"
  251. :icon="'angle-double-right'"
  252. />
  253. </button>
  254. </span>
  255. </div>
  256. <div
  257. v-if="scrobblePresent"
  258. class="status-rich-presence"
  259. >
  260. <a
  261. v-if="scrobble.externalLink"
  262. :href="scrobble.externalLink"
  263. target="_blank"
  264. >
  265. {{ scrobble.artist }} — {{ scrobble.title }}
  266. <FAIcon
  267. class="fa-scale-110 fa-old-padding"
  268. icon="play"
  269. />
  270. <span class="status-rich-presence-time">
  271. <Timeago
  272. template-key="time.in_past"
  273. :time="scrobble.created_at"
  274. :auto-update="60"
  275. />
  276. </span>
  277. </a>
  278. <span v-if="!scrobble.externalLink">
  279. <FAIcon
  280. class="fa-scale-110 fa-old-padding"
  281. icon="music"
  282. />
  283. {{ scrobble.artist }} — {{ scrobble.title }}
  284. <FAIcon
  285. class="fa-scale-110 fa-old-padding"
  286. icon="play"
  287. />
  288. <span class="status-rich-presence-time">
  289. <Timeago
  290. template-key="time.in_past"
  291. :time="scrobble.created_at"
  292. :auto-update="60"
  293. />
  294. </span>
  295. </span>
  296. </div>
  297. <div
  298. v-if="isReply || hasMentionsLine"
  299. class="heading-reply-row"
  300. >
  301. <span
  302. v-if="isReply"
  303. class="glued-label reply-glued-label"
  304. >
  305. <StatusPopover
  306. v-if="!isPreview"
  307. :status-id="status.parent_visible && status.in_reply_to_status_id"
  308. class="reply-to-popover"
  309. style="min-width: 0;"
  310. :class="{ '-strikethrough': !status.parent_visible }"
  311. >
  312. <button
  313. class="button-unstyled reply-to"
  314. :aria-label="$t('tool_tip.reply')"
  315. @click.prevent="gotoOriginal(status.in_reply_to_status_id)"
  316. >
  317. <FAIcon
  318. class="fa-scale-110 fa-old-padding"
  319. icon="reply"
  320. flip="horizontal"
  321. />
  322. {{ ' ' }}
  323. <span
  324. class="reply-to-text"
  325. >
  326. {{ $t('status.reply_to') }}
  327. </span>
  328. </button>
  329. </StatusPopover>
  330. <span
  331. v-else
  332. class="reply-to-no-popover"
  333. >
  334. <span class="reply-to-text">{{ $t('status.reply_to') }}</span>
  335. </span>
  336. <MentionLink
  337. :content="replyToName"
  338. :url="replyProfileLink"
  339. :user-id="status.in_reply_to_user_id"
  340. :user-screen-name="status.in_reply_to_screen_name"
  341. />
  342. </span>
  343. <!-- This little wrapper is made for sole purpose of "gluing" -->
  344. <!-- "Mentions" label to the first mention -->
  345. <span
  346. v-if="hasMentionsLine"
  347. class="glued-label"
  348. >
  349. <span
  350. class="mentions"
  351. :aria-label="$t('tool_tip.mentions')"
  352. @click.prevent="gotoOriginal(status.in_reply_to_status_id)"
  353. >
  354. <span
  355. class="mentions-text"
  356. >
  357. {{ $t('status.mentions') }}
  358. </span>
  359. </span>
  360. <MentionsLine
  361. v-if="hasMentionsLine"
  362. :mentions="mentionsLine.slice(0, 1)"
  363. class="mentions-line-first"
  364. />
  365. </span>
  366. {{ ' ' }}
  367. <MentionsLine
  368. v-if="hasMentionsLine"
  369. :mentions="mentionsLine.slice(1)"
  370. class="mentions-line"
  371. />
  372. </div>
  373. <div
  374. v-if="isEdited && editingAvailable && !isPreview"
  375. class="heading-edited-row"
  376. >
  377. <i18n-t
  378. keypath="status.edited_at"
  379. tag="span"
  380. >
  381. <template #time>
  382. <Timeago
  383. template-key="time.in_past"
  384. :time="status.edited_at"
  385. :auto-update="60"
  386. :long-format="true"
  387. />
  388. </template>
  389. </i18n-t>
  390. </div>
  391. </div>
  392. <StatusContent
  393. ref="content"
  394. :status="status"
  395. :no-heading="noHeading"
  396. :highlight="highlight"
  397. :focused="isFocused"
  398. :controlled-showing-tall="controlledShowingTall"
  399. :controlled-expanding-subject="controlledExpandingSubject"
  400. :controlled-showing-long-subject="controlledShowingLongSubject"
  401. :controlled-toggle-showing-tall="controlledToggleShowingTall"
  402. :controlled-toggle-expanding-subject="controlledToggleExpandingSubject"
  403. :controlled-toggle-showing-long-subject="controlledToggleShowingLongSubject"
  404. @mediaplay="addMediaPlaying($event)"
  405. @mediapause="removeMediaPlaying($event)"
  406. @parseReady="setHeadTailLinks"
  407. />
  408. <article
  409. v-if="hasVisibleQuote"
  410. class="quoted-status"
  411. >
  412. <button
  413. class="button-unstyled -link display-quoted-status-button"
  414. :aria-expanded="shouldDisplayQuote"
  415. @click="toggleDisplayQuote"
  416. >
  417. {{ shouldDisplayQuote ? $t('status.hide_quote') : $t('status.display_quote') }}
  418. <FAIcon
  419. class="display-quoted-status-button-icon"
  420. :icon="shouldDisplayQuote ? 'chevron-up' : 'chevron-down'"
  421. />
  422. </button>
  423. <Status
  424. v-if="shouldDisplayQuote"
  425. :statusoid="quotedStatus"
  426. :in-quote="true"
  427. />
  428. </article>
  429. <p
  430. v-else-if="hasInvisibleQuote"
  431. class="quoted-status -unavailable-prompt"
  432. >
  433. <i18n-t keypath="status.invisible_quote">
  434. <template #link>
  435. <bdi>
  436. <a
  437. :href="status.quote_url"
  438. target="_blank"
  439. >
  440. {{ status.quote_url }}
  441. </a>
  442. </bdi>
  443. </template>
  444. </i18n-t>
  445. </p>
  446. <div
  447. v-if="inConversation && !isPreview && replies && replies.length"
  448. class="replies"
  449. >
  450. <button
  451. v-if="showOtherRepliesAsButton && replies.length > 1"
  452. class="button-unstyled -link"
  453. :title="$tc('status.ancestor_follow', replies.length - 1, { numReplies: replies.length - 1 })"
  454. @click.prevent="dive"
  455. >
  456. {{ $tc('status.replies_list_with_others', replies.length - 1, { numReplies: replies.length - 1 }) }}
  457. </button>
  458. <span
  459. v-else
  460. class="faint"
  461. >
  462. {{ $t('status.replies_list') }}
  463. </span>
  464. <StatusPopover
  465. v-for="reply in replies"
  466. :key="reply.id"
  467. :status-id="reply.id"
  468. >
  469. <button
  470. class="button-unstyled -link reply-link"
  471. @click.prevent="gotoOriginal(reply.id)"
  472. >
  473. {{ reply.name }}
  474. </button>
  475. </StatusPopover>
  476. </div>
  477. <transition name="fade">
  478. <div
  479. v-if="shouldDisplayFavsAndRepeats"
  480. class="favs-repeated-users"
  481. >
  482. <div class="stats">
  483. <UserListPopover
  484. v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0"
  485. :users="statusFromGlobalRepository.rebloggedBy"
  486. >
  487. <div class="stat-count">
  488. <a class="stat-title">{{ $t('status.repeats') }}</a>
  489. <div class="stat-number">
  490. {{ statusFromGlobalRepository.rebloggedBy.length }}
  491. </div>
  492. </div>
  493. </UserListPopover>
  494. <UserListPopover
  495. v-if="statusFromGlobalRepository.favoritedBy && statusFromGlobalRepository.favoritedBy.length > 0"
  496. :users="statusFromGlobalRepository.favoritedBy"
  497. >
  498. <div
  499. class="stat-count"
  500. >
  501. <a class="stat-title">{{ $t('status.favorites') }}</a>
  502. <div class="stat-number">
  503. {{ statusFromGlobalRepository.favoritedBy.length }}
  504. </div>
  505. </div>
  506. </UserListPopover>
  507. <router-link
  508. v-if="statusFromGlobalRepository.quotes_count > 0"
  509. :to="{ name: 'quotes', params: { id: status.id } }"
  510. >
  511. <div
  512. class="stat-count"
  513. >
  514. <a class="stat-title">{{ $t('status.quotes') }}</a>
  515. <div class="stat-number">
  516. {{ statusFromGlobalRepository.quotes_count }}
  517. </div>
  518. </div>
  519. </router-link>
  520. <div class="avatar-row">
  521. <AvatarList :users="combinedFavsAndRepeatsUsers" />
  522. </div>
  523. </div>
  524. </div>
  525. </transition>
  526. <EmojiReactions
  527. v-if="(mergedConfig.emojiReactionsOnTimeline || isFocused) && (!noHeading && !isPreview)"
  528. :status="status"
  529. />
  530. <div
  531. v-if="!noHeading && !isPreview"
  532. class="status-actions"
  533. >
  534. <reply-button
  535. :replying="replying"
  536. :status="status"
  537. @toggle="toggleReplying"
  538. />
  539. <retweet-button
  540. :visibility="status.visibility"
  541. :logged-in="loggedIn"
  542. :status="status"
  543. @click="$emit('interacted')"
  544. />
  545. <favorite-button
  546. :logged-in="loggedIn"
  547. :status="status"
  548. @click="$emit('interacted')"
  549. />
  550. <ReactButton
  551. v-if="loggedIn"
  552. :status="status"
  553. @click="$emit('interacted')"
  554. />
  555. <extra-buttons
  556. :status="status"
  557. @onError="showError"
  558. @onSuccess="clearError"
  559. />
  560. </div>
  561. </div>
  562. </div>
  563. <div
  564. v-else
  565. class="gravestone"
  566. >
  567. <div class="left-side">
  568. <UserAvatar
  569. class="post-avatar"
  570. :compact="compact"
  571. :show-actor-type-indicator="showActorTypeIndicator"
  572. />
  573. </div>
  574. <div class="right-side">
  575. <div class="deleted-text">
  576. {{ $t('status.status_deleted') }}
  577. </div>
  578. <reply-button
  579. v-if="replying"
  580. :replying="replying"
  581. :status="status"
  582. @toggle="toggleReplying"
  583. />
  584. </div>
  585. </div>
  586. <div
  587. v-if="replying"
  588. class="status-container reply-form"
  589. >
  590. <PostStatusForm
  591. class="reply-body"
  592. :reply-to="status.id"
  593. :attentions="status.attentions"
  594. :replied-user="status.user"
  595. :copy-message-scope="status.visibility"
  596. :subject="replySubject"
  597. @posted="toggleReplying"
  598. />
  599. </div>
  600. </template>
  601. </div>
  602. </template>
  603. <script src="./status.js"></script>
  604. <style src="./status.scss" lang="scss"></style>