import {
- AfterDestroy,
AllowNull,
+ BeforeDestroy,
BelongsTo,
Column,
CreatedAt,
+ DataType,
+ Default,
DefaultScope,
ForeignKey,
HasMany,
UpdatedAt
} from 'sequelize-typescript'
import { ActivityPubActor } from '../../../shared/models/activitypub'
-import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels'
+import { VideoChannel } from '../../../shared/models/videos'
+import {
+ isVideoChannelDescriptionValid,
+ isVideoChannelNameValid,
+ isVideoChannelSupportValid
+} from '../../helpers/custom-validators/video-channels'
import { sendDeleteActor } from '../../lib/activitypub/send'
import { AccountModel } from '../account/account'
import { ActorModel } from '../activitypub/actor'
import { getSort, throwIfNotValid } from '../utils'
import { VideoModel } from './video'
+import { CONSTRAINTS_FIELDS } from '../../initializers'
+import { AvatarModel } from '../avatar/avatar'
enum ScopeNames {
WITH_ACCOUNT = 'WITH_ACCOUNT',
[ScopeNames.WITH_ACCOUNT]: {
include: [
{
- model: () => AccountModel,
+ model: () => AccountModel.unscoped(),
required: true,
include: [
{
- model: () => ActorModel,
- required: true
+ model: () => ActorModel.unscoped(),
+ required: true,
+ include: [
+ {
+ model: () => AvatarModel.unscoped(),
+ required: false
+ }
+ ]
}
]
}
indexes: [
{
fields: [ 'accountId' ]
+ },
+ {
+ fields: [ 'actorId' ]
}
]
})
name: string
@AllowNull(true)
+ @Default(null)
@Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description'))
- @Column
+ @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.DESCRIPTION.max))
description: string
+ @AllowNull(true)
+ @Default(null)
+ @Is('VideoChannelSupport', value => throwIfNotValid(value, isVideoChannelSupportValid, 'support'))
+ @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.SUPPORT.max))
+ support: string
+
@CreatedAt
createdAt: Date
foreignKey: {
allowNull: false
},
- onDelete: 'CASCADE'
+ hooks: true
})
Account: AccountModel
name: 'channelId',
allowNull: false
},
- onDelete: 'CASCADE'
+ onDelete: 'CASCADE',
+ hooks: true
})
Videos: VideoModel[]
- @AfterDestroy
- static sendDeleteIfOwned (instance: VideoChannelModel) {
+ @BeforeDestroy
+ static async sendDeleteIfOwned (instance: VideoChannelModel, options) {
+ if (!instance.Actor) {
+ instance.Actor = await instance.$get('Actor', { transaction: options.transaction }) as ActorModel
+ }
+
if (instance.Actor.isOwned()) {
- return sendDeleteActor(instance.Actor, undefined)
+ return sendDeleteActor(instance.Actor, options.transaction)
}
return undefined
const query = {
offset: start,
limit: count,
- order: [ getSort(sort) ]
+ order: getSort(sort)
}
return VideoChannelModel
static listByAccount (accountId: number) {
const query = {
- order: [ getSort('createdAt') ],
+ order: getSort('createdAt'),
include: [
{
model: AccountModel,
.findById(id, options)
}
- toFormattedJSON () {
+ static loadLocalByName (name: string) {
+ const query = {
+ include: [
+ {
+ model: ActorModel,
+ required: true,
+ where: {
+ preferredUsername: name,
+ serverId: null
+ }
+ }
+ ]
+ }
+
+ return VideoChannelModel.findOne(query)
+ }
+
+ toFormattedJSON (): VideoChannel {
const actor = this.Actor.toFormattedJSON()
- const account = {
+ const videoChannel = {
id: this.id,
- name: this.name,
+ displayName: this.getDisplayName(),
description: this.description,
+ support: this.support,
isLocal: this.Actor.isOwned(),
createdAt: this.createdAt,
- updatedAt: this.updatedAt
+ updatedAt: this.updatedAt,
+ ownerAccount: undefined
}
- return Object.assign(actor, account)
+ if (this.Account) videoChannel.ownerAccount = this.Account.toFormattedJSON()
+
+ return Object.assign(actor, videoChannel)
}
toActivityPubObject (): ActivityPubActor {
return Object.assign(obj, {
summary: this.description,
+ support: this.support,
attributedTo: [
{
type: 'Person' as 'Person',
]
})
}
+
+ getDisplayName () {
+ return this.name
+ }
}