Add ability to exclude muted accounts

This commit is contained in:
Chocobozzz 2021-11-02 11:50:03 +01:00
parent 61f85385bb
commit 231ff4af3b
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
6 changed files with 79 additions and 43 deletions

View File

@ -24,21 +24,7 @@ export class VideoListComponent extends RestTable implements OnInit {
selectedVideos: Video[] = [] selectedVideos: Video[] = []
inputFilters: AdvancedInputFilter[] = [ inputFilters: AdvancedInputFilter[]
{
title: $localize`Advanced filters`,
children: [
{
queryParams: { search: 'isLocal:false' },
label: $localize`Remote videos`
},
{
queryParams: { search: 'isLocal:true' },
label: $localize`Local videos`
}
]
}
]
videoActionsOptions: VideoActionsDisplayType = { videoActionsOptions: VideoActionsDisplayType = {
playlist: false, playlist: false,
@ -52,7 +38,7 @@ export class VideoListComponent extends RestTable implements OnInit {
liveInfo: false liveInfo: false
} }
loading = false loading = true
constructor ( constructor (
protected route: ActivatedRoute, protected route: ActivatedRoute,
@ -72,6 +58,8 @@ export class VideoListComponent extends RestTable implements OnInit {
ngOnInit () { ngOnInit () {
this.initialize() this.initialize()
this.inputFilters = this.videoService.buildAdminInputFilter()
this.bulkVideoActions = [ this.bulkVideoActions = [
[ [
{ {

View File

@ -49,7 +49,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
schedulePublicationPossible = false schedulePublicationPossible = false
// So that it can be accessed in the template // So that it can be accessed in the template
protected readonly BASE_VIDEO_UPLOAD_URL = VideoService.BASE_VIDEO_URL + 'upload-resumable' protected readonly BASE_VIDEO_UPLOAD_URL = VideoService.BASE_VIDEO_URL + '/upload-resumable'
private uploadxOptions: UploadxOptions private uploadxOptions: UploadxOptions
private isUpdatingVideo = false private isUpdatingVideo = false

View File

@ -288,7 +288,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
private async handleRequestError (err: any) { private async handleRequestError (err: any) {
const errorBody = err.body as PeerTubeProblemDocument const errorBody = err.body as PeerTubeProblemDocument
if (errorBody.code === ServerErrorCode.DOES_NOT_RESPECT_FOLLOW_CONSTRAINTS && errorBody.originUrl) { if (errorBody?.code === ServerErrorCode.DOES_NOT_RESPECT_FOLLOW_CONSTRAINTS && errorBody.originUrl) {
const originUrl = errorBody.originUrl + (window.location.search ?? '') const originUrl = errorBody.originUrl + (window.location.search ?? '')
const res = await this.confirmService.confirm( const res = await this.confirmService.confirm(

View File

@ -1,13 +1,16 @@
import * as debug from 'debug'
import { SortMeta } from 'primeng/api' import { SortMeta } from 'primeng/api'
import { HttpParams } from '@angular/common/http' import { HttpParams } from '@angular/common/http'
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { ComponentPaginationLight } from './component-pagination.model' import { ComponentPaginationLight } from './component-pagination.model'
import { RestPagination } from './rest-pagination' import { RestPagination } from './rest-pagination'
const logger = debug('peertube:rest')
interface QueryStringFilterPrefixes { interface QueryStringFilterPrefixes {
[key: string]: { [key: string]: {
prefix: string prefix: string
handler?: (v: string) => string | number handler?: (v: string) => string | number | boolean
multiple?: boolean multiple?: boolean
isBoolean?: boolean isBoolean?: boolean
} }
@ -87,6 +90,8 @@ export class RestService {
const prefixeStrings = Object.values(prefixes) const prefixeStrings = Object.values(prefixes)
.map(p => p.prefix) .map(p => p.prefix)
logger(`Built tokens "${tokens.join(', ')}" for prefixes "${prefixeStrings.join(', ')}"`)
// Search is the querystring minus defined filters // Search is the querystring minus defined filters
const searchTokens = tokens.filter(t => { const searchTokens = tokens.filter(t => {
return prefixeStrings.every(prefixString => t.startsWith(prefixString) === false) return prefixeStrings.every(prefixString => t.startsWith(prefixString) === false)
@ -122,8 +127,12 @@ export class RestService {
: matchedTokens[0] : matchedTokens[0]
} }
const search = searchTokens.join(' ') || undefined
logger('Built search: ' + search, additionalFilters)
return { return {
search: searchTokens.join(' ') || undefined, search,
...additionalFilters ...additionalFilters
} }

View File

@ -18,7 +18,7 @@ export class VideoCaptionService {
) {} ) {}
listCaptions (videoId: number | string): Observable<ResultList<VideoCaption>> { listCaptions (videoId: number | string): Observable<ResultList<VideoCaption>> {
return this.authHttp.get<ResultList<VideoCaption>>(VideoService.BASE_VIDEO_URL + videoId + '/captions') return this.authHttp.get<ResultList<VideoCaption>>(`${VideoService.BASE_VIDEO_URL}/${videoId}/captions`)
.pipe( .pipe(
switchMap(captionsResult => { switchMap(captionsResult => {
return this.serverService.getServerLocale() return this.serverService.getServerLocale()
@ -41,7 +41,7 @@ export class VideoCaptionService {
} }
removeCaption (videoId: number | string, language: string) { removeCaption (videoId: number | string, language: string) {
return this.authHttp.delete(VideoService.BASE_VIDEO_URL + videoId + '/captions/' + language) return this.authHttp.delete(`${VideoService.BASE_VIDEO_URL}/${videoId}/captions/${language}`)
.pipe( .pipe(
map(this.restExtractor.extractDataBool), map(this.restExtractor.extractDataBool),
catchError(res => this.restExtractor.handleError(res)) catchError(res => this.restExtractor.handleError(res))
@ -52,7 +52,7 @@ export class VideoCaptionService {
const body = { captionfile } const body = { captionfile }
const data = objectToFormData(body) const data = objectToFormData(body)
return this.authHttp.put(VideoService.BASE_VIDEO_URL + videoId + '/captions/' + language, data) return this.authHttp.put(`${VideoService.BASE_VIDEO_URL}/${videoId}/captions/${language}`, data)
.pipe( .pipe(
map(this.restExtractor.extractDataBool), map(this.restExtractor.extractDataBool),
catchError(res => this.restExtractor.handleError(res)) catchError(res => this.restExtractor.handleError(res))

View File

@ -5,6 +5,7 @@ import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http'
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { ComponentPaginationLight, RestExtractor, RestPagination, RestService, ServerService, UserService } from '@app/core' import { ComponentPaginationLight, RestExtractor, RestPagination, RestService, ServerService, UserService } from '@app/core'
import { objectToFormData } from '@app/helpers' import { objectToFormData } from '@app/helpers'
import { AdvancedInputFilter } from '@app/shared/shared-forms'
import { import {
BooleanBothQuery, BooleanBothQuery,
FeedFormat, FeedFormat,
@ -60,18 +61,18 @@ export class VideoService {
) {} ) {}
getVideoViewUrl (uuid: string) { getVideoViewUrl (uuid: string) {
return VideoService.BASE_VIDEO_URL + '/' + uuid + '/views' return `${VideoService.BASE_VIDEO_URL}/${uuid}/views`
} }
getUserWatchingVideoUrl (uuid: string) { getUserWatchingVideoUrl (uuid: string) {
return VideoService.BASE_VIDEO_URL + '/' + uuid + '/watching' return `${VideoService.BASE_VIDEO_URL}/${uuid}/watching`
} }
getVideo (options: { videoId: string }): Observable<VideoDetails> { getVideo (options: { videoId: string }): Observable<VideoDetails> {
return this.serverService.getServerLocale() return this.serverService.getServerLocale()
.pipe( .pipe(
switchMap(translations => { switchMap(translations => {
return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + '/' + options.videoId) return this.authHttp.get<VideoDetailsServerModel>(`${VideoService.BASE_VIDEO_URL}/${options.videoId}`)
.pipe(map(videoHash => ({ videoHash, translations }))) .pipe(map(videoHash => ({ videoHash, translations })))
}), }),
map(({ videoHash, translations }) => new VideoDetails(videoHash, translations)), map(({ videoHash, translations }) => new VideoDetails(videoHash, translations)),
@ -111,7 +112,7 @@ export class VideoService {
const data = objectToFormData(body) const data = objectToFormData(body)
return this.authHttp.put(VideoService.BASE_VIDEO_URL + '/' + video.id, data) return this.authHttp.put(`${VideoService.BASE_VIDEO_URL}/${video.id}`, data)
.pipe( .pipe(
map(this.restExtractor.extractDataBool), map(this.restExtractor.extractDataBool),
catchError(err => this.restExtractor.handleError(err)) catchError(err => this.restExtractor.handleError(err))
@ -119,7 +120,7 @@ export class VideoService {
} }
uploadVideo (video: FormData) { uploadVideo (video: FormData) {
const req = new HttpRequest('POST', VideoService.BASE_VIDEO_URL + '/' + 'upload', video, { reportProgress: true }) const req = new HttpRequest('POST', `${VideoService.BASE_VIDEO_URL}/upload`, video, { reportProgress: true })
return this.authHttp return this.authHttp
.request<{ video: { id: number, uuid: string } }>(req) .request<{ video: { id: number, uuid: string } }>(req)
@ -204,25 +205,17 @@ export class VideoService {
} }
getAdminVideos ( getAdminVideos (
parameters: CommonVideoParams & { pagination: RestPagination, search?: string } options: CommonVideoParams & { pagination: RestPagination, search?: string }
): Observable<ResultList<Video>> { ): Observable<ResultList<Video>> {
const { pagination, search } = parameters const { pagination, search } = options
const include = VideoInclude.BLACKLISTED |
VideoInclude.BLOCKED_OWNER |
VideoInclude.HIDDEN_PRIVACY |
VideoInclude.NOT_PUBLISHED_STATE |
VideoInclude.FILES
let params = new HttpParams() let params = new HttpParams()
params = this.buildCommonVideosParams({ params, include, ...parameters }) params = this.buildCommonVideosParams({ params, ...options })
params = params.set('start', pagination.start.toString()) params = params.set('start', pagination.start.toString())
.set('count', pagination.count.toString()) .set('count', pagination.count.toString())
if (search) {
params = this.buildAdminParamsFromSearch(search, params) params = this.buildAdminParamsFromSearch(search, params)
}
return this.authHttp return this.authHttp
.get<ResultList<Video>>(VideoService.BASE_VIDEO_URL, { params }) .get<ResultList<Video>>(VideoService.BASE_VIDEO_URL, { params })
@ -321,7 +314,7 @@ export class VideoService {
return from(ids) return from(ids)
.pipe( .pipe(
concatMap(id => this.authHttp.delete(VideoService.BASE_VIDEO_URL + '/' + id)), concatMap(id => this.authHttp.delete(`${VideoService.BASE_VIDEO_URL}/${id}`)),
toArray(), toArray(),
catchError(err => this.restExtractor.handleError(err)) catchError(err => this.restExtractor.handleError(err))
) )
@ -413,7 +406,7 @@ export class VideoService {
} }
private setVideoRate (id: number, rateType: UserVideoRateType) { private setVideoRate (id: number, rateType: UserVideoRateType) {
const url = VideoService.BASE_VIDEO_URL + '/' + id + '/rate' const url = `${VideoService.BASE_VIDEO_URL}/${id}/rate`
const body: UserVideoRateUpdate = { const body: UserVideoRateUpdate = {
rating: rateType rating: rateType
} }
@ -460,14 +453,60 @@ export class VideoService {
return newParams return newParams
} }
buildAdminInputFilter (): AdvancedInputFilter[] {
return [
{
title: $localize`Videos scope`,
children: [
{
queryParams: { search: 'isLocal:false' },
label: $localize`Remote videos`
},
{
queryParams: { search: 'isLocal:true' },
label: $localize`Local videos`
}
]
},
{
title: $localize`Include/Exclude`,
children: [
{
queryParams: { search: 'excludeMuted' },
label: $localize`Exclude muted accounts`
}
]
}
]
}
private buildAdminParamsFromSearch (search: string, params: HttpParams) { private buildAdminParamsFromSearch (search: string, params: HttpParams) {
let include = VideoInclude.BLACKLISTED |
VideoInclude.BLOCKED_OWNER |
VideoInclude.HIDDEN_PRIVACY |
VideoInclude.NOT_PUBLISHED_STATE |
VideoInclude.FILES
if (!search) return this.restService.addObjectParams(params, { include })
const filters = this.restService.parseQueryStringFilter(search, { const filters = this.restService.parseQueryStringFilter(search, {
isLocal: { isLocal: {
prefix: 'isLocal:', prefix: 'isLocal:',
isBoolean: true isBoolean: true
},
excludeMuted: {
prefix: 'excludeMuted',
handler: () => true
} }
}) })
return this.restService.addObjectParams(params, filters) if (filters.excludeMuted) {
include &= ~VideoInclude.BLOCKED_OWNER
filters.excludeMuted = undefined
}
return this.restService.addObjectParams(params, { ...filters, include })
} }
} }