1 import { omit } from 'lodash-es'
2 import { SortMeta } from 'primeng/api'
3 import { Observable } from 'rxjs'
4 import { catchError, map } from 'rxjs/operators'
5 import { HttpClient, HttpParams } from '@angular/common/http'
6 import { Injectable } from '@angular/core'
7 import { RestExtractor, RestPagination, RestService } from '@app/core'
8 import { I18n } from '@ngx-translate/i18n-polyfill'
13 AbusePredefinedReasonsString,
19 } from '@shared/models'
20 import { environment } from '../../../environments/environment'
23 export class AbuseService {
24 private static BASE_ABUSE_URL = environment.apiUrl + '/api/v1/abuses'
25 private static BASE_MY_ABUSE_URL = environment.apiUrl + '/api/v1/users/me/abuses'
29 private authHttp: HttpClient,
30 private restService: RestService,
31 private restExtractor: RestExtractor
34 getAdminAbuses (options: {
35 pagination: RestPagination,
38 }): Observable<ResultList<AdminAbuse>> {
39 const { pagination, sort, search } = options
40 const url = AbuseService.BASE_ABUSE_URL
42 let params = new HttpParams()
43 params = this.restService.addRestGetParams(params, pagination, sort)
46 params = this.buildParamsFromSearch(search, params)
49 return this.authHttp.get<ResultList<AdminAbuse>>(url, { params })
51 catchError(res => this.restExtractor.handleError(res))
55 getUserAbuses (options: {
56 pagination: RestPagination,
59 }): Observable<ResultList<UserAbuse>> {
60 const { pagination, sort, search } = options
61 const url = AbuseService.BASE_MY_ABUSE_URL
63 let params = new HttpParams()
64 params = this.restService.addRestGetParams(params, pagination, sort)
67 params = this.buildParamsFromSearch(search, params)
70 return this.authHttp.get<ResultList<UserAbuse>>(url, { params })
72 catchError(res => this.restExtractor.handleError(res))
76 reportVideo (parameters: AbuseCreate) {
77 const url = AbuseService.BASE_ABUSE_URL
79 const body = omit(parameters, ['id'])
81 return this.authHttp.post(url, body)
83 map(this.restExtractor.extractDataBool),
84 catchError(res => this.restExtractor.handleError(res))
88 updateAbuse (abuse: AdminAbuse, abuseUpdate: AbuseUpdate) {
89 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id
91 return this.authHttp.put(url, abuseUpdate)
93 map(this.restExtractor.extractDataBool),
94 catchError(res => this.restExtractor.handleError(res))
98 removeAbuse (abuse: AdminAbuse) {
99 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id
101 return this.authHttp.delete(url)
103 map(this.restExtractor.extractDataBool),
104 catchError(res => this.restExtractor.handleError(res))
108 addAbuseMessage (abuse: UserAbuse, message: string) {
109 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id + '/messages'
111 return this.authHttp.post(url, { message })
113 map(this.restExtractor.extractDataBool),
114 catchError(res => this.restExtractor.handleError(res))
118 listAbuseMessages (abuse: UserAbuse) {
119 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id + '/messages'
121 return this.authHttp.get<ResultList<AbuseMessage>>(url)
123 catchError(res => this.restExtractor.handleError(res))
127 deleteAbuseMessage (abuse: UserAbuse, abuseMessage: AbuseMessage) {
128 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id + '/messages/' + abuseMessage.id
130 return this.authHttp.delete(url)
132 map(this.restExtractor.extractDataBool),
133 catchError(res => this.restExtractor.handleError(res))
137 getPrefefinedReasons (type: AbuseFilter) {
138 let reasons: { id: AbusePredefinedReasonsString, label: string, description?: string, help?: string }[] = [
140 id: 'violentOrRepulsive',
141 label: this.i18n('Violent or repulsive'),
142 help: this.i18n('Contains offensive, violent, or coarse language or iconography.')
145 id: 'hatefulOrAbusive',
146 label: this.i18n('Hateful or abusive'),
147 help: this.i18n('Contains abusive, racist or sexist language or iconography.')
150 id: 'spamOrMisleading',
151 label: this.i18n('Spam, ad or false news'),
152 help: this.i18n('Contains marketing, spam, purposefully deceitful news, or otherwise misleading thumbnail/text/tags. Please provide reputable sources to report hoaxes.')
156 label: this.i18n('Privacy breach or doxxing'),
157 help: this.i18n('Contains personal information that could be used to track, identify, contact or impersonate someone (e.g. name, address, phone number, email, or credit card details).')
161 label: this.i18n('Copyright'),
162 help: this.i18n('Infringes your copyright wrt. the regional laws with which the server must comply.')
166 label: this.i18n('Breaks server rules'),
167 description: this.i18n('Anything not included in the above that breaks the terms of service, code of conduct, or general rules in place on the server.')
171 if (type === 'video') {
172 reasons = reasons.concat([
175 label: this.i18n('Thumbnails'),
176 help: this.i18n('The above can only be seen in thumbnails.')
180 label: this.i18n('Captions'),
181 help: this.i18n('The above can only be seen in captions (please describe which).')
189 private buildParamsFromSearch (search: string, params: HttpParams) {
190 const filters = this.restService.parseQueryStringFilter(search, {
195 if (v === 'accepted') return AbuseState.ACCEPTED
196 if (v === 'pending') return AbuseState.PENDING
197 if (v === 'rejected') return AbuseState.REJECTED
205 if (v === 'deleted') return v
206 if (v === 'blacklisted') return v
211 searchReporter: { prefix: 'reporter:' },
212 searchReportee: { prefix: 'reportee:' },
213 predefinedReason: { prefix: 'tag:' }
216 return this.restService.addObjectParams(params, filters)