Fix broken infinite scroll when deleting items

Signed-off-by: Chocobozzz <me@florianbigard.com>
This commit is contained in:
Chocobozzz 2024-12-23 10:45:10 +01:00
parent 93b353adde
commit a977115fae
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
19 changed files with 156 additions and 101 deletions

View File

@ -2,7 +2,7 @@ import { NgFor, NgIf } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service'
import { ComponentPagination, ConfirmService, hasMoreItems, Notifier } from '@app/core'
import { ComponentPagination, ConfirmService, hasMoreItems, Notifier, resetCurrentPage, updatePaginationOnDelete } from '@app/core'
import { PluginService } from '@app/core/plugins/plugin.service'
import { compareSemVer } from '@peertube/peertube-core-utils'
import { PeerTubePlugin, PluginType, PluginType_Type } from '@peertube/peertube-models'
@ -69,8 +69,8 @@ export class PluginListInstalledComponent implements OnInit {
}
reloadPlugins () {
this.pagination.currentPage = 1
this.plugins = []
resetCurrentPage(this.pagination)
this.loadMorePlugins()
}
@ -143,7 +143,7 @@ export class PluginListInstalledComponent implements OnInit {
this.notifier.success($localize`${plugin.name} uninstalled.`)
this.plugins = this.plugins.filter(p => p.name !== plugin.name)
this.pagination.totalItems--
updatePaginationOnDelete(this.pagination)
this.uninstalling[pluginKey] = false
},

View File

