</h1>
<p-table
- [value]="followers" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" (onPage)="onPage($event)"
+ [value]="followers" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
+ [sortField]="sort.field" [sortOrder]="sort.order" (onPage)="onPage($event)"
+ [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} followers"
>
<ng-template pTemplate="caption">
<div class="caption">
- <div class="ml-auto has-feedback has-clear">
- <input
- type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
- (keyup)="onSearch($event)"
- >
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
+ <div class="ml-auto">
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
</ng-template>
@import '_variables';
@import '_mixins';
-.caption {
- justify-content: flex-end;
-
- input {
- @include peertube-input-text(250px);
- }
-}
-
a {
@include disable-default-a-behaviour;
display: inline-block;
const handle = follow.follower.name + '@' + follow.follower.host
this.notifier.success($localize`${handle} rejected from instance followers`)
- this.loadData()
+ this.reloadData()
},
err => {
const handle = follow.follower.name + '@' + follow.follower.host
this.notifier.success($localize`${handle} removed from instance followers`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
)
}
- protected loadData () {
+ protected reloadData () {
this.followService.getFollowers({ pagination: this.pagination, sort: this.sort, search: this.search })
.subscribe(
resultList => {
</h1>
<p-table
- [value]="following" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
+ [value]="following" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" (onPage)="onPage($event)"
+ [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} hosts"
>
</a>
</div>
- <div class="ml-auto has-feedback has-clear">
- <input
- type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
- (keyup)="onSearch($event)"
- >
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
+ <div class="ml-auto">
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
</ng-template>
}
}
-.caption {
- justify-content: flex-end;
-
- input {
- @include peertube-input-text(250px);
- }
-}
-
.follow-button {
@include create-button;
}
this.followService.follow(hosts).subscribe(
() => {
this.notifier.success($localize`Follow request(s) sent!`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
this.followService.unfollow(follow).subscribe(
() => {
this.notifier.success($localize`You are not following ${follow.following.host} anymore.`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
)
}
- protected loadData () {
+ protected reloadData () {
this.followService.getFollowing({ pagination: this.pagination, sort: this.sort, search: this.search })
.subscribe(
resultList => {
this.pagination.start = 0
this.saveSelectLocalStorage()
- this.loadData()
+ this.reloadData()
}
getRedundancyStrategy (redundancy: VideoRedundancy) {
.subscribe(
() => {
this.notifier.success($localize`Video redundancies removed!`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
}
- protected loadData () {
+ protected reloadData () {
const options = {
pagination: this.pagination,
sort: this.sort,
<p-table
- [value]="blockedAccounts" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" (onPage)="onPage($event)"
+ [value]="blockedAccounts" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
+ [sortField]="sort.field" [sortOrder]="sort.order" (onPage)="onPage($event)"
+ [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted accounts"
>
<ng-template pTemplate="caption">
<div class="caption">
- <div class="ml-auto has-feedback has-clear">
- <input
- type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
- (keyup)="onSearch($event)"
- >
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
+ <div class="ml-auto">
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
</ng-template>
</h1>
<p-table
- [value]="blocklist" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
+ [value]="blocklist" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
+ [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id"
+ [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blocked videos"
(onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
<ng-template pTemplate="caption">
<div class="caption">
<div class="ml-auto">
- <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)" (resetTableFilter)="resetTableFilter()"></my-advanced-input-filter>
+ <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
</ng-template>
height: 24px;
}
-.input-group {
- @include peertube-input-group(300px);
-
- .dropdown-toggle::after {
- margin-left: 0;
- }
-}
-
-.caption {
- justify-content: flex-end;
-
- input {
- @include peertube-input-text(250px);
- flex-grow: 1;
- }
-}
-
.badge {
@include table-badge;
}
import { switchMap } from 'rxjs/operators'
import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils'
import { environment } from 'src/environments/environment'
-import { AfterViewInit, Component, OnInit } from '@angular/core'
+import { Component, OnInit } from '@angular/core'
import { DomSanitizer } from '@angular/platform-browser'
-import { ActivatedRoute, Params, Router } from '@angular/router'
+import { ActivatedRoute, Router } from '@angular/router'
import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
import { AdvancedInputFilter } from '@app/shared/shared-forms'
import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
templateUrl: './video-block-list.component.html',
styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-block-list.component.scss' ]
})
-export class VideoBlockListComponent extends RestTable implements OnInit, AfterViewInit {
+export class VideoBlockListComponent extends RestTable implements OnInit {
blocklist: (VideoBlacklist & { reasonHtml?: string, embedHtml?: string })[] = []
totalRecords = 0
sort: SortMeta = { field: 'createdAt', order: -1 }
).subscribe(
() => {
this.notifier.success($localize`Video ${videoBlock.video.name} switched to manual block.`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
})
this.initialize()
- this.listenToSearchChange()
- }
-
- ngAfterViewInit () {
- if (this.search) this.setTableFilter(this.search, false)
}
getIdentifier () {
this.videoBlocklistService.unblockVideo(entry.video.id).subscribe(
() => {
this.notifier.success($localize`Video ${entry.video.name} unblocked.`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
)
}
- protected loadData () {
+ protected reloadData () {
this.videoBlocklistService.listBlocks({
pagination: this.pagination,
sort: this.sort,
<em i18n>This view also shows comments from muted accounts.</em>
<p-table
- [value]="comments" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
+ [value]="comments" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
+ [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id"
+ [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} comments"
(onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
</div>
<div class="ml-auto">
- <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)" (resetTableFilter)="resetTableFilter()"></my-advanced-input-filter>
+ <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
</ng-template>
height: 24px;
}
-.input-group {
- @include peertube-input-group(300px);
-
- .dropdown-toggle::after {
- margin-left: 0;
- }
-}
-
-.caption {
- justify-content: flex-end;
-
- input {
- @include peertube-input-text(250px);
- flex-grow: 1;
- }
-}
-
.video {
display: flex;
flex-direction: column;
templateUrl: './video-comment-list.component.html',
styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ]
})
-export class VideoCommentListComponent extends RestTable implements OnInit, AfterViewInit {
- baseRoute = '/admin/moderation/video-comments/list'
-
+export class VideoCommentListComponent extends RestTable implements OnInit {
comments: VideoCommentAdmin[]
totalRecords = 0
sort: SortMeta = { field: 'createdAt', order: -1 }
ngOnInit () {
this.initialize()
- this.listenToSearchChange()
this.bulkCommentActions = [
{
]
}
- ngAfterViewInit () {
- if (this.search) this.setTableFilter(this.search, false)
- }
-
getIdentifier () {
return 'VideoCommentListComponent'
}
return this.selectedComments.length !== 0
}
- protected loadData () {
+ protected reloadData () {
this.videoCommentService.getAdminVideoComments({
pagination: this.pagination,
sort: this.sort,
this.videoCommentService.deleteVideoComments(commentArgs).subscribe(
() => {
this.notifier.success($localize`${commentArgs.length} comments deleted.`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message),
private deleteComment (comment: VideoCommentAdmin) {
this.videoCommentService.deleteVideoComment(comment.video.id, comment.id)
.subscribe(
- () => this.loadData(),
+ () => this.reloadData(),
err => this.notifier.error(err.message)
)
onJobStateOrTypeChanged () {
this.pagination.start = 0
- this.loadData()
+ this.reloadData()
this.saveJobStateAndType()
}
this.jobs = []
this.totalRecords = 0
- this.loadData()
+ this.reloadData()
}
- protected loadData () {
+ protected reloadData () {
let jobState = this.jobState as JobState
if (this.jobState === 'all') jobState = null
<p-table
- [value]="users" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" [resizableColumns]="true"
- [(selection)]="selectedUsers"
+ [value]="users" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
+ [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true" [(selection)]="selectedUsers"
+ [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users"
(onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
</div>
<div class="ml-auto">
- <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)" (resetTableFilter)="resetTableFilter()"></my-advanced-input-filter>
+ <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
import { SortMeta } from 'primeng/api'
-import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'
+import { Component, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService, UserService } from '@app/core'
import { AdvancedInputFilter } from '@app/shared/shared-forms'
templateUrl: './user-list.component.html',
styleUrls: [ './user-list.component.scss' ]
})
-export class UserListComponent extends RestTable implements OnInit, AfterViewInit {
+export class UserListComponent extends RestTable implements OnInit {
@ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent
users: User[] = []
.subscribe(config => this.serverConfig = config)
this.initialize()
- this.listenToSearchChange()
this.bulkUserActions = [
[
this.columns.push({ id: 'lastLoginDate', label: 'Last login' })
}
- ngAfterViewInit () {
- if (this.search) this.setTableFilter(this.search, false)
- }
-
getIdentifier () {
return 'UserListComponent'
}
}
onUserChanged () {
- this.loadData()
+ this.reloadData()
}
async unbanUsers (users: User[]) {
.subscribe(
() => {
this.notifier.success($localize`${users.length} users unbanned.`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
this.userService.removeUser(users).subscribe(
() => {
this.notifier.success($localize`${users.length} users deleted.`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
this.userService.updateUsers(users, { emailVerified: true }).subscribe(
() => {
this.notifier.success($localize`${users.length} users email set as verified.`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
return this.selectedUsers.length !== 0
}
- protected loadData () {
+ protected reloadData () {
this.selectedUsers = []
this.userService.getUsers({
</h1>
<div class="video-channels-header d-flex justify-content-between">
- <div class="has-feedback has-clear">
- <input type="text" placeholder="Search your channels" i18n-placeholder [(ngModel)]="channelsSearch"
- (ngModelChange)="onChannelsSearchChanged()" />
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
- </div>
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
<a class="create-button" routerLink="create">
<my-global-icon iconName="add" aria-hidden="true"></my-global-icon>
import { ChartData } from 'chart.js'
import { max, maxBy, min, minBy } from 'lodash-es'
-import { Subject } from 'rxjs'
-import { debounceTime, mergeMap } from 'rxjs/operators'
-import { Component, OnInit } from '@angular/core'
-import { AuthService, ConfirmService, Notifier, ScreenService, User } from '@app/core'
+import { mergeMap } from 'rxjs/operators'
+import { Component } from '@angular/core'
+import { AuthService, ConfirmService, Notifier, ScreenService } from '@app/core'
import { VideoChannel, VideoChannelService } from '@app/shared/shared-main'
@Component({
templateUrl: './my-video-channels.component.html',
styleUrls: [ './my-video-channels.component.scss' ]
})
-export class MyVideoChannelsComponent implements OnInit {
+export class MyVideoChannelsComponent {
totalItems: number
videoChannels: VideoChannel[] = []
+
videoChannelsChartData: ChartData[]
videoChannelsMinimumDailyViews = 0
videoChannelsMaximumDailyViews: number
- channelsSearch: string
- channelsSearchChanged = new Subject<string>()
-
chartOptions: any
- private user: User
+ search: string
constructor (
private authService: AuthService,
private confirmService: ConfirmService,
private videoChannelService: VideoChannelService,
private screenService: ScreenService
- ) {}
-
- ngOnInit () {
- this.user = this.authService.getUser()
-
- this.loadVideoChannels()
-
- this.channelsSearchChanged
- .pipe(debounceTime(500))
- .subscribe(() => {
- this.loadVideoChannels()
- })
- }
+ ) {}
get isInSmallView () {
return this.screenService.isInSmallView()
}
- resetSearch () {
- this.channelsSearch = ''
- this.onChannelsSearchChanged()
- }
-
- onChannelsSearchChanged () {
- this.channelsSearchChanged.next()
+ onSearch (search: string) {
+ this.search = search
+ this.loadVideoChannels()
}
async deleteVideoChannel (videoChannel: VideoChannel) {
private loadVideoChannels () {
this.authService.userInformationLoaded
- .pipe(mergeMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account, null, true, this.channelsSearch)))
- .subscribe(res => {
+ .pipe(mergeMap(() => {
+ const user = this.authService.getUser()
+
+ return this.videoChannelService.listAccountVideoChannels(user.account, null, true, this.search)
+ })).subscribe(res => {
this.videoChannels = res.data
this.totalItems = res.total
<div class="top-buttons">
<div class="search-wrapper">
- <div class="input-group has-feedback has-clear">
- <input
- type="text" name="history-search" id="history-search" i18n-placeholder placeholder="Search your history"
- (keyup)="onSearch($event)"
- >
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
- </div>
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
</div>
<div class="history-switch">
</button>
</div>
-
-<div class="no-history" i18n *ngIf="hasDoneFirstQuery && videos.length === 0">You don't have any video in your watch history yet.</div>
-
-<div myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onDataSubject.asObservable()" class="videos">
- <div class="video" *ngFor="let video of videos">
- <my-video-miniature
- [video]="video" [displayAsRow]="true"
- (videoRemoved)="removeVideoFromArray(video)" (videoBlocked)="removeVideoFromArray(video)"
- ></my-video-miniature>
- </div>
-</div>
+<my-videos-selection
+ [pagination]="pagination"
+ [(videosModel)]="videos"
+ [miniatureDisplayOptions]="miniatureDisplayOptions"
+ [titlePage]="titlePage"
+ [getVideosObservableFunction]="getVideosObservableFunction"
+ [user]="user"
+ [loadOnInit]="false"
+ i18n-noResultMessage noResultMessage="You don't have any video in your watch history yet."
+ [enableSelection]="false"
+ #videosSelection
+></my-videos-selection>
-import { Component, ComponentFactoryResolver, OnDestroy, OnInit } from '@angular/core'
+import { Subject } from 'rxjs'
+import { tap } from 'rxjs/operators'
+import { Component, ComponentFactoryResolver, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import {
AuthService,
ComponentPagination,
ConfirmService,
+ DisableForReuseHook,
LocalStorageService,
Notifier,
ScreenService,
ServerService,
+ User,
UserService
} from '@app/core'
import { immutableAssign } from '@app/helpers'
-import { UserHistoryService } from '@app/shared/shared-main'
-import { AbstractVideoList } from '@app/shared/shared-video-miniature'
-import { Subject } from 'rxjs'
-import { debounceTime, tap, distinctUntilChanged } from 'rxjs/operators'
+import { UserHistoryService, Video } from '@app/shared/shared-main'
+import { MiniatureDisplayOptions, VideosSelectionComponent } from '@app/shared/shared-video-miniature'
@Component({
templateUrl: './my-history.component.html',
styleUrls: [ './my-history.component.scss' ]
})
-export class MyHistoryComponent extends AbstractVideoList implements OnInit, OnDestroy {
+export class MyHistoryComponent implements OnInit, DisableForReuseHook {
+ @ViewChild('videosSelection', { static: true }) videosSelection: VideosSelectionComponent
+
titlePage: string
pagination: ComponentPagination = {
currentPage: 1,
itemsPerPage: 5,
totalItems: null
}
+
videosHistoryEnabled: boolean
- search: string
- protected searchStream: Subject<string>
+ miniatureDisplayOptions: MiniatureDisplayOptions = {
+ date: true,
+ views: true,
+ by: true,
+ privacyLabel: false,
+ privacyText: true,
+ state: true,
+ blacklistInfo: true
+ }
+
+ getVideosObservableFunction = this.getVideosObservable.bind(this)
+
+ user: User
+
+ videos: Video[] = []
+ search: string
constructor (
protected router: Router,
private userHistoryService: UserHistoryService,
protected cfr: ComponentFactoryResolver
) {
- super()
-
this.titlePage = $localize`My watch history`
}
ngOnInit () {
- super.ngOnInit()
+ this.user = this.authService.getUser()
this.authService.userInformationLoaded
- .subscribe(() => {
- this.videosHistoryEnabled = this.authService.getUser().videosHistoryEnabled
- })
-
- this.searchStream = new Subject()
+ .subscribe(() => this.videosHistoryEnabled = this.user.videosHistoryEnabled)
+ }
- this.searchStream
- .pipe(
- debounceTime(400),
- distinctUntilChanged()
- )
- .subscribe(search => {
- this.search = search
- this.reloadVideos()
- })
+ disableForReuse () {
+ this.videosSelection.disableForReuse()
}
- onSearch (event: Event) {
- const target = event.target as HTMLInputElement
- this.searchStream.next(target.value)
+ enabledForReuse () {
+ this.videosSelection.enabledForReuse()
}
- resetSearch () {
- const searchInput = document.getElementById('history-search') as HTMLInputElement
- searchInput.value = ''
- this.searchStream.next('')
+ reloadData () {
+ this.videosSelection.reloadVideos()
}
- ngOnDestroy () {
- super.ngOnDestroy()
+ onSearch (search: string) {
+ this.search = search
+ this.reloadData()
}
getVideosObservable (page: number) {
() => {
this.notifier.success($localize`Videos history deleted`)
- this.reloadVideos()
+ this.reloadData()
},
err => this.notifier.error(err.message)
}
accepted () {
- this.loadData()
+ this.reloadData()
}
refuse (videoChangeOwnership: VideoChangeOwnership) {
this.videoOwnershipService.refuseOwnership(videoChangeOwnership.id)
.subscribe(
- () => this.loadData(),
+ () => this.reloadData(),
err => this.notifier.error(err.message)
)
}
- protected loadData () {
+ protected reloadData () {
return this.videoOwnershipService.getOwnershipChanges(this.pagination, this.sort)
.subscribe(
resultList => {
</h1>
<div class="video-subscriptions-header">
- <div class="has-feedback has-clear">
- <input type="text" placeholder="Search your subscriptions" i18n-placeholder [(ngModel)]="subscriptionsSearch"
- (ngModelChange)="onSubscriptionsSearchChanged()" />
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
- </div>
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
</div>
<div class="no-results" i18n *ngIf="pagination.totalItems === 0">You don't have any subscription yet.</div>
.video-subscriptions-header {
margin-bottom: 30px;
+ display: flex;
}
@media screen and (max-width: $small-view) {
import { Subject } from 'rxjs'
-import { debounceTime } from 'rxjs/operators'
-import { Component, OnInit } from '@angular/core'
+import { Component } from '@angular/core'
import { ComponentPagination, Notifier } from '@app/core'
import { VideoChannel } from '@app/shared/shared-main'
import { UserSubscriptionService } from '@app/shared/shared-user-subscription'
templateUrl: './my-subscriptions.component.html',
styleUrls: [ './my-subscriptions.component.scss' ]
})
-export class MySubscriptionsComponent implements OnInit {
+export class MySubscriptionsComponent {
videoChannels: VideoChannel[] = []
pagination: ComponentPagination = {
onDataSubject = new Subject<any[]>()
- subscriptionsSearch: string
- subscriptionsSearchChanged = new Subject<string>()
+ search: string
constructor (
private userSubscriptionService: UserSubscriptionService,
private notifier: Notifier
) {}
- ngOnInit () {
- this.loadSubscriptions()
-
- this.subscriptionsSearchChanged
- .pipe(debounceTime(500))
- .subscribe(() => {
- this.pagination.currentPage = 1
- this.loadSubscriptions(false)
- })
- }
-
- resetSearch () {
- this.subscriptionsSearch = ''
- this.onSubscriptionsSearchChanged()
- }
-
- onSubscriptionsSearchChanged () {
- this.subscriptionsSearchChanged.next()
- }
-
onNearOfBottom () {
// Last page
if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return
this.loadSubscriptions()
}
+ onSearch (search: string) {
+ this.search = search
+ this.loadSubscriptions(false)
+ }
+
private loadSubscriptions (more = true) {
- this.userSubscriptionService.listSubscriptions({ pagination: this.pagination, search: this.subscriptionsSearch })
+ this.userSubscriptionService.listSubscriptions({ pagination: this.pagination, search: this.search })
.subscribe(
res => {
this.videoChannels = more
return '/videos/update/' + video.uuid
}
- protected loadData () {
+ protected reloadData () {
this.videoImportService.getMyVideoImports(this.pagination, this.sort)
.subscribe(
resultList => {
</h1>
<div class="video-playlists-header d-flex justify-content-between">
- <div class="has-feedback has-clear">
- <input type="text" placeholder="Search your playlists" i18n-placeholder [(ngModel)]="videoPlaylistsSearch"
- (ngModelChange)="onVideoPlaylistSearchChanged()" />
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
- </div>
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
<a class="create-button" routerLink="create">
<my-global-icon iconName="add" aria-hidden="true"></my-global-icon>
import { Subject } from 'rxjs'
-import { debounceTime, mergeMap } from 'rxjs/operators'
-import { Component, OnInit } from '@angular/core'
-import { AuthService, ComponentPagination, ConfirmService, Notifier, User } from '@app/core'
+import { mergeMap } from 'rxjs/operators'
+import { Component } from '@angular/core'
+import { AuthService, ComponentPagination, ConfirmService, Notifier } from '@app/core'
import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist'
import { VideoPlaylistType } from '@shared/models'
templateUrl: './my-video-playlists.component.html',
styleUrls: [ './my-video-playlists.component.scss' ]
})
-export class MyVideoPlaylistsComponent implements OnInit {
- videoPlaylistsSearch: string
+export class MyVideoPlaylistsComponent {
videoPlaylists: VideoPlaylist[] = []
- videoPlaylistSearchChanged = new Subject<string>()
pagination: ComponentPagination = {
currentPage: 1,
onDataSubject = new Subject<any[]>()
- private user: User
+ search: string
constructor (
private authService: AuthService,
private notifier: Notifier,
private confirmService: ConfirmService,
private videoPlaylistService: VideoPlaylistService
- ) {}
-
- ngOnInit () {
- this.user = this.authService.getUser()
-
- this.loadVideoPlaylists()
-
- this.videoPlaylistSearchChanged
- .pipe(
- debounceTime(500))
- .subscribe(() => {
- this.loadVideoPlaylists(true)
- })
- }
+ ) {}
async deleteVideoPlaylist (videoPlaylist: VideoPlaylist) {
const res = await this.confirmService.confirm(
this.loadVideoPlaylists()
}
- resetSearch () {
- this.videoPlaylistsSearch = ''
- this.onVideoPlaylistSearchChanged()
- }
-
- onVideoPlaylistSearchChanged () {
- this.videoPlaylistSearchChanged.next()
+ onSearch (search: string) {
+ this.search = search
+ this.loadVideoPlaylists(true)
}
private loadVideoPlaylists (reset = false) {
this.authService.userInformationLoaded
.pipe(mergeMap(() => {
- return this.videoPlaylistService.listAccountPlaylists(this.user.account, this.pagination, '-updatedAt', this.videoPlaylistsSearch)
- }))
- .subscribe(res => {
+ const user = this.authService.getUser()
+
+ return this.videoPlaylistService.listAccountPlaylists(user.account, this.pagination, '-updatedAt', this.search)
+ })).subscribe(res => {
if (reset) this.videoPlaylists = []
+
this.videoPlaylists = this.videoPlaylists.concat(res.data)
this.pagination.totalItems = res.total
</h1>
<div class="videos-header d-flex justify-content-between">
- <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)" (resetTableFilter)="resetTableFilter()"></my-advanced-input-filter>
+ <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter>
<div class="peertube-select-container peertube-select-button">
<select [(ngModel)]="sort" (ngModelChange)="onChangeSortColumn()" class="form-control">
[titlePage]="titlePage"
[getVideosObservableFunction]="getVideosObservableFunction"
[user]="user"
+ [loadOnInit]="false"
#videosSelection
>
<ng-template ptTemplate="globalButtons">
</ng-template>
</my-videos-selection>
-
<my-video-change-ownership #videoChangeOwnershipModal></my-video-change-ownership>
<my-live-stream-information #liveStreamInformationModal></my-live-stream-information>
import { concat, Observable } from 'rxjs'
import { tap, toArray } from 'rxjs/operators'
-import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'
+import { Component, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
-import { AuthService, ComponentPagination, ConfirmService, Notifier, RouteFilter, ScreenService, ServerService, User } from '@app/core'
+import { AuthService, ComponentPagination, ConfirmService, Notifier, ScreenService, ServerService, User } from '@app/core'
import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
import { immutableAssign } from '@app/helpers'
import { AdvancedInputFilter } from '@app/shared/shared-forms'
templateUrl: './my-videos.component.html',
styleUrls: [ './my-videos.component.scss' ]
})
-export class MyVideosComponent extends RouteFilter implements OnInit, AfterViewInit, DisableForReuseHook {
+export class MyVideosComponent implements OnInit, DisableForReuseHook {
@ViewChild('videosSelection', { static: true }) videosSelection: VideosSelectionComponent
@ViewChild('videoChangeOwnershipModal', { static: true }) videoChangeOwnershipModal: VideoChangeOwnershipComponent
@ViewChild('liveStreamInformationModal', { static: true }) liveStreamInformationModal: LiveStreamInformationComponent
videos: Video[] = []
getVideosObservableFunction = this.getVideosObservable.bind(this)
+
sort: VideoSortField = '-publishedAt'
user: User
}
]
+ private search: string
+
constructor (
protected router: Router,
protected serverService: ServerService,
private confirmService: ConfirmService,
private videoService: VideoService
) {
- super()
-
this.titlePage = $localize`My videos`
}
this.buildActions()
this.user = this.authService.getUser()
-
- this.initSearch()
- this.listenToSearchChange()
}
- ngAfterViewInit () {
- if (this.search) this.setTableFilter(this.search, false)
+ onSearch (search: string) {
+ this.search = search
+ this.reloadData()
}
- loadData () {
+ reloadData () {
this.videosSelection.reloadVideos()
}
import * as debug from 'debug'
import { LazyLoadEvent, SortMeta } from 'primeng/api'
-import { Subject } from 'rxjs'
import { ActivatedRoute, Router } from '@angular/router'
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
-import { RouteFilter } from '../routing'
import { RestPagination } from './rest-pagination'
const logger = debug('peertube:tables:RestTable')
-export abstract class RestTable extends RouteFilter {
+export abstract class RestTable {
abstract totalRecords: number
abstract sort: SortMeta
abstract pagination: RestPagination
- search: string
rowsPerPageOptions = [ 10, 20, 50, 100 ]
rowsPerPage = this.rowsPerPageOptions[0]
expandedRows = {}
- protected searchStream: Subject<string>
+ search: string
protected route: ActivatedRoute
protected router: Router
initialize () {
this.loadSort()
- this.initSearch()
}
loadSort () {
count: this.rowsPerPage
}
- this.loadData()
+ this.reloadData()
this.saveSort()
}
count: this.rowsPerPage
}
- this.loadData()
+ this.reloadData()
}
this.expandedRows = {}
}
- protected abstract loadData (): void
+ onSearch (search: string) {
+ this.search = search
+ this.reloadData()
+ }
+
+ protected abstract reloadData (): void
private getSortLocalStorageKey () {
return 'rest-table-sort-' + this.getIdentifier()
export * from './menu-guard.service'
export * from './preload-selected-modules-list'
export * from './redirect.service'
-export * from './route-filter'
export * from './server-config-resolver.service'
export * from './unlogged-guard.service'
export * from './user-right-guard.service'
+++ /dev/null
-import * as debug from 'debug'
-import { Subject } from 'rxjs'
-import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
-import { ActivatedRoute, Params, Router } from '@angular/router'
-
-const logger = debug('peertube:tables:RouteFilter')
-
-export abstract class RouteFilter {
- search: string
-
- protected searchStream: Subject<string>
-
- protected route: ActivatedRoute
- protected router: Router
-
- initSearch () {
- this.searchStream = new Subject()
-
- this.searchStream
- .pipe(
- debounceTime(200),
- distinctUntilChanged()
- )
- .subscribe(search => {
- this.search = search
-
- logger('On search %s.', this.search)
-
- this.loadData()
- })
- }
-
- onSearch (event: Event) {
- const target = event.target as HTMLInputElement
- this.searchStream.next(target.value)
-
- this.setQueryParams(target.value)
- }
-
- resetTableFilter () {
- this.setTableFilter('')
- this.setQueryParams('')
- this.resetSearch()
- }
-
- resetSearch () {
- this.searchStream.next('')
- this.setTableFilter('')
- }
-
- listenToSearchChange () {
- this.route.queryParams
- .subscribe(params => {
- this.search = params.search || ''
-
- // Primeng table will run an event to load data
- this.setTableFilter(this.search)
- })
- }
-
- setTableFilter (filter: string, triggerEvent = true) {
- // FIXME: cannot use ViewChild, so create a component for the filter input
- const filterInput = document.getElementById('table-filter') as HTMLInputElement
- if (!filterInput) return
-
- filterInput.value = filter
-
- if (triggerEvent) filterInput.dispatchEvent(new Event('keyup'))
- }
-
- protected abstract loadData (): void
-
- private setQueryParams (search: string) {
- const queryParams: Params = {}
-
- if (search) Object.assign(queryParams, { search })
- this.router.navigate([ ], { queryParams })
- }
-}
<p-table
- [value]="abuses" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" [resizableColumns]="true"
+ [value]="abuses" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
+ [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true"
+ [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} reports"
(onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
<ng-template pTemplate="caption">
<div class="caption">
<div class="ml-auto">
- <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)" (resetTableFilter)="resetTableFilter()"></my-advanced-input-filter>
+ <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
</ng-template>
import { SortMeta } from 'primeng/api'
import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils'
import { environment } from 'src/environments/environment'
-import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core'
+import { Component, Input, OnInit, ViewChild } from '@angular/core'
import { DomSanitizer } from '@angular/platform-browser'
import { ActivatedRoute, Router } from '@angular/router'
import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core'
import { AbuseService, BlocklistService, VideoBlockService } from '@app/shared/shared-moderation'
import { VideoCommentService } from '@app/shared/shared-video-comment'
import { AbuseState, AdminAbuse } from '@shared/models'
+import { AdvancedInputFilter } from '../shared-forms'
import { AbuseMessageModalComponent } from './abuse-message-modal.component'
import { ModerationCommentModalComponent } from './moderation-comment-modal.component'
import { ProcessedAbuse } from './processed-abuse.model'
-import { AdvancedInputFilter } from '../shared-forms'
const logger = debug('peertube:moderation:AbuseListTableComponent')
templateUrl: './abuse-list-table.component.html',
styleUrls: [ '../shared-moderation/moderation.scss', './abuse-list-table.component.scss' ]
})
-export class AbuseListTableComponent extends RestTable implements OnInit, AfterViewInit {
+export class AbuseListTableComponent extends RestTable implements OnInit {
@Input() viewType: 'admin' | 'user'
@ViewChild('abuseMessagesModal', { static: true }) abuseMessagesModal: AbuseMessageModalComponent
]
this.initialize()
- this.listenToSearchChange()
- }
-
- ngAfterViewInit () {
- if (this.search) this.setTableFilter(this.search, false)
}
isAdminView () {
}
onModerationCommentUpdated () {
- this.loadData()
+ this.reloadData()
}
isAbuseAccepted (abuse: AdminAbuse) {
this.abuseService.removeAbuse(abuse).subscribe(
() => {
this.notifier.success($localize`Abuse deleted.`)
- this.loadData()
+ this.reloadData()
},
err => this.notifier.error(err.message)
updateAbuseState (abuse: AdminAbuse, state: AbuseState) {
this.abuseService.updateAbuse(abuse, { state })
.subscribe(
- () => this.loadData(),
+ () => this.reloadData(),
err => this.notifier.error(err.message)
)
return Actor.IS_LOCAL(abuse.reporterAccount.host)
}
- protected loadData () {
+ protected reloadData () {
logger('Loading data.')
const options = {
<div class="input-group has-feedback has-clear">
- <div class="input-group-prepend c-hand" ngbDropdown placement="bottom-left auto" container="body">
+ <div *ngIf="hasFilters()" class="input-group-prepend c-hand" ngbDropdown placement="bottom-left auto" container="body">
<div class="input-group-text" ngbDropdownToggle>
<span class="caret" aria-haspopup="menu" role="button"></span>
</div>
<a *ngFor="let filter of filters" [routerLink]="[ '.' ]" [queryParams]="filter.queryParams" class="dropdown-item">
{{ filter.label }}
</a>
-
</div>
</div>
+
<input
type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
- (keyup)="onSearch($event)"
+ [(ngModel)]="searchValue"
+ (keyup)="onInputSearch($event)"
>
+
<a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="onResetTableFilter()"></a>
<span class="sr-only" i18n>Clear filters</span>
</div>
-import { Component, EventEmitter, Input, Output } from '@angular/core'
-import { Params } from '@angular/router'
+import * as debug from 'debug'
+import { Subject } from 'rxjs'
+import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
+import { ActivatedRoute, Params, Router } from '@angular/router'
export type AdvancedInputFilter = {
label: string
queryParams: Params
}
+const logger = debug('peertube:AdvancedInputFilterComponent')
+
@Component({
selector: 'my-advanced-input-filter',
templateUrl: './advanced-input-filter.component.html',
styleUrls: [ './advanced-input-filter.component.scss' ]
})
-export class AdvancedInputFilterComponent {
+export class AdvancedInputFilterComponent implements OnInit {
@Input() filters: AdvancedInputFilter[] = []
- @Output() resetTableFilter = new EventEmitter<void>()
- @Output() search = new EventEmitter<Event>()
+ @Output() search = new EventEmitter<string>()
+
+ searchValue: string
+
+ private searchStream: Subject<string>
+
+ constructor (
+ private route: ActivatedRoute,
+ private router: Router
+ ) { }
+
+ ngOnInit () {
+ this.initSearchStream()
+ this.listenToRouteSearchChange()
+ }
- onSearch (event: Event) {
- this.search.emit(event)
+ onInputSearch (event: Event) {
+ this.updateSearch((event.target as HTMLInputElement).value)
}
onResetTableFilter () {
- this.resetTableFilter.emit()
+ this.updateSearch('')
+ }
+
+ hasFilters () {
+ return this.filters.length !== 0
+ }
+
+ private updateSearch (value: string) {
+ this.searchValue = value
+ this.searchStream.next(this.searchValue)
+ }
+
+ private listenToRouteSearchChange () {
+ this.route.queryParams
+ .subscribe(params => {
+ const search = params.search || ''
+
+ logger('On route search change "%s".', search)
+
+ this.updateSearch(search)
+ })
+ }
+
+ private initSearchStream () {
+ this.searchStream = new Subject()
+
+ this.searchStream
+ .pipe(
+ debounceTime(200),
+ distinctUntilChanged()
+ )
+ .subscribe(() => {
+ logger('On search "%s".', this.searchValue)
+
+ this.setQueryParams(this.searchValue)
+ this.search.emit(this.searchValue)
+ })
+ }
+
+ private setQueryParams (search: string) {
+ const queryParams: Params = {}
+
+ if (search) Object.assign(queryParams, { search })
+ this.router.navigate([ ], { queryParams })
}
}
}
}
-::ng-deep .dropdown-toggle::after {
+.sub-menu ::ng-deep .dropdown-toggle::after {
position: relative;
top: 2px;
}
-::ng-deep .dropdown-menu {
+.sub-menu ::ng-deep .dropdown-menu {
margin-top: 0 !important;
}
>
<ng-template pTemplate="caption">
<div class="caption">
- <div class="ml-auto has-feedback has-clear">
- <input
- type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
- (keyup)="onSearch($event)"
- >
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
+ <div class="ml-auto">
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
</ng-template>
@import '_variables';
@import '_mixins';
-.caption {
- justify-content: flex-end;
-
- input {
- @include peertube-input-text(250px);
-
- flex-grow: 1;
- }
-}
-
.chip {
@include chip;
}
: $localize`Account ${blockedAccount.nameWithHost} unmuted by your instance.`
)
- this.loadData()
+ this.reloadData()
}
)
}
- protected loadData () {
+ protected reloadData () {
const operation = this.mode === BlocklistComponentType.Account
? this.blocklistService.getUserAccountBlocklist({
pagination: this.pagination,
}
}
-.input-group {
- @include peertube-input-group(300px);
-
- .dropdown-toggle::after {
- margin-left: 0;
- }
-}
-
.chip {
@include chip;
}
-.caption {
- justify-content: flex-end;
-
- input {
- @include peertube-input-text(250px);
- flex-grow: 1;
- }
-}
-
my-action-dropdown.show {
::ng-deep .dropdown-root {
display: block !important;
</h1>
<p-table
- [value]="blockedServers" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" (onPage)="onPage($event)"
+ [value]="blockedServers" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
+ [sortField]="sort.field" [sortOrder]="sort.order" (onPage)="onPage($event)"
+ [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted instances"
>
</a>
</div>
- <div class="ml-auto has-feedback has-clear">
- <input
- type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
- (keyup)="onSearch($event)"
- >
- <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
- <span class="sr-only" i18n>Clear filters</span>
+ <div class="ml-auto">
+ <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
</div>
</div>
</ng-template>
}
}
-.caption {
- justify-content: flex-end;
-
- input {
- @include peertube-input-text(250px);
- flex-grow: 1;
- }
-}
-
.unblock-button {
@include peertube-button;
@include grey-button;
@include create-button;
}
-.caption {
- justify-content: flex-end;
-
- input {
- @include peertube-input-text(250px);
- flex-grow: 1;
- }
-}
-
.chip {
@include chip;
}
: $localize`Instance ${host} unmuted by your instance.`
)
- this.loadData()
+ this.reloadData()
}
)
}
: $localize`Instance ${domain} muted by your instance.`
)
- this.loadData()
+ this.reloadData()
}
)
})
}
- protected loadData () {
+ protected reloadData () {
const operation = this.mode === BlocklistComponentType.Account
? this.blocklistService.getUserServerBlocklist({
pagination: this.pagination,
-<div class="no-results" i18n *ngIf="hasDoneFirstQuery && videos.length === 0">No results.</div>
+<div class="no-results" i18n *ngIf="hasDoneFirstQuery && videos.length === 0">{{ noResultMessage }}</div>
<div myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()" class="videos">
<div class="video" *ngFor="let video of videos; let i = index; trackBy: videoById">
- <div class="checkbox-container">
+ <div class="checkbox-container" *ngIf="enableSelection">
<my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="_selection[video.id]"></my-peertube-checkbox>
</div>
@Input() pagination: ComponentPagination
@Input() titlePage: string
@Input() miniatureDisplayOptions: MiniatureDisplayOptions
+ @Input() noResultMessage = $localize`No results.`
+ @Input() enableSelection = true
+ @Input() loadOnInit = true
@Input() getVideosObservableFunction: (page: number, sort?: VideoSortField) => Observable<ResultList<Video>>