Normalize modal close buttons, and cancel/submit button styles
[oweals/peertube.git] / client / src / app / shared / video / video.model.ts
1 import { User } from '../'
2 import { UserRight, Video as VideoServerModel, VideoPrivacy, VideoState } from '../../../../../shared'
3 import { Avatar } from '../../../../../shared/models/avatars/avatar.model'
4 import { VideoConstant } from '../../../../../shared/models/videos/video-constant.model'
5 import { durationToString, getAbsoluteAPIUrl } from '../misc/utils'
6 import { peertubeTranslate, ServerConfig } from '../../../../../shared/models'
7 import { Actor } from '@app/shared/actor/actor.model'
8 import { VideoScheduleUpdate } from '../../../../../shared/models/videos/video-schedule-update.model'
9 import { AuthUser } from '@app/core'
10
11 export class Video implements VideoServerModel {
12   byVideoChannel: string
13   byAccount: string
14
15   accountAvatarUrl: string
16   videoChannelAvatarUrl: string
17
18   createdAt: Date
19   updatedAt: Date
20   publishedAt: Date
21   originallyPublishedAt: Date | string
22   category: VideoConstant<number>
23   licence: VideoConstant<number>
24   language: VideoConstant<string>
25   privacy: VideoConstant<VideoPrivacy>
26   description: string
27   duration: number
28   durationLabel: string
29   id: number
30   uuid: string
31   isLocal: boolean
32   name: string
33   serverHost: string
34   thumbnailPath: string
35   thumbnailUrl: string
36   previewPath: string
37   previewUrl: string
38   embedPath: string
39   embedUrl: string
40   views: number
41   likes: number
42   dislikes: number
43   nsfw: boolean
44
45   originInstanceUrl: string
46   originInstanceHost: string
47
48   waitTranscoding?: boolean
49   state?: VideoConstant<VideoState>
50   scheduledUpdate?: VideoScheduleUpdate
51   blacklisted?: boolean
52   blacklistedReason?: string
53
54   account: {
55     id: number
56     name: string
57     displayName: string
58     url: string
59     host: string
60     avatar?: Avatar
61   }
62
63   channel: {
64     id: number
65     name: string
66     displayName: string
67     url: string
68     host: string
69     avatar?: Avatar
70   }
71
72   userHistory?: {
73     currentTime: number
74   }
75
76   static buildClientUrl (videoUUID: string) {
77     return '/videos/watch/' + videoUUID
78   }
79
80   constructor (hash: VideoServerModel, translations = {}) {
81     const absoluteAPIUrl = getAbsoluteAPIUrl()
82
83     this.createdAt = new Date(hash.createdAt.toString())
84     this.publishedAt = new Date(hash.publishedAt.toString())
85     this.category = hash.category
86     this.licence = hash.licence
87     this.language = hash.language
88     this.privacy = hash.privacy
89     this.waitTranscoding = hash.waitTranscoding
90     this.state = hash.state
91     this.description = hash.description
92
93     this.duration = hash.duration
94     this.durationLabel = durationToString(hash.duration)
95
96     this.id = hash.id
97     this.uuid = hash.uuid
98
99     this.isLocal = hash.isLocal
100     this.name = hash.name
101
102     this.thumbnailPath = hash.thumbnailPath
103     this.thumbnailUrl = absoluteAPIUrl + hash.thumbnailPath
104
105     this.previewPath = hash.previewPath
106     this.previewUrl = absoluteAPIUrl + hash.previewPath
107
108     this.embedPath = hash.embedPath
109     this.embedUrl = absoluteAPIUrl + hash.embedPath
110
111     this.views = hash.views
112     this.likes = hash.likes
113     this.dislikes = hash.dislikes
114
115     this.nsfw = hash.nsfw
116
117     this.account = hash.account
118     this.channel = hash.channel
119
120     this.byAccount = Actor.CREATE_BY_STRING(hash.account.name, hash.account.host)
121     this.byVideoChannel = Actor.CREATE_BY_STRING(hash.channel.name, hash.channel.host)
122     this.accountAvatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.account)
123     this.videoChannelAvatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.channel)
124
125     this.category.label = peertubeTranslate(this.category.label, translations)
126     this.licence.label = peertubeTranslate(this.licence.label, translations)
127     this.language.label = peertubeTranslate(this.language.label, translations)
128     this.privacy.label = peertubeTranslate(this.privacy.label, translations)
129
130     this.scheduledUpdate = hash.scheduledUpdate
131     this.originallyPublishedAt = hash.originallyPublishedAt ? new Date(hash.originallyPublishedAt.toString()) : null
132
133     if (this.state) this.state.label = peertubeTranslate(this.state.label, translations)
134
135     this.blacklisted = hash.blacklisted
136     this.blacklistedReason = hash.blacklistedReason
137
138     this.userHistory = hash.userHistory
139
140     this.originInstanceHost = this.account.host
141     this.originInstanceUrl = 'https://' + this.originInstanceHost
142   }
143
144   isVideoNSFWForUser (user: User, serverConfig: ServerConfig) {
145     // Video is not NSFW, skip
146     if (this.nsfw === false) return false
147
148     // Return user setting if logged in
149     if (user) return user.nsfwPolicy !== 'display'
150
151     // Return default instance config
152     return serverConfig.instance.defaultNSFWPolicy !== 'display'
153   }
154
155   isRemovableBy (user: AuthUser) {
156     return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.REMOVE_ANY_VIDEO))
157   }
158
159   isBlackistableBy (user: AuthUser) {
160     return this.blacklisted !== true && user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true
161   }
162
163   isUnblacklistableBy (user: AuthUser) {
164     return this.blacklisted === true && user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true
165   }
166
167   isUpdatableBy (user: AuthUser) {
168     return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.UPDATE_ANY_VIDEO))
169   }
170
171   canBeDuplicatedBy (user: AuthUser) {
172     return user && this.isLocal === false && user.hasRight(UserRight.MANAGE_VIDEOS_REDUNDANCIES)
173   }
174 }