Add ability to exclude muted accounts

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

View File

@ -49,7 +49,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
schedulePublicationPossible = false
// 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 isUpdatingVideo = false

View File

@ -288,7 +288,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
private async handleRequestError (err: any) {
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 res = await this.confirmService.confirm(

View File

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

View File

@ -18,7 +18,7 @@ export class VideoCaptionService {
) {}
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(
switchMap(captionsResult => {
return this.serverService.getServerLocale()
@ -41,7 +41,7 @@ export class VideoCaptionService {
}
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(
map(this.restExtractor.extractDataBool),
catchError(res => this.restExtractor.handleError(res))
@ -52,7 +52,7 @@ export class VideoCaptionService {
const body = { captionfile }
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(
map(this.restExtractor.extractDataBool),
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 { ComponentPaginationLight, RestExtractor, RestPagination, RestService, ServerService, UserService } from '@app/core'
import { objectToFormData } from '@app/helpers'
import { AdvancedInputFilter } from '@app/shared/shared-forms'
import {
BooleanBothQuery,
FeedFormat,
@ -60,18 +61,18 @@ export class VideoService {
) {}
getVideoViewUrl (uuid: string) {
return VideoService.BASE_VIDEO_URL + '/' + uuid + '/views'
return `${VideoService.BASE_VIDEO_URL}/${uuid}/views`
}
getUserWatchingVideoUrl (uuid: string) {
return VideoService.BASE_VIDEO_URL + '/' + uuid + '/watching'
return `${VideoService.BASE_VIDEO_URL}/${uuid}/watching`
}
getVideo (options: { videoId: string }): Observable<VideoDetails> {
return this.serverService.getServerLocale()
.pipe(
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 })))
}),
map(({ videoHash, translations }) => new VideoDetails(videoHash, translations)),
@ -111,7 +112,7 @@ export class VideoService {
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(
map(this.restExtractor.extractDataBool),
catchError(err => this.restExtractor.handleError(err))
@ -119,7 +120,7 @@ export class VideoService {
}
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
.request<{ video: { id: number, uuid: string } }>(req)
@ -204,25 +205,17 @@ export class VideoService {
}
getAdminVideos (
parameters: CommonVideoParams & { pagination: RestPagination, search?: string }
options: CommonVideoParams & { pagination: RestPagination, search?: string }
): Observable<ResultList<Video>> {
const { pagination, search } = parameters
const include = VideoInclude.BLACKLISTED |
VideoInclude.BLOCKED_OWNER |
VideoInclude.HIDDEN_PRIVACY |
VideoInclude.NOT_PUBLISHED_STATE |
VideoInclude.FILES
const { pagination, search } = options
let params = new HttpParams()
params = this.buildCommonVideosParams({ params, include, ...parameters })
params = this.buildCommonVideosParams({ params, ...options })
params = params.set('start', pagination.start.toString())
.set('count', pagination.count.toString())
if (search) {
params = this.buildAdminParamsFromSearch(search, params)
}
return this.authHttp
.get<ResultList<Video>>(VideoService.BASE_VIDEO_URL, { params })
@ -321,7 +314,7 @@ export class VideoService {
return from(ids)
.pipe(
concatMap(id => this.authHttp.delete(VideoService.BASE_VIDEO_URL + '/' + id)),
concatMap(id => this.authHttp.delete(`${VideoService.BASE_VIDEO_URL}/${id}`)),
toArray(),
catchError(err => this.restExtractor.handleError(err))
)
@ -413,7 +406,7 @@ export class VideoService {
}
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 = {
rating: rateType
}
@ -460,14 +453,60 @@ export class VideoService {
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) {
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, {
isLocal: {
prefix: 'isLocal:',
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 })
}
}