233 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<GenericConfirmationDialog
 | 
						|
  {id}
 | 
						|
  {label}
 | 
						|
  {title}
 | 
						|
  className="report-dialog-contents"
 | 
						|
  {positiveText}
 | 
						|
  on:positive="doReport()">
 | 
						|
  <div class="report-dialog">
 | 
						|
    <div class="report-flex">
 | 
						|
      <div class="recent-statuses">
 | 
						|
        {#if loading}
 | 
						|
          <div class="loading-spinner-container">
 | 
						|
            <LoadingSpinner />
 | 
						|
          </div>
 | 
						|
        {:else}
 | 
						|
          <ul>
 | 
						|
            {#each displayStatuses as status (status.id)}
 | 
						|
              <li>
 | 
						|
                <input type="checkbox"
 | 
						|
                       id="status-report-{status.id}"
 | 
						|
                       name="status-report-{status.id}"
 | 
						|
                       checked={status.report}
 | 
						|
                       on:change="onChange(status.id, event)"
 | 
						|
                >
 | 
						|
                <label for="status-report-{status.id}">
 | 
						|
                  {status.text}
 | 
						|
                </label>
 | 
						|
              </li>
 | 
						|
            {/each}
 | 
						|
          </ul>
 | 
						|
        {/if}
 | 
						|
      </div>
 | 
						|
      <div class="report-info">
 | 
						|
        <p>You are reporting @{account.acct} to the moderators of {$currentInstance}.</p>
 | 
						|
        <label class="sr-only" id="comments-label">Additional comments</label>
 | 
						|
        <textarea bind:value="comment"
 | 
						|
                  placeholder="Additional comments"
 | 
						|
                  aria-labelledby="comments-label"
 | 
						|
                  maxlength="1000"></textarea>
 | 
						|
        {#if remoteInstance}
 | 
						|
          <p>Forward to the moderators of {remoteInstance} as well?</p>
 | 
						|
          <input type="checkbox"
 | 
						|
                 id="report-forward"
 | 
						|
                 name="report-forward"
 | 
						|
                 bind:checked="forward">
 | 
						|
          <label for="report-forward">
 | 
						|
            Forward to {remoteInstance}
 | 
						|
          </label>
 | 
						|
        {/if}
 | 
						|
      </div>
 | 
						|
    </div>
 | 
						|
  </div>
 | 
						|
</GenericConfirmationDialog>
 | 
						|
<style>
 | 
						|
  :global(.report-dialog-contents .confirmation-dialog-form) {
 | 
						|
    max-width: 80vw;
 | 
						|
  }
 | 
						|
  .report-dialog {
 | 
						|
    padding: 20px 40px;
 | 
						|
    overflow-y: auto;
 | 
						|
  }
 | 
						|
  .loading-spinner-container {
 | 
						|
    width: 100%;
 | 
						|
    height: 100%;
 | 
						|
    display: flex;
 | 
						|
    justify-content: center;
 | 
						|
    align-items: center;
 | 
						|
  }
 | 
						|
  ul {
 | 
						|
    list-style: none;
 | 
						|
    max-height: 30vh;
 | 
						|
    overflow-y: auto;
 | 
						|
    overflow-x: hidden;
 | 
						|
    border: 1px solid var(--main-border);
 | 
						|
  }
 | 
						|
  li {
 | 
						|
    padding: 10px 5px;
 | 
						|
    border-top: 1px solid var(--main-border);
 | 
						|
  }
 | 
						|
  li:first-child {
 | 
						|
    border-top: none;
 | 
						|
  }
 | 
						|
 | 
						|
  .recent-statuses label {
 | 
						|
    padding: 10px 5px;
 | 
						|
    display: -webkit-box;
 | 
						|
    -webkit-line-clamp: 5;
 | 
						|
    -webkit-box-orient: vertical;
 | 
						|
  }
 | 
						|
  textarea {
 | 
						|
    width: 100%;
 | 
						|
    overflow-y: auto;
 | 
						|
    max-height: 40vh;
 | 
						|
    font-size: 1.3em;
 | 
						|
    min-height: 100px;
 | 
						|
  }
 | 
						|
  p {
 | 
						|
    margin: 20px 0;
 | 
						|
  }
 | 
						|
 | 
						|
  .recent-statuses li {
 | 
						|
    display: flex;
 | 
						|
    flex-direction: row;
 | 
						|
    align-items: center;
 | 
						|
  }
 | 
						|
  .recent-statuses input {
 | 
						|
    margin-right: 10px;
 | 
						|
  }
 | 
						|
  .recent-statuses label {
 | 
						|
    width: 0;
 | 
						|
    flex: 1;
 | 
						|
    word-wrap: break-word;
 | 
						|
    overflow: hidden;
 | 
						|
    white-space: pre-wrap;
 | 
						|
    text-overflow: ellipsis;
 | 
						|
    border-left: 1px solid var(--main-border);
 | 
						|
    padding-left: 10px;
 | 
						|
  }
 | 
						|
 | 
						|
  .report-flex {
 | 
						|
    display: flex;
 | 
						|
    flex-direction: row;
 | 
						|
  }
 | 
						|
 | 
						|
  .report-flex > * {
 | 
						|
    flex: 1;
 | 
						|
  }
 | 
						|
 | 
						|
  .report-info {
 | 
						|
    margin-left: 20px;
 | 
						|
  }
 | 
						|
 | 
						|
  @media (max-width: 767px) {
 | 
						|
    .report-dialog {
 | 
						|
      padding: 20px;
 | 
						|
      overflow-x: hidden;
 | 
						|
      max-height: 65vh;
 | 
						|
    }
 | 
						|
    .report-flex {
 | 
						|
      flex-direction: column;
 | 
						|
    }
 | 
						|
    .report-info {
 | 
						|
      margin-left: 0;
 | 
						|
    }
 | 
						|
    textarea {
 | 
						|
      max-height: 20vh;
 | 
						|
    }
 | 
						|
    p, label {
 | 
						|
      word-wrap: break-word;
 | 
						|
    }
 | 
						|
    :global(.report-dialog-contents .confirmation-dialog-form) {
 | 
						|
      max-width: calc(100% - 20px);
 | 
						|
    }
 | 
						|
  }
 | 
						|
</style>
 | 
						|
<script>
 | 
						|
  import GenericConfirmationDialog from './GenericConfirmationDialog.html'
 | 
						|
  import LoadingSpinner from '../../LoadingSpinner.html'
 | 
						|
  import { show } from '../helpers/showDialog'
 | 
						|
  import { close } from '../helpers/closeDialog'
 | 
						|
  import { oncreate as onCreateDialog } from '../helpers/onCreateDialog'
 | 
						|
  import { getRecentStatusesForAccount } from '../../../_actions/getRecentStatusesForAccount'
 | 
						|
  import { statusHtmlToPlainText } from '../../../_utils/statusHtmlToPlainText'
 | 
						|
  import { toast } from '../../toast/toast'
 | 
						|
  import { store } from '../../../_store/store'
 | 
						|
  import { reportStatuses } from '../../../_actions/reportStatuses'
 | 
						|
 | 
						|
  export default {
 | 
						|
    async oncreate () {
 | 
						|
      onCreateDialog.call(this)
 | 
						|
      const { account, status, reportMap } = this.get()
 | 
						|
      if (status) {
 | 
						|
        reportMap[status.id] = true
 | 
						|
      }
 | 
						|
      try {
 | 
						|
        const recentStatuses = await getRecentStatusesForAccount(account.id)
 | 
						|
        console.log('recentStatuses', recentStatuses)
 | 
						|
        this.set({ recentStatuses })
 | 
						|
      } catch (err) {
 | 
						|
        console.error(err)
 | 
						|
        toast.say('Unable to load recent statuses: ' + (err.message || ''))
 | 
						|
      } finally {
 | 
						|
        this.set({ loading: false })
 | 
						|
      }
 | 
						|
    },
 | 
						|
    store: () => store,
 | 
						|
    data: () => ({
 | 
						|
      account: undefined,
 | 
						|
      status: undefined,
 | 
						|
      positiveText: 'Report',
 | 
						|
      reportMap: {},
 | 
						|
      recentStatuses: [],
 | 
						|
      loading: true,
 | 
						|
      forward: false,
 | 
						|
      comment: ''
 | 
						|
    }),
 | 
						|
    computed: {
 | 
						|
      displayStatuses: ({ statuses, reportMap }) => (
 | 
						|
        statuses.map(status => ({
 | 
						|
          id: status.id,
 | 
						|
          text: statusHtmlToPlainText(status.content, status.mentions) || '(No content)',
 | 
						|
          report: reportMap[status.id]
 | 
						|
        }))
 | 
						|
      ),
 | 
						|
      statuses: ({ status, recentStatuses }) => (
 | 
						|
        [status].concat((recentStatuses || []).filter(({ id }) => (!status || id !== status.id))).filter(Boolean)
 | 
						|
      ),
 | 
						|
      remoteInstance: ({ account }) => account.acct.split('@')[1]
 | 
						|
    },
 | 
						|
    methods: {
 | 
						|
      show,
 | 
						|
      close,
 | 
						|
      onChange (statusId, event) {
 | 
						|
        const report = event.target.checked
 | 
						|
        const { reportMap } = this.get()
 | 
						|
        reportMap[statusId] = report
 | 
						|
      },
 | 
						|
      async doReport () {
 | 
						|
        const { displayStatuses, account, comment, forward, reportMap } = this.get()
 | 
						|
        const statusIds = displayStatuses.map(({ id }) => id).filter(id => reportMap[id])
 | 
						|
        if (!statusIds.length) {
 | 
						|
          toast.say('No toots to report.')
 | 
						|
        } else {
 | 
						|
          await reportStatuses(account, statusIds, comment, forward)
 | 
						|
        }
 | 
						|
      }
 | 
						|
    },
 | 
						|
    components: {
 | 
						|
      GenericConfirmationDialog,
 | 
						|
      LoadingSpinner
 | 
						|
    }
 | 
						|
  }
 | 
						|
</script>
 |