ContextMenu.vue 22 KB

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