mirror of https://github.com/Chocobozzz/PeerTube
Group videos on chronological order
parent
e6b04e0e79
commit
34c7f429e4
|
@ -29,6 +29,7 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
|
|||
private accountSub: Subscription
|
||||
|
||||
constructor (
|
||||
protected i18n: I18n,
|
||||
protected router: Router,
|
||||
protected serverService: ServerService,
|
||||
protected route: ActivatedRoute,
|
||||
|
@ -36,7 +37,6 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
|
|||
protected notifier: Notifier,
|
||||
protected confirmService: ConfirmService,
|
||||
protected screenService: ScreenService,
|
||||
private i18n: I18n,
|
||||
private accountService: AccountService,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
|
|
|
@ -27,6 +27,7 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn
|
|||
videosHistoryEnabled: boolean
|
||||
|
||||
constructor (
|
||||
protected i18n: I18n,
|
||||
protected router: Router,
|
||||
protected serverService: ServerService,
|
||||
protected route: ActivatedRoute,
|
||||
|
@ -34,7 +35,6 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn
|
|||
protected userService: UserService,
|
||||
protected notifier: Notifier,
|
||||
protected screenService: ScreenService,
|
||||
protected i18n: I18n,
|
||||
private confirmService: ConfirmService,
|
||||
private videoService: VideoService,
|
||||
private userHistoryService: UserHistoryService
|
||||
|
|
|
@ -29,6 +29,7 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
|
|||
private videoChannelSub: Subscription
|
||||
|
||||
constructor (
|
||||
protected i18n: I18n,
|
||||
protected router: Router,
|
||||
protected serverService: ServerService,
|
||||
protected route: ActivatedRoute,
|
||||
|
@ -36,7 +37,6 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
|
|||
protected notifier: Notifier,
|
||||
protected confirmService: ConfirmService,
|
||||
protected screenService: ScreenService,
|
||||
private i18n: I18n,
|
||||
private videoChannelService: VideoChannelService,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
|
|
|
@ -22,11 +22,18 @@
|
|||
myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true"
|
||||
class="videos"
|
||||
>
|
||||
<my-video-miniature
|
||||
*ngFor="let video of videos; trackBy: videoById" [video]="video" [user]="user" [ownerDisplayType]="ownerDisplayType"
|
||||
[displayVideoActions]="displayVideoActions" [displayOptions]="displayOptions"
|
||||
(videoBlacklisted)="removeVideoFromArray(video)" (videoRemoved)="removeVideoFromArray(video)"
|
||||
>
|
||||
</my-video-miniature>
|
||||
<ng-container *ngFor="let video of videos; trackBy: videoById;">
|
||||
<div class="date-title" *ngIf="getCurrentGroupedDateLabel(video)">
|
||||
{{ getCurrentGroupedDateLabel(video) }}
|
||||
</div>
|
||||
|
||||
|
||||
<my-video-miniature
|
||||
[video]="video" [user]="user" [ownerDisplayType]="ownerDisplayType"
|
||||
[displayVideoActions]="displayVideoActions" [displayOptions]="displayOptions"
|
||||
(videoBlacklisted)="removeVideoFromArray(video)" (videoRemoved)="removeVideoFromArray(video)"
|
||||
>
|
||||
</my-video-miniature>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -24,6 +24,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
.date-title {
|
||||
font-size: 16px;
|
||||
font-weight: $font-semibold;
|
||||
margin-bottom: 20px;
|
||||
margin-top: -10px;
|
||||
padding-top: 20px;
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top: 1px solid $separator-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
.margin-content {
|
||||
@include adapt-margin-content-width;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,17 @@ import { MiniatureDisplayOptions, OwnerDisplayType } from '@app/shared/video/vid
|
|||
import { Syndication } from '@app/shared/video/syndication.model'
|
||||
import { Notifier, ServerService } from '@app/core'
|
||||
import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
import { isThisMonth, isThisWeek, isToday, isYesterday } from '@shared/core-utils/miscs/date'
|
||||
|
||||
enum GroupDate {
|
||||
UNKNOWN = 0,
|
||||
TODAY = 1,
|
||||
YESTERDAY = 2,
|
||||
THIS_WEEK = 3,
|
||||
THIS_MONTH = 4,
|
||||
OLDER = 5
|
||||
}
|
||||
|
||||
export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableForReuseHook {
|
||||
pagination: ComponentPagination = {
|
||||
|
@ -31,6 +42,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
|
|||
displayModerationBlock = false
|
||||
titleTooltip: string
|
||||
displayVideoActions = true
|
||||
groupByDate = false
|
||||
|
||||
disabled = false
|
||||
|
||||
|
@ -50,11 +62,15 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
|
|||
protected abstract serverService: ServerService
|
||||
protected abstract screenService: ScreenService
|
||||
protected abstract router: Router
|
||||
protected abstract i18n: I18n
|
||||
abstract titlePage: string
|
||||
|
||||
private resizeSubscription: Subscription
|
||||
private angularState: number
|
||||
|
||||
private groupedDateLabels: { [id in GroupDate]: string }
|
||||
private groupedDates: { [id: number]: GroupDate } = {}
|
||||
|
||||
abstract getVideosObservable (page: number): Observable<{ videos: Video[], totalVideos: number }>
|
||||
|
||||
abstract generateSyndicationList (): void
|
||||
|
@ -64,6 +80,15 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
|
|||
}
|
||||
|
||||
ngOnInit () {
|
||||
this.groupedDateLabels = {
|
||||
[GroupDate.UNKNOWN]: null,
|
||||
[GroupDate.TODAY]: this.i18n('Today'),
|
||||
[GroupDate.YESTERDAY]: this.i18n('Yesterday'),
|
||||
[GroupDate.THIS_WEEK]: this.i18n('This week'),
|
||||
[GroupDate.THIS_MONTH]: this.i18n('This month'),
|
||||
[GroupDate.OLDER]: this.i18n('Older')
|
||||
}
|
||||
|
||||
// Subscribe to route changes
|
||||
const routeParams = this.route.snapshot.queryParams
|
||||
this.loadRouteParams(routeParams)
|
||||
|
@ -113,6 +138,8 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
|
|||
this.pagination.totalItems = totalVideos
|
||||
this.videos = this.videos.concat(videos)
|
||||
|
||||
if (this.groupByDate) this.buildGroupedDateLabels()
|
||||
|
||||
this.onMoreVideos()
|
||||
},
|
||||
|
||||
|
@ -134,6 +161,49 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
|
|||
this.videos = this.videos.filter(v => v.id !== video.id)
|
||||
}
|
||||
|
||||
buildGroupedDateLabels () {
|
||||
let currentGroupedDate: GroupDate = GroupDate.UNKNOWN
|
||||
|
||||
for (const video of this.videos) {
|
||||
const publishedDate = video.publishedAt
|
||||
|
||||
if (currentGroupedDate < GroupDate.TODAY && isToday(publishedDate)) {
|
||||
currentGroupedDate = GroupDate.TODAY
|
||||
this.groupedDates[ video.id ] = currentGroupedDate
|
||||
continue
|
||||
}
|
||||
|
||||
if (currentGroupedDate < GroupDate.YESTERDAY && isYesterday(publishedDate)) {
|
||||
currentGroupedDate = GroupDate.YESTERDAY
|
||||
this.groupedDates[ video.id ] = currentGroupedDate
|
||||
continue
|
||||
}
|
||||
|
||||
if (currentGroupedDate < GroupDate.THIS_WEEK && isThisWeek(publishedDate)) {
|
||||
currentGroupedDate = GroupDate.THIS_WEEK
|
||||
this.groupedDates[ video.id ] = currentGroupedDate
|
||||
continue
|
||||
}
|
||||
|
||||
if (currentGroupedDate < GroupDate.THIS_MONTH && isThisMonth(publishedDate)) {
|
||||
currentGroupedDate = GroupDate.THIS_MONTH
|
||||
this.groupedDates[ video.id ] = currentGroupedDate
|
||||
continue
|
||||
}
|
||||
|
||||
if (currentGroupedDate < GroupDate.OLDER) {
|
||||
currentGroupedDate = GroupDate.OLDER
|
||||
this.groupedDates[ video.id ] = currentGroupedDate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentGroupedDateLabel (video: Video) {
|
||||
if (this.groupByDate === false) return undefined
|
||||
|
||||
return this.groupedDateLabels[this.groupedDates[video.id]]
|
||||
}
|
||||
|
||||
// On videos hook for children that want to do something
|
||||
protected onMoreVideos () { /* empty */ }
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import { Video } from '@app/shared/video/video.model'
|
|||
import { PeerTubeTemplateDirective } from '@app/shared/angular/peertube-template.directive'
|
||||
import { VideoSortField } from '@app/shared/video/sort-field.type'
|
||||
import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
export type SelectionType = { [ id: number ]: boolean }
|
||||
|
||||
|
@ -44,6 +45,7 @@ export class VideosSelectionComponent extends AbstractVideoList implements OnIni
|
|||
globalButtonsTemplate: TemplateRef<any>
|
||||
|
||||
constructor (
|
||||
protected i18n: I18n,
|
||||
protected router: Router,
|
||||
protected route: ActivatedRoute,
|
||||
protected notifier: Notifier,
|
||||
|
|
|
@ -22,13 +22,13 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On
|
|||
filter: VideoFilter = 'local'
|
||||
|
||||
constructor (
|
||||
protected i18n: I18n,
|
||||
protected router: Router,
|
||||
protected serverService: ServerService,
|
||||
protected route: ActivatedRoute,
|
||||
protected notifier: Notifier,
|
||||
protected authService: AuthService,
|
||||
protected screenService: ScreenService,
|
||||
private i18n: I18n,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
|
|
@ -17,15 +17,16 @@ import { Notifier, ServerService } from '@app/core'
|
|||
export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
||||
titlePage: string
|
||||
sort: VideoSortField = '-publishedAt'
|
||||
groupByDate = true
|
||||
|
||||
constructor (
|
||||
protected i18n: I18n,
|
||||
protected route: ActivatedRoute,
|
||||
protected serverService: ServerService,
|
||||
protected router: Router,
|
||||
protected notifier: Notifier,
|
||||
protected authService: AuthService,
|
||||
protected screenService: ScreenService,
|
||||
private i18n: I18n,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
|
|
@ -19,13 +19,13 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit,
|
|||
defaultSort: VideoSortField = '-trending'
|
||||
|
||||
constructor (
|
||||
protected i18n: I18n,
|
||||
protected router: Router,
|
||||
protected serverService: ServerService,
|
||||
protected route: ActivatedRoute,
|
||||
protected notifier: Notifier,
|
||||
protected authService: AuthService,
|
||||
protected screenService: ScreenService,
|
||||
private i18n: I18n,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
|
|
@ -19,15 +19,16 @@ export class VideoUserSubscriptionsComponent extends AbstractVideoList implement
|
|||
titlePage: string
|
||||
sort = '-publishedAt' as VideoSortField
|
||||
ownerDisplayType: OwnerDisplayType = 'auto'
|
||||
groupByDate = true
|
||||
|
||||
constructor (
|
||||
protected i18n: I18n,
|
||||
protected router: Router,
|
||||
protected serverService: ServerService,
|
||||
protected route: ActivatedRoute,
|
||||
protected notifier: Notifier,
|
||||
protected authService: AuthService,
|
||||
protected screenService: ScreenService,
|
||||
private i18n: I18n,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
function isToday (d: Date) {
|
||||
const today = new Date()
|
||||
|
||||
return areDatesEqual(d, today)
|
||||
}
|
||||
|
||||
function isYesterday (d: Date) {
|
||||
const yesterday = new Date()
|
||||
yesterday.setDate(yesterday.getDate() - 1)
|
||||
|
||||
return areDatesEqual(d, yesterday)
|
||||
}
|
||||
|
||||
function isThisWeek (d: Date) {
|
||||
const minDateOfThisWeek = new Date()
|
||||
minDateOfThisWeek.setHours(0, 0, 0)
|
||||
|
||||
// getDay() -> Sunday - Saturday : 0 - 6
|
||||
// We want to start our week on Monday
|
||||
let dayOfWeek = minDateOfThisWeek.getDay() - 1
|
||||
if (dayOfWeek < 0) dayOfWeek = 6 // Sunday
|
||||
|
||||
minDateOfThisWeek.setDate(minDateOfThisWeek.getDate() - dayOfWeek)
|
||||
|
||||
return d >= minDateOfThisWeek
|
||||
}
|
||||
|
||||
function isThisMonth (d: Date) {
|
||||
const thisMonth = new Date().getMonth()
|
||||
|
||||
return d.getMonth() === thisMonth
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
isYesterday,
|
||||
isThisWeek,
|
||||
isThisMonth,
|
||||
isToday
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function areDatesEqual (d1: Date, d2: Date) {
|
||||
return d1.getFullYear() === d2.getFullYear() &&
|
||||
d1.getMonth() === d2.getMonth() &&
|
||||
d1.getDate() === d2.getDate()
|
||||
}
|
Loading…
Reference in New Issue