@ -2,7 +2,7 @@ import { NgFor, NgIf } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service'
import { ComponentPagination, ConfirmService, hasMoreItems, Notifier, PluginService } from '@app/core'
import { ComponentPagination, ConfirmService, hasMoreItems, Notifier, PluginService, resetCurrentPage } from '@app/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { PeerTubePluginIndex, PluginType, PluginType_Type } from '@peertube/peertube-models'
import { logger } from '@root-helpers/logger'
@ -94,7 +94,7 @@ export class PluginSearchComponent implements OnInit {
}
reloadPlugins () {
this.pagination.currentPage = 1
resetCurrentPage(this.pagination)
this.plugins = []
this.loadMorePlugins()

View File

@ -1,7 +1,16 @@
import { NgFor, NgIf } from '@angular/common'
import { Component } from '@angular/core'
import { RouterLink } from '@angular/router'
import { AuthService, ComponentPagination, ConfirmService, Notifier, ScreenService, hasMoreItems } from '@app/core'
import {
AuthService,
ComponentPagination,
ConfirmService,
Notifier,
ScreenService,
hasMoreItems,
resetCurrentPage,
updatePaginationOnDelete
} from '@app/core'
import { formatICU } from '@app/helpers'
import { VideoChannel } from '@app/shared/shared-main/channel/video-channel.model'
import { VideoChannelService } from '@app/shared/shared-main/channel/video-channel.service'
@ -12,12 +21,12 @@ import { Subject, first, map, switchMap } from 'rxjs'
import { ActorAvatarComponent } from '../../shared/shared-actor-image/actor-avatar.component'
import { AdvancedInputFilterComponent } from '../../shared/shared-forms/advanced-input-filter.component'
import { GlobalIconComponent } from '../../shared/shared-icons/global-icon.component'
import { DeferLoadingDirective } from '../../shared/shared-main/common/defer-loading.directive'
import { InfiniteScrollerDirective } from '../../shared/shared-main/common/infinite-scroller.directive'
import { NumberFormatterPipe } from '../../shared/shared-main/common/number-formatter.pipe'
import { DeleteButtonComponent } from '../../shared/shared-main/buttons/delete-button.component'
import { EditButtonComponent } from '../../shared/shared-main/buttons/edit-button.component'
import { ChannelsSetupMessageComponent } from '../../shared/shared-main/channel/channels-setup-message.component'
import { DeferLoadingDirective } from '../../shared/shared-main/common/defer-loading.directive'
import { InfiniteScrollerDirective } from '../../shared/shared-main/common/infinite-scroller.directive'
import { NumberFormatterPipe } from '../../shared/shared-main/common/number-formatter.pipe'
type CustomChartData = (ChartData & { startDate: string, total: number })
@ -75,7 +84,7 @@ export class MyVideoChannelsComponent {
onSearch (search: string) {
this.search = search
this.pagination.currentPage = 1
resetCurrentPage(this.pagination)
this.videoChannels = []
this.pagesDone.clear()
@ -105,6 +114,8 @@ export class MyVideoChannelsComponent {
next: () => {
this.videoChannels = this.videoChannels.filter(c => c.id !== videoChannel.id)
this.notifier.success($localize`Video channel ${videoChannel.displayName} deleted.`)
updatePaginationOnDelete(this.pagination)
},
error: err => this.notifier.error(err.message)

View File

@ -1,7 +1,8 @@
import { NgFor, NgIf } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { AuthService, ComponentPagination, Notifier } from '@app/core'
import { AuthService, ComponentPagination, Notifier, resetCurrentPage } from '@app/core'
import { formatICU } from '@app/helpers'
import { UserSubscriptionService } from '@app/shared/shared-user-subscription/user-subscription.service'
import { ActorFollow } from '@peertube/peertube-models'
import { Subject } from 'rxjs'
@ -9,7 +10,6 @@ import { ActorAvatarComponent } from '../../shared/shared-actor-image/actor-avat
import { AdvancedInputFilter, AdvancedInputFilterComponent } from '../../shared/shared-forms/advanced-input-filter.component'
import { GlobalIconComponent } from '../../shared/shared-icons/global-icon.component'
import { InfiniteScrollerDirective } from '../../shared/shared-main/common/infinite-scroller.directive'
import { formatICU } from '@app/helpers'
@Component({
templateUrl: './my-followers.component.html',
@ -68,7 +68,7 @@ export class MyFollowersComponent implements OnInit {
onSearch (search: string) {
this.search = search
this.pagination.currentPage = 1
resetCurrentPage(this.pagination)
this.loadFollowers(false)
}

View File

@ -1,16 +1,16 @@
import { Subject } from 'rxjs'
import { NgFor, NgIf } from '@angular/common'
import { Component } from '@angular/core'
import { ComponentPagination, Notifier } from '@app/core'
import { SubscribeButtonComponent } from '../../shared/shared-user-subscription/subscribe-button.component'
import { RouterLink } from '@angular/router'
import { ActorAvatarComponent } from '../../shared/shared-actor-image/actor-avatar.component'
import { InfiniteScrollerDirective } from '../../shared/shared-main/common/infinite-scroller.directive'
import { AdvancedInputFilterComponent } from '../../shared/shared-forms/advanced-input-filter.component'
import { NgIf, NgFor } from '@angular/common'
import { GlobalIconComponent } from '../../shared/shared-icons/global-icon.component'
import { ComponentPagination, Notifier, resetCurrentPage } from '@app/core'
import { formatICU } from '@app/helpers'
import { VideoChannel } from '@app/shared/shared-main/channel/video-channel.model'
import { UserSubscriptionService } from '@app/shared/shared-user-subscription/user-subscription.service'
import { formatICU } from '@app/helpers'
import { Subject } from 'rxjs'
import { ActorAvatarComponent } from '../../shared/shared-actor-image/actor-avatar.component'
import { AdvancedInputFilterComponent } from '../../shared/shared-forms/advanced-input-filter.component'
import { GlobalIconComponent } from '../../shared/shared-icons/global-icon.component'
import { InfiniteScrollerDirective } from '../../shared/shared-main/common/infinite-scroller.directive'
import { SubscribeButtonComponent } from '../../shared/shared-user-subscription/subscribe-button.component'
@Component({
templateUrl: './my-subscriptions.component.html',
@ -55,7 +55,7 @@ export class MySubscriptionsComponent {
onSearch (search: string) {
this.search = search
this.pagination.currentPage = 1
resetCurrentPage(this.pagination)
this.loadSubscriptions(false)
}

View File

@ -1,7 +1,15 @@
import { NgIf } from '@angular/common'
import { Component, OnInit, ViewChild } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { AuthService, ComponentPagination, ConfirmService, DisableForReuseHook, Notifier, User, UserService } from '@app/core'
import {
AuthService,
ComponentPagination,
ConfirmService,
DisableForReuseHook,
Notifier,
updatePaginationOnDelete,
User,
UserService
} from '@app/core'
import { immutableAssign } from '@app/helpers'
import { ButtonComponent } from '@app/shared/shared-main/buttons/button.component'
import { UserHistoryService } from '@app/shared/shared-main/users/user-history.service'
@ -11,7 +19,6 @@ import { VideosSelectionComponent } from '@app/shared/shared-video-miniature/vid
import { tap } from 'rxjs/operators'
import { AdvancedInputFilterComponent } from '../../shared/shared-forms/advanced-input-filter.component'
import { InputSwitchComponent } from '../../shared/shared-forms/input-switch.component'
import { GlobalIconComponent } from '../../shared/shared-icons/global-icon.component'
import { DeleteButtonComponent } from '../../shared/shared-main/buttons/delete-button.component'
import { PeerTubeTemplateDirective } from '../../shared/shared-main/common/peertube-template.directive'
@ -21,8 +28,6 @@ import { PeerTubeTemplateDirective } from '../../shared/shared-main/common/peert
standalone: true,
imports: [
ButtonComponent,
GlobalIconComponent,
NgIf,
AdvancedInputFilterComponent,
InputSwitchComponent,
FormsModule,
@ -132,6 +137,7 @@ export class MyHistoryComponent implements OnInit, DisableForReuseHook {
.subscribe({
next: () => {
this.videos = this.videos.filter(v => v.id !== video.id)
updatePaginationOnDelete(this.pagination)
},
error: err => this.notifier.error(err.message)

View File

@ -2,7 +2,7 @@ import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop'
import { NgFor, NgIf } from '@angular/common'
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { ComponentPagination, ConfirmService, HooksService, Notifier, ScreenService } from '@app/core'
import { ComponentPagination, ConfirmService, HooksService, Notifier, ScreenService, updatePaginationOnDelete } from '@app/core'
import { ButtonComponent } from '@app/shared/shared-main/buttons/button.component'
import { VideoShareComponent } from '@app/shared/shared-share-modal/video-share.component'
import { VideoPlaylistElement } from '@app/shared/shared-video-playlist/video-playlist-element.model'
@ -121,6 +121,7 @@ export class MyVideoPlaylistElementsComponent implements OnInit, OnDestroy {
const oldFirst = this.findFirst()
this.playlistElements = this.playlistElements.filter(v => v.id !== element.id)
updatePaginationOnDelete(this.pagination)
this.reorderClientPositions(oldFirst)
}
@ -184,13 +185,12 @@ export class MyVideoPlaylistElementsComponent implements OnInit, OnDestroy {
'my-library',
'filter:api.my-library.video-playlist-elements.list.params',
'filter:api.my-library.video-playlist-elements.list.result'
)
.subscribe(({ total, data }) => {
this.playlistElements = this.playlistElements.concat(data)
this.pagination.totalItems = total
).subscribe(({ total, data }) => {
this.playlistElements = this.playlistElements.concat(data)
this.pagination.totalItems = total
this.onDataSubject.next(data)
})
this.onDataSubject.next(data)
})
}
private loadPlaylistInfo () {

View File

@ -1,7 +1,7 @@
import { NgFor, NgIf } from '@angular/common'
import { Component } from '@angular/core'
import { RouterLink } from '@angular/router'
import { AuthService, ComponentPagination, ConfirmService, Notifier } from '@app/core'
import { AuthService, ComponentPagination, ConfirmService, Notifier, resetCurrentPage, updatePaginationOnDelete } from '@app/core'
import { formatICU } from '@app/helpers'
import { VideoPlaylist } from '@app/shared/shared-video-playlist/video-playlist.model'
import { VideoPlaylistService } from '@app/shared/shared-video-playlist/video-playlist.service'
@ -61,8 +61,8 @@ export class MyVideoPlaylistsComponent {
this.videoPlaylistService.removeVideoPlaylist(videoPlaylist)
.subscribe({
next: () => {
this.videoPlaylists = this.videoPlaylists
.filter(p => p.id !== videoPlaylist.id)
this.videoPlaylists = this.videoPlaylists.filter(p => p.id !== videoPlaylist.id)
updatePaginationOnDelete(this.pagination)
this.notifier.success($localize`Playlist ${videoPlaylist.displayName} deleted.`)
},
@ -85,7 +85,7 @@ export class MyVideoPlaylistsComponent {
onSearch (search: string) {
this.search = search
this.pagination.currentPage = 1
resetCurrentPage(this.pagination)
this.loadVideoPlaylists(true)
}

View File

@ -2,7 +2,16 @@ import { NgIf } from '@angular/common'
import { Component, OnInit, ViewChild } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { ActivatedRoute, Router, RouterLink } from '@angular/router'
import { AuthService, ComponentPagination, ConfirmService, Notifier, ScreenService, ServerService, User } from '@app/core'
import {
AuthService,
ComponentPagination,
ConfirmService,
Notifier,
ScreenService,
ServerService,
updatePaginationOnDelete,
User
} from '@app/core'
import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
import { formatICU, immutableAssign } from '@app/helpers'
import { DropdownAction } from '@app/shared/shared-main/buttons/action-dropdown.component'
@ -256,6 +265,8 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook {
private removeVideoFromArray (id: number) {
this.videos = this.videos.filter(v => v.id !== id)
updatePaginationOnDelete(this.pagination)
}
private buildActions () {

View File

@ -4,6 +4,7 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router'
import { AuthService, HooksService, MetaService, Notifier, ServerService, User, UserService } from '@app/core'
import { immutableAssign, SimpleMemoize } from '@app/helpers'
import { validateHost } from '@app/shared/form-validators/host-validators'
import { GlobalIconComponent } from '@app/shared/shared-icons/global-icon.component'
import { VideoChannel } from '@app/shared/shared-main/channel/video-channel.model'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { Video } from '@app/shared/shared-main/video/video.model'
@ -21,7 +22,6 @@ import { SubscribeButtonComponent } from '../shared/shared-user-subscription/sub
import { MiniatureDisplayOptions, VideoMiniatureComponent } from '../shared/shared-video-miniature/video-miniature.component'
import { VideoPlaylistMiniatureComponent } from '../shared/shared-video-playlist/video-playlist-miniature.component'
import { SearchFiltersComponent } from './search-filters.component'
import { GlobalIconComponent } from '@app/shared/shared-icons/global-icon.component'
@Component({
selector: 'my-search',
@ -54,6 +54,8 @@ export class SearchComponent implements OnInit, OnDestroy {
currentPage: 1,
totalItems: null as number
}
deletedVideos = 0
advancedSearch: AdvancedSearch = new AdvancedSearch()
isSearchFilterCollapsed = true
currentSearch: string
@ -222,7 +224,10 @@ export class SearchComponent implements OnInit, OnDestroy {
// Add VideoChannel/VideoPlaylist for typings, but the template already checks "video" argument is a video
removeVideoFromArray (video: Video | VideoChannel | VideoPlaylist) {
const previous = this.results
this.results = this.results.filter(r => !this.isVideo(r) || r.id !== video.id)
if (previous.length !== this.results.length) this.deletedVideos++
}
getLinkType (): LinkType {
@ -281,6 +286,7 @@ export class SearchComponent implements OnInit, OnDestroy {
private resetPagination () {
this.pagination.currentPage = 1
this.pagination.totalItems = null
this.deletedVideos = 0
this.results = []
}
@ -305,7 +311,7 @@ export class SearchComponent implements OnInit, OnDestroy {
private getVideosObs () {
const params = {
search: this.currentSearch,
componentPagination: immutableAssign(this.pagination, { itemsPerPage: 10 }),
componentPagination: immutableAssign(this.pagination, { itemsPerPage: 10, itemsRemoved: this.deletedVideos }),
advancedSearch: this.advancedSearch
}

View File

@ -1,13 +1,13 @@
import { Subject, Subscription } from 'rxjs'
import { NgFor, NgIf } from '@angular/common'
import { AfterViewInit, Component, OnDestroy, OnInit } from '@angular/core'
import { ComponentPagination, hasMoreItems, HooksService, ScreenService } from '@app/core'
import { VideoPlaylistMiniatureComponent } from '../../shared/shared-video-playlist/video-playlist-miniature.component'
import { InfiniteScrollerDirective } from '../../shared/shared-main/common/infinite-scroller.directive'
import { NgIf, NgFor } from '@angular/common'
import { ComponentPagination, hasMoreItems, HooksService, resetCurrentPage, ScreenService } from '@app/core'
import { VideoChannel } from '@app/shared/shared-main/channel/video-channel.model'
import { VideoChannelService } from '@app/shared/shared-main/channel/video-channel.service'
import { VideoPlaylist } from '@app/shared/shared-video-playlist/video-playlist.model'
import { VideoPlaylistService } from '@app/shared/shared-video-playlist/video-playlist.service'
import { Subject, Subscription } from 'rxjs'
import { InfiniteScrollerDirective } from '../../shared/shared-main/common/infinite-scroller.directive'
import { VideoPlaylistMiniatureComponent } from '../../shared/shared-video-playlist/video-playlist-miniature.component'
@Component({
selector: 'my-video-channel-playlists',
@ -46,7 +46,7 @@ export class VideoChannelPlaylistsComponent implements OnInit, AfterViewInit, On
this.hooks.runAction('action:video-channel-playlists.video-channel.loaded', 'video-channel', { videoChannel })
this.videoPlaylists = []
this.pagination.currentPage = 1
resetCurrentPage(this.pagination)
this.loadVideoPlaylists()
})
}

View File

@ -1,18 +1,26 @@
import { NgClass, NgFor, NgIf } from '@angular/common'
import { Component, EventEmitter, Input, Output } from '@angular/core'
import { Router } from '@angular/router'
import { AuthService, ComponentPagination, HooksService, Notifier, SessionStorageService, UserService } from '@app/core'
import {
AuthService,
ComponentPagination,
HooksService,
Notifier,
SessionStorageService,
updatePaginationOnDelete,
UserService
} from '@app/core'
import { isInViewport } from '@app/helpers'
import { VideoPlaylistElement } from '@app/shared/shared-video-playlist/video-playlist-element.model'
import { VideoPlaylist } from '@app/shared/shared-video-playlist/video-playlist.model'
import { VideoPlaylistService } from '@app/shared/shared-video-playlist/video-playlist.service'
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
import { VideoPlaylistPrivacy } from '@peertube/peertube-models'
import { getBoolOrDefault } from '@root-helpers/local-storage-utils'
import { peertubeSessionStorage } from '@root-helpers/peertube-web-storage'
import { VideoPlaylistPrivacy } from '@peertube/peertube-models'
import { VideoPlaylistElementMiniatureComponent } from '../../../../shared/shared-video-playlist/video-playlist-element-miniature.component'
import { GlobalIconComponent } from '../../../../shared/shared-icons/global-icon.component'
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
import { InfiniteScrollerDirective } from '../../../../shared/shared-main/common/infinite-scroller.directive'
import { NgIf, NgClass, NgFor } from '@angular/common'
import { VideoPlaylist } from '@app/shared/shared-video-playlist/video-playlist.model'
import { VideoPlaylistElement } from '@app/shared/shared-video-playlist/video-playlist-element.model'
import { VideoPlaylistService } from '@app/shared/shared-video-playlist/video-playlist.service'
import { VideoPlaylistElementMiniatureComponent } from '../../../../shared/shared-video-playlist/video-playlist-element-miniature.component'
@Component({
selector: 'my-video-watch-playlist',
@ -74,7 +82,7 @@ export class VideoWatchPlaylistComponent {
onElementRemoved (playlistElement: VideoPlaylistElement) {
this.playlistElements = this.playlistElements.filter(e => e.id !== playlistElement.id)
this.playlistPagination.totalItems--
updatePaginationOnDelete(this.playlistPagination)
}
isPlaylistOwned () {

View File

@ -2,11 +2,12 @@ export interface ComponentPagination {
currentPage: number
itemsPerPage: number
totalItems: number
itemsRemoved?: number
}
export type ComponentPaginationLight = Omit<ComponentPagination, 'totalItems'> & { totalItems?: number }
export function hasMoreItems (componentPagination: ComponentPagination) {
export function hasMoreItems (componentPagination: ComponentPaginationLight) {
// No results
if (componentPagination.totalItems === 0) return false
@ -16,3 +17,16 @@ export function hasMoreItems (componentPagination: ComponentPagination) {
const maxPage = componentPagination.totalItems / componentPagination.itemsPerPage
return maxPage > componentPagination.currentPage
}
export function updatePaginationOnDelete (componentPagination: ComponentPagination, itemsDeleted = 1) {
componentPagination.totalItems -= itemsDeleted
if (!componentPagination.itemsRemoved) componentPagination.itemsRemoved = 0
componentPagination.itemsRemoved += itemsDeleted
}
export function resetCurrentPage (componentPagination: ComponentPaginationLight) {
componentPagination.currentPage = 1
componentPagination.itemsRemoved = 0
}

View File

@ -72,10 +72,11 @@ export class RestService {
}
componentToRestPagination (componentPagination: ComponentPaginationLight): RestPagination {
const start: number = (componentPagination.currentPage - 1) * componentPagination.itemsPerPage
const count: number = componentPagination.itemsPerPage
const { currentPage, itemsPerPage, itemsRemoved = 0 } = componentPagination
return { start, count }
const start = Math.max(0, (currentPage - 1) * itemsPerPage - itemsRemoved)
return { start, count: itemsPerPage }
}
/*

View File

@ -33,7 +33,7 @@
<my-video-miniature
[video]="live" [user]="userMiniature" [displayAsRow]="displayAsRow"
[displayVideoActions]="displayVideoActions" [displayOptions]="displayOptions"
(videoBlocked)="removeVideoFromArray(live)" (liveRemoved)="removeVideoFromArray(live)"
(videoBlocked)="removeVideoFromArray(live)" (videoRemoved)="removeVideoFromArray(live)"
>
</my-video-miniature>
</div>

View File

@ -3,12 +3,15 @@ import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, S
import { ActivatedRoute } from '@angular/router'
import {
AuthService,
ComponentPagination,
ComponentPaginationLight,
Notifier,
PeerTubeRouterService,
ScreenService,
User,
UserService
UserService,
resetCurrentPage,
updatePaginationOnDelete
} from '@app/core'
import { GlobalIconComponent, GlobalIconName } from '@app/shared/shared-icons/global-icon.component'
import { isLastMonth, isLastWeek, isThisMonth, isToday, isYesterday } from '@peertube/peertube-core-utils'
@ -112,9 +115,10 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
private userSub: Subscription
private resizeSub: Subscription
private pagination: ComponentPaginationLight = {
private pagination: ComponentPagination = {
currentPage: 1,
itemsPerPage: 25
itemsPerPage: 25,
totalItems: null
}
private groupedDateLabels: { [id in GroupDate]: string }
@ -276,12 +280,17 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
}
reloadVideos () {
this.pagination.currentPage = 1
resetCurrentPage(this.pagination)
this.loadMoreVideos(true)
}
removeVideoFromArray (video: Video) {
this.videos = this.videos.filter(v => v.id !== video.id)
if (this.videos.some(v => v.id === video.id)) {
this.videos = this.videos.filter(v => v.id !== video.id)
updatePaginationOnDelete(this.pagination)
}
this.highlightedLives = this.highlightedLives.filter(v => v.id !== video.id)
}

View File

@ -17,19 +17,16 @@
[displayVideoActions]="false" [user]="user"
></my-video-miniature>
<!-- Display only once -->
<div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0">
<div class="action-selection-mode-child">
<button i18n class="cancel-selection peertube-button secondary-button me-2" (click)="abortSelectionMode()">
Cancel
</button>
<ng-container *ngTemplateOutlet="globalButtonsTemplate"></ng-container>
</div>
</div>
<ng-container *ngIf="isInSelectionMode() === false">
@if (isInSelectionMode() === false) {
<ng-container *ngTemplateOutlet="rowButtonsTemplate; context: {$implicit: video}"></ng-container>
</ng-container>
}
</div>
</div>
<div class="action-selection-mode" *ngIf="isInSelectionMode() === true">
<button i18n class="cancel-selection peertube-button secondary-button me-2" (click)="abortSelectionMode()">
Cancel
</button>
<ng-container *ngTemplateOutlet="globalButtonsTemplate"></ng-container>
</div>

View File

@ -2,14 +2,10 @@
@use '_mixins' as *;
.action-selection-mode {
display: flex;
justify-content: flex-end;
flex-grow: 1;
}
.action-selection-mode-child {
position: fixed;
display: flex;
bottom: 1rem;
@include right(#{pvar(--x-margin-content)});
.action-button {
display: block;
@ -45,10 +41,10 @@
}
.checkbox-container {
display: none;
display: none !important;
}
.action-selection-mode {
display: none; // disable for small screens
display: none !important; // disable for small screens
}
}

View File

@ -1,16 +1,16 @@
import { Observable, Subject } from 'rxjs'
import { NgFor, NgIf, NgTemplateOutlet } from '@angular/common'
import { AfterContentInit, Component, ContentChildren, EventEmitter, Input, Output, QueryList, TemplateRef } from '@angular/core'
import { ComponentPagination, Notifier, User } from '@app/core'
import { logger } from '@root-helpers/logger'
import { FormsModule } from '@angular/forms'
import { ComponentPagination, Notifier, resetCurrentPage, User } from '@app/core'
import { objectKeysTyped } from '@peertube/peertube-core-utils'
import { ResultList, VideosExistInPlaylists, VideoSortField } from '@peertube/peertube-models'
import { MiniatureDisplayOptions, VideoMiniatureComponent } from './video-miniature.component'
import { FormsModule } from '@angular/forms'
import { logger } from '@root-helpers/logger'
import { Observable, Subject } from 'rxjs'
import { PeertubeCheckboxComponent } from '../shared-forms/peertube-checkbox.component'
import { InfiniteScrollerDirective } from '../shared-main/common/infinite-scroller.directive'
import { NgIf, NgFor, NgTemplateOutlet } from '@angular/common'
import { Video } from '../shared-main/video/video.model'
import { PeerTubeTemplateDirective } from '../shared-main/common/peertube-template.directive'
import { Video } from '../shared-main/video/video.model'
import { MiniatureDisplayOptions, VideoMiniatureComponent } from './video-miniature.component'
export type SelectionType = { [ id: number ]: boolean }
@ -145,11 +145,7 @@ export class VideosSelectionComponent implements AfterContentInit {
}
reloadVideos () {
this.pagination.currentPage = 1
resetCurrentPage(this.pagination)
this.loadMoreVideos(true)
}
removeVideoFromArray (video: Video) {
this.videos = this.videos.filter(v => v.id !== video.id)
}
}