Add ability to exclude muted accounts
This commit is contained in:
parent
61f85385bb
commit
231ff4af3b
|
@ -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 = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue