logo

pleroma-fe

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

status.vue (19414B)


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