logo

pleroma-fe

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

post_status_form.vue (13758B)


  1. <template>
  2. <div
  3. ref="form"
  4. class="post-status-form"
  5. >
  6. <form
  7. autocomplete="off"
  8. @submit.prevent
  9. @dragover.prevent="fileDrag"
  10. >
  11. <div class="form-group">
  12. <i18n-t
  13. v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private' && !disableLockWarning"
  14. keypath="post_status.account_not_locked_warning"
  15. tag="p"
  16. class="visibility-notice"
  17. scope="global"
  18. >
  19. <button
  20. class="button-unstyled -link"
  21. @click="openProfileTab"
  22. >
  23. {{ $t('post_status.account_not_locked_warning_link') }}
  24. </button>
  25. </i18n-t>
  26. <p
  27. v-if="!hideScopeNotice && newStatus.visibility === 'public'"
  28. class="visibility-notice notice-dismissible"
  29. >
  30. <span>{{ $t('post_status.scope_notice.public') }}</span>
  31. <a
  32. class="fa-scale-110 fa-old-padding dismiss"
  33. :title="$t('post_status.scope_notice_dismiss')"
  34. role="button"
  35. tabindex="0"
  36. @click.prevent="dismissScopeNotice()"
  37. >
  38. <FAIcon icon="times" />
  39. </a>
  40. </p>
  41. <p
  42. v-else-if="!hideScopeNotice && newStatus.visibility === 'unlisted'"
  43. class="visibility-notice notice-dismissible"
  44. >
  45. <span>{{ $t('post_status.scope_notice.unlisted') }}</span>
  46. <a
  47. class="fa-scale-110 fa-old-padding dismiss"
  48. :title="$t('post_status.scope_notice_dismiss')"
  49. role="button"
  50. tabindex="0"
  51. @click.prevent="dismissScopeNotice()"
  52. >
  53. <FAIcon icon="times" />
  54. </a>
  55. </p>
  56. <p
  57. v-else-if="!hideScopeNotice && newStatus.visibility === 'private' && $store.state.users.currentUser.locked"
  58. class="visibility-notice notice-dismissible"
  59. >
  60. <span>{{ $t('post_status.scope_notice.private') }}</span>
  61. <a
  62. class="fa-scale-110 fa-old-padding dismiss"
  63. :title="$t('post_status.scope_notice_dismiss')"
  64. role="button"
  65. tabindex="0"
  66. @click.prevent="dismissScopeNotice()"
  67. >
  68. <FAIcon icon="times" />
  69. </a>
  70. </p>
  71. <p
  72. v-else-if="newStatus.visibility === 'direct'"
  73. class="visibility-notice"
  74. >
  75. <span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
  76. <span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
  77. </p>
  78. <div
  79. v-if="isEdit"
  80. class="visibility-notice edit-warning"
  81. >
  82. <p>{{ $t('post_status.edit_remote_warning') }}</p>
  83. <p>{{ $t('post_status.edit_unsupported_warning') }}</p>
  84. </div>
  85. <div
  86. v-if="!disablePreview"
  87. class="preview-heading faint"
  88. >
  89. <a
  90. class="preview-toggle faint"
  91. @click.stop.prevent="togglePreview"
  92. >
  93. {{ $t('post_status.preview') }}
  94. <FAIcon :icon="showPreview ? 'chevron-left' : 'chevron-right'" />
  95. </a>
  96. <div
  97. v-show="previewLoading"
  98. class="preview-spinner"
  99. >
  100. <FAIcon
  101. class="fa-old-padding"
  102. spin
  103. icon="circle-notch"
  104. />
  105. </div>
  106. <div
  107. v-if="quotable"
  108. role="radiogroup"
  109. class="btn-group reply-or-quote-selector"
  110. >
  111. <button
  112. :id="`reply-or-quote-option-${randomSeed}-reply`"
  113. class="btn button-default reply-or-quote-option"
  114. :class="{ toggled: !newStatus.quoting }"
  115. tabindex="0"
  116. role="radio"
  117. :aria-labelledby="`reply-or-quote-option-${randomSeed}-reply`"
  118. :aria-checked="!newStatus.quoting"
  119. @click="newStatus.quoting = false"
  120. >
  121. {{ $t('post_status.reply_option') }}
  122. </button>
  123. <button
  124. :id="`reply-or-quote-option-${randomSeed}-quote`"
  125. class="btn button-default reply-or-quote-option"
  126. :class="{ toggled: newStatus.quoting }"
  127. tabindex="0"
  128. role="radio"
  129. :aria-labelledby="`reply-or-quote-option-${randomSeed}-quote`"
  130. :aria-checked="newStatus.quoting"
  131. @click="newStatus.quoting = true"
  132. >
  133. {{ $t('post_status.quote_option') }}
  134. </button>
  135. </div>
  136. </div>
  137. <div
  138. v-if="showPreview"
  139. class="preview-container"
  140. >
  141. <div
  142. v-if="!preview"
  143. class="preview-status"
  144. >
  145. {{ $t('general.loading') }}
  146. </div>
  147. <div
  148. v-else-if="preview.error"
  149. class="preview-status preview-error"
  150. >
  151. {{ preview.error }}
  152. </div>
  153. <StatusContent
  154. v-else
  155. :status="preview"
  156. class="preview-status"
  157. />
  158. </div>
  159. <EmojiInput
  160. v-if="!disableSubject && (newStatus.spoilerText || alwaysShowSubject)"
  161. v-model="newStatus.spoilerText"
  162. enable-emoji-picker
  163. :suggest="emojiSuggestor"
  164. class="input form-control"
  165. >
  166. <template #default="inputProps">
  167. <input
  168. v-model="newStatus.spoilerText"
  169. type="text"
  170. :placeholder="$t('post_status.content_warning')"
  171. :disabled="posting && !optimisticPosting"
  172. v-bind="propsToNative(inputProps)"
  173. size="1"
  174. class="input form-post-subject"
  175. >
  176. </template>
  177. </EmojiInput>
  178. <EmojiInput
  179. ref="emoji-input"
  180. v-model="newStatus.status"
  181. :suggest="emojiUserSuggestor"
  182. :placement="emojiPickerPlacement"
  183. class="input form-control main-input"
  184. enable-sticker-picker
  185. enable-emoji-picker
  186. hide-emoji-button
  187. :newline-on-ctrl-enter="submitOnEnter"
  188. @input="onEmojiInputInput"
  189. @sticker-uploaded="addMediaFile"
  190. @sticker-upload-failed="uploadFailed"
  191. @shown="handleEmojiInputShow"
  192. >
  193. <template #default="inputProps">
  194. <textarea
  195. ref="textarea"
  196. v-model="newStatus.status"
  197. :placeholder="placeholder || $t('post_status.default')"
  198. rows="1"
  199. cols="1"
  200. :disabled="posting && !optimisticPosting"
  201. class="input form-post-body"
  202. :class="{ 'scrollable-form': !!maxHeight }"
  203. v-bind="propsToNative(inputProps)"
  204. @keydown.exact.enter="submitOnEnter && postStatus($event, newStatus)"
  205. @keydown.meta.enter="postStatus($event, newStatus)"
  206. @keydown.ctrl.enter="!submitOnEnter && postStatus($event, newStatus)"
  207. @input="resize"
  208. @compositionupdate="resize"
  209. @paste="paste"
  210. />
  211. <p
  212. v-if="hasStatusLengthLimit"
  213. class="character-counter faint"
  214. :class="{ error: isOverLengthLimit }"
  215. >
  216. {{ charactersLeft }}
  217. </p>
  218. </template>
  219. </EmojiInput>
  220. <div
  221. v-if="!disableScopeSelector"
  222. class="visibility-tray"
  223. >
  224. <scope-selector
  225. v-if="!disableVisibilitySelector"
  226. :show-all="showAllScopes"
  227. :user-default="userDefaultScope"
  228. :original-scope="copyMessageScope"
  229. :initial-scope="newStatus.visibility"
  230. :on-scope-change="changeVis"
  231. />
  232. <div
  233. v-if="postFormats.length > 1"
  234. class="text-format"
  235. >
  236. <Select
  237. v-model="newStatus.contentType"
  238. class="input form-control"
  239. :attrs="{ 'aria-label': $t('post_status.content_type_selection') }"
  240. >
  241. <option
  242. v-for="postFormat in postFormats"
  243. :key="postFormat"
  244. :value="postFormat"
  245. >
  246. {{ $t(`post_status.content_type["${postFormat}"]`) }}
  247. </option>
  248. </Select>
  249. </div>
  250. <div
  251. v-if="postFormats.length === 1 && postFormats[0] !== 'text/plain'"
  252. class="text-format"
  253. >
  254. <span class="only-format">
  255. {{ $t(`post_status.content_type["${postFormats[0]}"]`) }}
  256. </span>
  257. </div>
  258. </div>
  259. </div>
  260. <poll-form
  261. v-if="pollsAvailable"
  262. ref="pollForm"
  263. :visible="pollFormVisible"
  264. :params="newStatus.poll"
  265. />
  266. <span
  267. v-if="!disableDraft && shouldAutoSaveDraft"
  268. class="auto-save-status"
  269. >
  270. {{ autoSaveState }}
  271. </span>
  272. <div
  273. ref="bottom"
  274. class="form-bottom"
  275. >
  276. <div class="form-bottom-left">
  277. <media-upload
  278. ref="mediaUpload"
  279. class="media-upload-icon"
  280. :drop-files="dropFiles"
  281. :disabled="uploadFileLimitReached"
  282. @uploading="startedUploadingFiles"
  283. @uploaded="addMediaFile"
  284. @upload-failed="uploadFailed"
  285. @all-uploaded="finishedUploadingFiles"
  286. />
  287. <button
  288. class="emoji-icon button-unstyled"
  289. :title="$t('emoji.add_emoji')"
  290. @click="showEmojiPicker"
  291. >
  292. <FAIcon icon="smile-beam" />
  293. </button>
  294. <button
  295. v-if="pollsAvailable"
  296. class="poll-icon button-unstyled"
  297. :class="{ selected: pollFormVisible }"
  298. :title="$t('polls.add_poll')"
  299. @click="togglePollForm"
  300. >
  301. <FAIcon icon="poll-h" />
  302. </button>
  303. </div>
  304. <div class="btn-group post-button-group">
  305. <button
  306. class="btn button-default post-button"
  307. :disabled="isOverLengthLimit || posting || uploadingFiles || disableSubmit"
  308. @click.stop.prevent="postStatus($event, newStatus)"
  309. >
  310. <template v-if="posting">
  311. {{ $t('post_status.posting') }}
  312. </template>
  313. <template v-else>
  314. {{ $t('post_status.post') }}
  315. </template>
  316. </button>
  317. <Popover
  318. v-if="!hideExtraActions"
  319. class="more-post-actions"
  320. :normal-button="true"
  321. trigger="click"
  322. placement="bottom"
  323. :offset="{ y: 5 }"
  324. >
  325. <template #trigger>
  326. <FAIcon
  327. class="fa-scale-110 fa-old-padding"
  328. icon="chevron-down"
  329. />
  330. </template>
  331. <template #content="{close}">
  332. <div
  333. class="dropdown-menu"
  334. role="menu"
  335. >
  336. <button
  337. v-if="!hideDraft || !disableDraft"
  338. class="menu-item dropdown-item"
  339. role="menu"
  340. :disabled="!safeToSaveDraft && saveable"
  341. :class="{ disabled: !safeToSaveDraft }"
  342. @click.prevent="saveDraft"
  343. @click="close"
  344. >
  345. <template v-if="closeable">
  346. {{ $t('post_status.save_to_drafts_and_close_button') }}
  347. </template>
  348. <template v-else>
  349. {{ $t('post_status.save_to_drafts_button') }}
  350. </template>
  351. </button>
  352. </div>
  353. </template>
  354. </Popover>
  355. </div>
  356. </div>
  357. <div
  358. v-show="showDropIcon !== 'hide'"
  359. :style="{ animation: showDropIcon === 'show' ? 'fade-in 0.25s' : 'fade-out 0.5s' }"
  360. class="drop-indicator"
  361. @dragleave="fileDragStop"
  362. @drop.stop="fileDrop"
  363. >
  364. <FAIcon :icon="uploadFileLimitReached ? 'ban' : 'upload'" />
  365. </div>
  366. <div
  367. v-if="error"
  368. class="alert error"
  369. >
  370. Error: {{ error }}
  371. <button
  372. class="button-unstyled"
  373. @click="clearError"
  374. >
  375. <FAIcon
  376. class="fa-scale-110 fa-old-padding"
  377. icon="times"
  378. />
  379. </button>
  380. </div>
  381. <gallery
  382. v-if="newStatus.files && newStatus.files.length > 0"
  383. class="attachments"
  384. :grid="true"
  385. :nsfw="false"
  386. :attachments="newStatus.files"
  387. :descriptions="newStatus.mediaDescriptions"
  388. :set-media="() => $store.dispatch('setMedia', newStatus.files)"
  389. :editable="true"
  390. :edit-attachment="editAttachment"
  391. :remove-attachment="removeMediaFile"
  392. :shift-up-attachment="newStatus.files.length > 1 && shiftUpMediaFile"
  393. :shift-dn-attachment="newStatus.files.length > 1 && shiftDnMediaFile"
  394. @play="$emit('mediaplay', attachment.id)"
  395. @pause="$emit('mediapause', attachment.id)"
  396. />
  397. <div
  398. v-if="newStatus.files.length > 0 && !disableSensitivityCheckbox"
  399. class="upload_settings"
  400. >
  401. <Checkbox v-model="newStatus.nsfw">
  402. {{ $t('post_status.attachments_sensitive') }}
  403. </Checkbox>
  404. </div>
  405. </form>
  406. <DraftCloser
  407. ref="draftCloser"
  408. @save="saveAndCloseDraft"
  409. @discard="discardAndCloseDraft"
  410. />
  411. </div>
  412. </template>
  413. <script src="./post_status_form.js"></script>
  414. <style src="./post_status_form.scss" lang="scss"></style>