ContextMenu.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. <template>
  2. <div class="modal-stack">
  3. <b-modal ref="ctxModal"
  4. id="ctx-modal"
  5. hide-header
  6. hide-footer
  7. centered
  8. rounded
  9. size="sm"
  10. body-class="list-group-flush p-0 rounded">
  11. <div class="list-group text-center">
  12. <div v-if="status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer" @click="ctxMenuGoToPost()">View Post</div>
  13. <div v-if="status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer" @click="ctxMenuGoToProfile()">View Profile</div>
  14. <!-- <div v-if="status && status.local == true && !status.in_reply_to_id" class="list-group-item rounded cursor-pointer" @click="ctxMenuEmbed()">Embed</div>
  15. <div class="list-group-item rounded cursor-pointer" @click="ctxMenuCopyLink()">Copy Link</div> -->
  16. <div v-if="status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer" @click="ctxMenuShare()">Share</div>
  17. <div v-if="status && profile && profile.is_admin == true && status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer" @click="ctxModMenuShow()">Moderation Tools</div>
  18. <div v-if="status && status.account.id != profile.id" class="list-group-item rounded cursor-pointer text-danger" @click="ctxMenuReportPost()">Report</div>
  19. <div v-if="status && profile.id == status.account.id && status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer text-danger" @click="archivePost(status)">Archive</div>
  20. <div v-if="status && profile.id == status.account.id && status.visibility == 'archived'" class="list-group-item rounded cursor-pointer text-danger" @click="unarchivePost(status)">Unarchive</div>
  21. <div v-if="status && (profile.is_admin || profile.id == status.account.id) && status.visibility !== 'archived'" class="list-group-item rounded cursor-pointer text-danger" @click="deletePost(status)">Delete</div>
  22. <div class="list-group-item rounded cursor-pointer text-lighter" @click="closeCtxMenu()">Cancel</div>
  23. </div>
  24. </b-modal>
  25. <b-modal ref="ctxModModal"
  26. id="ctx-mod-modal"
  27. hide-header
  28. hide-footer
  29. centered
  30. rounded
  31. size="sm"
  32. body-class="list-group-flush p-0 rounded">
  33. <div class="list-group text-center">
  34. <p class="py-2 px-3 mb-0">
  35. <div class="text-center font-weight-bold text-danger">Moderation Tools</div>
  36. <div class="small text-center text-muted">Select one of the following options</div>
  37. </p>
  38. <div class="list-group-item rounded cursor-pointer" @click="moderatePost(status, 'unlist')">Unlist from Timelines</div>
  39. <div v-if="status.sensitive" class="list-group-item rounded cursor-pointer" @click="moderatePost(status, 'remcw')">Remove Content Warning</div>
  40. <div v-else class="list-group-item rounded cursor-pointer" @click="moderatePost(status, 'addcw')">Add Content Warning</div>
  41. <div class="list-group-item rounded cursor-pointer" @click="moderatePost(status, 'spammer')">
  42. Mark as Spammer<br />
  43. <span class="small">Unlist + CW existing and future posts</span>
  44. </div>
  45. <!-- <div class="list-group-item rounded cursor-pointer" @click="ctxModOtherMenuShow()">Other</div> -->
  46. <div class="list-group-item rounded cursor-pointer text-lighter" @click="ctxModMenuClose()">Cancel</div>
  47. </div>
  48. </b-modal>
  49. <b-modal ref="ctxModOtherModal"
  50. id="ctx-mod-other-modal"
  51. hide-header
  52. hide-footer
  53. centered
  54. rounded
  55. size="sm"
  56. body-class="list-group-flush p-0 rounded">
  57. <div class="list-group text-center">
  58. <p class="py-2 px-3 mb-0">
  59. <div class="text-center font-weight-bold text-danger">Moderation Tools</div>
  60. <div class="small text-center text-muted">Select one of the following options</div>
  61. </p>
  62. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="confirmModal()">Unlist Posts</div>
  63. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="confirmModal()">Moderation Log</div>
  64. <div class="list-group-item rounded cursor-pointer text-lighter" @click="ctxModOtherMenuClose()">Cancel</div>
  65. </div>
  66. </b-modal>
  67. <b-modal ref="ctxShareModal"
  68. id="ctx-share-modal"
  69. title="Share"
  70. hide-footer
  71. hide-header
  72. centered
  73. rounded
  74. size="sm"
  75. body-class="list-group-flush p-0 rounded text-center">
  76. <div class="list-group-item rounded cursor-pointer" @click="shareStatus(status, $event)">{{status.reblogged ? 'Unshare' : 'Share'}} to Followers</div>
  77. <div class="list-group-item rounded cursor-pointer" @click="ctxMenuCopyLink()">Copy Link</div>
  78. <div v-if="status && status.local == true && !status.in_reply_to_id" class="list-group-item rounded cursor-pointer" @click="ctxMenuEmbed()">Embed</div>
  79. <!-- <div class="list-group-item rounded cursor-pointer border-top-0">Email</div>
  80. <div class="list-group-item rounded cursor-pointer">Facebook</div>
  81. <div class="list-group-item rounded cursor-pointer">Mastodon</div>
  82. <div class="list-group-item rounded cursor-pointer">Pinterest</div>
  83. <div class="list-group-item rounded cursor-pointer">Pixelfed</div>
  84. <div class="list-group-item rounded cursor-pointer">Twitter</div>
  85. <div class="list-group-item rounded cursor-pointer">VK</div> -->
  86. <div class="list-group-item rounded cursor-pointer text-lighter" @click="closeCtxShareMenu()">Cancel</div>
  87. </b-modal>
  88. <b-modal ref="ctxEmbedModal"
  89. id="ctx-embed-modal"
  90. hide-header
  91. hide-footer
  92. centered
  93. rounded
  94. size="md"
  95. body-class="p-2 rounded">
  96. <div>
  97. <div class="form-group">
  98. <textarea class="form-control disabled text-monospace" rows="8" style="overflow-y:hidden;border: 1px solid #efefef; font-size: 12px; line-height: 18px; margin: 0 0 7px;resize:none;" v-model="ctxEmbedPayload" disabled=""></textarea>
  99. </div>
  100. <div class="form-group pl-2 d-flex justify-content-center">
  101. <div class="form-check mr-3">
  102. <input class="form-check-input" type="checkbox" v-model="ctxEmbedShowCaption" :disabled="ctxEmbedCompactMode == true">
  103. <label class="form-check-label font-weight-light">
  104. Show Caption
  105. </label>
  106. </div>
  107. <div class="form-check mr-3">
  108. <input class="form-check-input" type="checkbox" v-model="ctxEmbedShowLikes" :disabled="ctxEmbedCompactMode == true">
  109. <label class="form-check-label font-weight-light">
  110. Show Likes
  111. </label>
  112. </div>
  113. <div class="form-check">
  114. <input class="form-check-input" type="checkbox" v-model="ctxEmbedCompactMode">
  115. <label class="form-check-label font-weight-light">
  116. Compact Mode
  117. </label>
  118. </div>
  119. </div>
  120. <hr>
  121. <button :class="copiedEmbed ? 'btn btn-primary btn-block btn-sm py-1 font-weight-bold disabed': 'btn btn-primary btn-block btn-sm py-1 font-weight-bold'" @click="ctxCopyEmbed" :disabled="copiedEmbed">{{copiedEmbed ? 'Embed Code Copied!' : 'Copy Embed Code'}}</button>
  122. <p class="mb-0 px-2 small text-muted">By using this embed, you agree to our <a href="/site/terms">Terms of Use</a></p>
  123. </div>
  124. </b-modal>
  125. <b-modal ref="ctxReport"
  126. id="ctx-report"
  127. hide-header
  128. hide-footer
  129. centered
  130. rounded
  131. size="sm"
  132. body-class="list-group-flush p-0 rounded">
  133. <p class="py-2 px-3 mb-0">
  134. <div class="text-center font-weight-bold text-danger">Report</div>
  135. <div class="small text-center text-muted">Select one of the following options</div>
  136. </p>
  137. <div class="list-group text-center">
  138. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('spam')">Spam</div>
  139. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('sensitive')">Sensitive Content</div>
  140. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('abusive')">Abusive or Harmful</div>
  141. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="openCtxReportOtherMenu()">Other</div>
  142. <!-- <div class="list-group-item rounded cursor-pointer" @click="ctxReportMenuGoBack()">Go Back</div> -->
  143. <div class="list-group-item rounded cursor-pointer text-lighter" @click="ctxReportMenuGoBack()">Cancel</div>
  144. </div>
  145. </b-modal>
  146. <b-modal ref="ctxReportOther"
  147. id="ctx-report-other"
  148. hide-header
  149. hide-footer
  150. centered
  151. rounded
  152. size="sm"
  153. body-class="list-group-flush p-0 rounded">
  154. <p class="py-2 px-3 mb-0">
  155. <div class="text-center font-weight-bold text-danger">Report</div>
  156. <div class="small text-center text-muted">Select one of the following options</div>
  157. </p>
  158. <div class="list-group text-center">
  159. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('underage')">Underage Account</div>
  160. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('copyright')">Copyright Infringement</div>
  161. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('impersonation')">Impersonation</div>
  162. <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('scam')">Scam or Fraud</div>
  163. <!-- <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('terrorism')">Terrorism Related</div> -->
  164. <!-- <div class="list-group-item rounded cursor-pointer font-weight-bold" @click="sendReport('other')">Other or Not listed</div> -->
  165. <!-- <div class="list-group-item rounded cursor-pointer" @click="ctxReportOtherMenuGoBack()">Go Back</div> -->
  166. <div class="list-group-item rounded cursor-pointer text-lighter" @click="ctxReportOtherMenuGoBack()">Cancel</div>
  167. </div>
  168. </b-modal>
  169. <b-modal ref="ctxConfirm"
  170. id="ctx-confirm"
  171. hide-header
  172. hide-footer
  173. centered
  174. rounded
  175. size="sm"
  176. body-class="list-group-flush p-0 rounded">
  177. <div class="d-flex align-items-center justify-content-center py-3">
  178. <div>{{ this.confirmModalTitle }}</div>
  179. </div>
  180. <div class="d-flex border-top btn-group btn-group-block rounded-0" role="group">
  181. <button type="button" class="btn btn-outline-lighter border-left-0 border-top-0 border-bottom-0 border-right py-2" style="color: rgb(0,122,255) !important;" @click.prevent="confirmModalCancel()">Cancel</button>
  182. <button type="button" class="btn btn-outline-lighter border-0" style="color: rgb(0,122,255) !important;" @click.prevent="confirmModalConfirm()">Confirm</button>
  183. </div>
  184. </b-modal>
  185. </div>
  186. </template>
  187. <script type="text/javascript">
  188. export default {
  189. props: [
  190. 'status',
  191. 'profile'
  192. ],
  193. data() {
  194. return {
  195. ctxMenuStatus: false,
  196. ctxMenuRelationship: false,
  197. ctxEmbedPayload: false,
  198. copiedEmbed: false,
  199. replySending: false,
  200. ctxEmbedShowCaption: true,
  201. ctxEmbedShowLikes: false,
  202. ctxEmbedCompactMode: false,
  203. confirmModalTitle: 'Are you sure?',
  204. confirmModalIdentifer: null,
  205. confirmModalType: false,
  206. }
  207. },
  208. watch: {
  209. ctxEmbedShowCaption: function (n,o) {
  210. if(n == true) {
  211. this.ctxEmbedCompactMode = false;
  212. }
  213. let mode = this.ctxEmbedCompactMode ? 'compact' : 'full';
  214. this.ctxEmbedPayload = window.App.util.embed.post(this.ctxMenuStatus.url, this.ctxEmbedShowCaption, this.ctxEmbedShowLikes, mode);
  215. },
  216. ctxEmbedShowLikes: function (n,o) {
  217. if(n == true) {
  218. this.ctxEmbedCompactMode = false;
  219. }
  220. let mode = this.ctxEmbedCompactMode ? 'compact' : 'full';
  221. this.ctxEmbedPayload = window.App.util.embed.post(this.ctxMenuStatus.url, this.ctxEmbedShowCaption, this.ctxEmbedShowLikes, mode);
  222. },
  223. ctxEmbedCompactMode: function (n,o) {
  224. if(n == true) {
  225. this.ctxEmbedShowCaption = false;
  226. this.ctxEmbedShowLikes = false;
  227. }
  228. let mode = this.ctxEmbedCompactMode ? 'compact' : 'full';
  229. this.ctxEmbedPayload = window.App.util.embed.post(this.ctxMenuStatus.url, this.ctxEmbedShowCaption, this.ctxEmbedShowLikes, mode);
  230. }
  231. },
  232. methods: {
  233. open() {
  234. this.ctxMenu();
  235. },
  236. ctxMenu() {
  237. this.ctxMenuStatus = this.status;
  238. this.ctxEmbedPayload = window.App.util.embed.post(this.status.url);
  239. if(this.status.account.id == this.profile.id) {
  240. this.ctxMenuRelationship = false;
  241. this.$refs.ctxModal.show();
  242. } else {
  243. axios.get('/api/pixelfed/v1/accounts/relationships', {
  244. params: {
  245. 'id[]': this.status.account.id
  246. }
  247. }).then(res => {
  248. this.ctxMenuRelationship = res.data[0];
  249. this.$refs.ctxModal.show();
  250. });
  251. }
  252. },
  253. closeCtxMenu() {
  254. this.copiedEmbed = false;
  255. this.ctxMenuStatus = false;
  256. this.ctxMenuRelationship = false;
  257. this.$refs.ctxModal.hide();
  258. this.$refs.ctxReport.hide();
  259. this.$refs.ctxReportOther.hide();
  260. this.closeModals();
  261. },
  262. ctxMenuCopyLink() {
  263. let status = this.ctxMenuStatus;
  264. navigator.clipboard.writeText(status.url);
  265. this.closeModals();
  266. return;
  267. },
  268. ctxMenuGoToPost() {
  269. let status = this.ctxMenuStatus;
  270. window.location.href = this.statusUrl(status);
  271. this.closeCtxMenu();
  272. return;
  273. },
  274. ctxMenuGoToProfile() {
  275. let status = this.ctxMenuStatus;
  276. window.location.href = this.profileUrl(status);
  277. this.closeCtxMenu();
  278. return;
  279. },
  280. ctxMenuReportPost() {
  281. this.$refs.ctxModal.hide();
  282. this.$refs.ctxReport.show();
  283. return;
  284. },
  285. ctxMenuEmbed() {
  286. this.closeModals();
  287. this.$refs.ctxEmbedModal.show();
  288. },
  289. ctxMenuShare() {
  290. this.$refs.ctxModal.hide();
  291. this.$refs.ctxShareModal.show();
  292. },
  293. closeCtxShareMenu() {
  294. this.$refs.ctxShareModal.hide();
  295. this.$refs.ctxModal.show();
  296. },
  297. ctxCopyEmbed() {
  298. navigator.clipboard.writeText(this.ctxEmbedPayload);
  299. this.ctxEmbedShowCaption = true;
  300. this.ctxEmbedShowLikes = false;
  301. this.ctxEmbedCompactMode = false;
  302. this.$refs.ctxEmbedModal.hide();
  303. },
  304. ctxModMenuShow() {
  305. this.$refs.ctxModal.hide();
  306. this.$refs.ctxModModal.show();
  307. },
  308. ctxModOtherMenuShow() {
  309. this.$refs.ctxModal.hide();
  310. this.$refs.ctxModModal.hide();
  311. this.$refs.ctxModOtherModal.show();
  312. },
  313. ctxModMenu() {
  314. this.$refs.ctxModal.hide();
  315. },
  316. ctxModMenuClose() {
  317. this.closeModals();
  318. },
  319. ctxModOtherMenuClose() {
  320. this.closeModals();
  321. this.$refs.ctxModModal.show();
  322. },
  323. formatCount(count) {
  324. return App.util.format.count(count);
  325. },
  326. openCtxReportOtherMenu() {
  327. let s = this.ctxMenuStatus;
  328. this.closeCtxMenu();
  329. this.ctxMenuStatus = s;
  330. this.$refs.ctxReportOther.show();
  331. },
  332. ctxReportMenuGoBack() {
  333. this.$refs.ctxReportOther.hide();
  334. this.$refs.ctxReport.hide();
  335. this.$refs.ctxModal.show();
  336. },
  337. ctxReportOtherMenuGoBack() {
  338. this.$refs.ctxReportOther.hide();
  339. this.$refs.ctxModal.hide();
  340. this.$refs.ctxReport.show();
  341. },
  342. sendReport(type) {
  343. let id = this.ctxMenuStatus.id;
  344. swal({
  345. 'title': 'Confirm Report',
  346. 'text': 'Are you sure you want to report this post?',
  347. 'icon': 'warning',
  348. 'buttons': true,
  349. 'dangerMode': true
  350. }).then((res) => {
  351. if(res) {
  352. axios.post('/i/report/', {
  353. 'report': type,
  354. 'type': 'post',
  355. 'id': id,
  356. }).then(res => {
  357. this.closeCtxMenu();
  358. swal('Report Sent!', 'We have successfully received your report.', 'success');
  359. }).catch(err => {
  360. swal('Oops!', 'There was an issue reporting this post.', 'error');
  361. })
  362. } else {
  363. this.closeCtxMenu();
  364. }
  365. });
  366. },
  367. closeModals() {
  368. this.$refs.ctxModal.hide();
  369. this.$refs.ctxModModal.hide();
  370. this.$refs.ctxModOtherModal.hide();
  371. this.$refs.ctxShareModal.hide();
  372. this.$refs.ctxEmbedModal.hide();
  373. this.$refs.ctxReport.hide();
  374. this.$refs.ctxReportOther.hide();
  375. this.$refs.ctxConfirm.hide();
  376. },
  377. openCtxStatusModal() {
  378. this.closeModals();
  379. this.$refs.ctxStatusModal.show();
  380. },
  381. openConfirmModal() {
  382. this.closeModals();
  383. this.$refs.ctxConfirm.show();
  384. },
  385. closeConfirmModal() {
  386. this.closeModals();
  387. this.confirmModalTitle = 'Are you sure?';
  388. this.confirmModalType = false;
  389. this.confirmModalIdentifer = null;
  390. },
  391. confirmModalConfirm() {
  392. switch(this.confirmModalType) {
  393. case 'post.delete':
  394. axios.post('/i/delete', {
  395. type: 'status',
  396. item: this.confirmModalIdentifer
  397. }).then(res => {
  398. this.feed = this.feed.filter(s => {
  399. return s.id != this.confirmModalIdentifer;
  400. });
  401. this.closeConfirmModal();
  402. }).catch(err => {
  403. this.closeConfirmModal();
  404. swal('Error', 'Something went wrong. Please try again later.', 'error');
  405. });
  406. break;
  407. }
  408. this.closeConfirmModal();
  409. },
  410. confirmModalCancel() {
  411. this.closeConfirmModal();
  412. },
  413. moderatePost(status, action, $event) {
  414. let username = status.account.username;
  415. let pid = status.id;
  416. let msg = '';
  417. let self = this;
  418. switch(action) {
  419. case 'addcw':
  420. msg = 'Are you sure you want to add a content warning to this post?';
  421. swal({
  422. title: 'Confirm',
  423. text: msg,
  424. icon: 'warning',
  425. buttons: true,
  426. dangerMode: true
  427. }).then(res => {
  428. if(res) {
  429. axios.post('/api/v2/moderator/action', {
  430. action: action,
  431. item_id: status.id,
  432. item_type: 'status'
  433. }).then(res => {
  434. swal('Success', 'Successfully added content warning', 'success');
  435. status.sensitive = true;
  436. self.closeModals();
  437. self.ctxModMenuClose();
  438. }).catch(err => {
  439. swal(
  440. 'Error',
  441. 'Something went wrong, please try again later.',
  442. 'error'
  443. );
  444. self.closeModals();
  445. self.ctxModMenuClose();
  446. });
  447. }
  448. });
  449. break;
  450. case 'remcw':
  451. msg = 'Are you sure you want to remove the content warning on this post?';
  452. swal({
  453. title: 'Confirm',
  454. text: msg,
  455. icon: 'warning',
  456. buttons: true,
  457. dangerMode: true
  458. }).then(res => {
  459. if(res) {
  460. axios.post('/api/v2/moderator/action', {
  461. action: action,
  462. item_id: status.id,
  463. item_type: 'status'
  464. }).then(res => {
  465. swal('Success', 'Successfully added content warning', 'success');
  466. status.sensitive = false;
  467. self.closeModals();
  468. self.ctxModMenuClose();
  469. }).catch(err => {
  470. swal(
  471. 'Error',
  472. 'Something went wrong, please try again later.',
  473. 'error'
  474. );
  475. self.closeModals();
  476. self.ctxModMenuClose();
  477. });
  478. }
  479. });
  480. break;
  481. case 'unlist':
  482. msg = 'Are you sure you want to unlist this post?';
  483. swal({
  484. title: 'Confirm',
  485. text: msg,
  486. icon: 'warning',
  487. buttons: true,
  488. dangerMode: true
  489. }).then(res => {
  490. if(res) {
  491. axios.post('/api/v2/moderator/action', {
  492. action: action,
  493. item_id: status.id,
  494. item_type: 'status'
  495. }).then(res => {
  496. this.feed = this.feed.filter(f => {
  497. return f.id != status.id;
  498. });
  499. swal('Success', 'Successfully unlisted post', 'success');
  500. self.closeModals();
  501. self.ctxModMenuClose();
  502. }).catch(err => {
  503. self.closeModals();
  504. self.ctxModMenuClose();
  505. swal(
  506. 'Error',
  507. 'Something went wrong, please try again later.',
  508. 'error'
  509. );
  510. });
  511. }
  512. });
  513. break;
  514. case 'spammer':
  515. msg = 'Are you sure you want to mark this user as a spammer? All existing and future posts will be unlisted on timelines and a content warning will be applied.';
  516. swal({
  517. title: 'Confirm',
  518. text: msg,
  519. icon: 'warning',
  520. buttons: true,
  521. dangerMode: true
  522. }).then(res => {
  523. if(res) {
  524. axios.post('/api/v2/moderator/action', {
  525. action: action,
  526. item_id: status.id,
  527. item_type: 'status'
  528. }).then(res => {
  529. swal('Success', 'Successfully marked account as spammer', 'success');
  530. self.closeModals();
  531. self.ctxModMenuClose();
  532. }).catch(err => {
  533. self.closeModals();
  534. self.ctxModMenuClose();
  535. swal(
  536. 'Error',
  537. 'Something went wrong, please try again later.',
  538. 'error'
  539. );
  540. });
  541. }
  542. });
  543. break;
  544. }
  545. },
  546. shareStatus(status, $event) {
  547. if($('body').hasClass('loggedIn') == false) {
  548. return;
  549. }
  550. this.closeModals();
  551. axios.post('/i/share', {
  552. item: status.id
  553. }).then(res => {
  554. status.reblogs_count = res.data.count;
  555. status.reblogged = !status.reblogged;
  556. if(status.reblogged) {
  557. swal('Success', 'You shared this post', 'success');
  558. } else {
  559. swal('Success', 'You unshared this post', 'success');
  560. }
  561. }).catch(err => {
  562. swal('Error', 'Something went wrong, please try again later.', 'error');
  563. });
  564. },
  565. statusUrl(status) {
  566. if(status.account.local == true) {
  567. return status.url;
  568. }
  569. return '/i/web/post/_/' + status.account.id + '/' + status.id;
  570. },
  571. profileUrl(status) {
  572. if(status.account.local == true) {
  573. return status.account.url;
  574. }
  575. return '/i/web/profile/_/' + status.account.id;
  576. },
  577. deletePost(status) {
  578. if($('body').hasClass('loggedIn') == false || this.ownerOrAdmin(status) == false) {
  579. return;
  580. }
  581. if(window.confirm('Are you sure you want to delete this post?') == false) {
  582. return;
  583. }
  584. axios.post('/i/delete', {
  585. type: 'status',
  586. item: status.id
  587. }).then(res => {
  588. this.$emit('status-delete', status.id);
  589. this.closeModals();
  590. }).catch(err => {
  591. swal('Error', 'Something went wrong. Please try again later.', 'error');
  592. });
  593. },
  594. owner(status) {
  595. return this.profile.id === status.account.id;
  596. },
  597. admin() {
  598. return this.profile.is_admin == true;
  599. },
  600. ownerOrAdmin(status) {
  601. return this.owner(status) || this.admin();
  602. },
  603. archivePost(status) {
  604. if(window.confirm('Are you sure you want to archive this post?') == false) {
  605. return;
  606. }
  607. axios.post('/api/pixelfed/v2/status/' + status.id + '/archive')
  608. .then(res => {
  609. this.$emit('status-delete', status.id);
  610. this.closeModals();
  611. });
  612. },
  613. unarchivePost(status) {
  614. if(window.confirm('Are you sure you want to unarchive this post?') == false) {
  615. return;
  616. }
  617. axios.post('/api/pixelfed/v2/status/' + status.id + '/unarchive')
  618. .then(res => {
  619. this.closeModals();
  620. });
  621. }
  622. }
  623. }
  624. </script>