private accountSub: Subscription
constructor (
+ protected i18n: I18n,
protected router: Router,
protected serverService: ServerService,
protected route: ActivatedRoute,
protected notifier: Notifier,
protected confirmService: ConfirmService,
protected screenService: ScreenService,
- private i18n: I18n,
private accountService: AccountService,
private videoService: VideoService
) {
videosHistoryEnabled: boolean
constructor (
+ protected i18n: I18n,
protected router: Router,
protected serverService: ServerService,
protected route: ActivatedRoute,
protected userService: UserService,
protected notifier: Notifier,
protected screenService: ScreenService,
- protected i18n: I18n,
private confirmService: ConfirmService,
private videoService: VideoService,
private userHistoryService: UserHistoryService
private videoChannelSub: Subscription
constructor (
+ protected i18n: I18n,
protected router: Router,
protected serverService: ServerService,
protected route: ActivatedRoute,
protected notifier: Notifier,
protected confirmService: ConfirmService,
protected screenService: ScreenService,
- private i18n: I18n,
private videoChannelService: VideoChannelService,
private videoService: VideoService
) {
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>
}
}
+.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;
}
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 = {
displayModerationBlock = false
titleTooltip: string
displayVideoActions = true
+ groupByDate = false
disabled = false
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
}
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)
this.pagination.totalItems = totalVideos
this.videos = this.videos.concat(videos)
+ if (this.groupByDate) this.buildGroupedDateLabels()
+
this.onMoreVideos()
},
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 */ }
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 }
globalButtonsTemplate: TemplateRef<any>
constructor (
+ protected i18n: I18n,
protected router: Router,
protected route: ActivatedRoute,
protected notifier: Notifier,
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()
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()
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()
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()
--- /dev/null
+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()
+}