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 (19564B)


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