import { getServerActor } from '../../helpers/utils'
import { ACTOR_FOLLOW_SCORE, FOLLOW_STATES, SERVER_ACTOR_NAME } from '../../initializers/constants'
import { ServerModel } from '../server/server'
-import { createSafeIn, getSort } from '../utils'
+import { createSafeIn, getSort, getFollowsSort } from '../utils'
import { ActorModel, unusedActorAttributesForAPI } from './actor'
import { VideoChannelModel } from '../video/video-channel'
import { AccountModel } from '../account/account'
-import { IncludeOptions, Op, QueryTypes, Transaction } from 'sequelize'
+import { IncludeOptions, Op, QueryTypes, Transaction, WhereOptions } from 'sequelize'
import {
MActorFollowActorsDefault,
MActorFollowActorsDefaultSubscription,
MActorFollowFormattable,
MActorFollowSubscriptions
} from '@server/typings/models'
+import { ActivityPubActorType } from '@shared/models'
@Table({
tableName: 'actorFollow',
return ActorFollowModel.findAll(query)
}
- static listFollowingForApi (id: number, start: number, count: number, sort: string, search?: string) {
+ static listFollowingForApi (options: {
+ id: number,
+ start: number,
+ count: number,
+ sort: string,
+ state?: FollowState,
+ actorType?: ActivityPubActorType,
+ search?: string
+ }) {
+ const { id, start, count, sort, search, state, actorType } = options
+
+ const followWhere = state ? { state } : {}
+ const followingWhere: WhereOptions = {}
+ const followingServerWhere: WhereOptions = {}
+
+ if (search) {
+ Object.assign(followingServerWhere, {
+ host: {
+ [ Op.iLike ]: '%' + search + '%'
+ }
+ })
+ }
+
+ if (actorType) {
+ Object.assign(followingWhere, { type: actorType })
+ }
+
const query = {
distinct: true,
offset: start,
limit: count,
- order: getSort(sort),
+ order: getFollowsSort(sort),
+ where: followWhere,
include: [
{
model: ActorModel,
model: ActorModel,
as: 'ActorFollowing',
required: true,
+ where: followingWhere,
include: [
{
model: ServerModel,
required: true,
- where: search ? {
- host: {
- [Op.iLike]: '%' + search + '%'
- }
- } : undefined
+ where: followingServerWhere
}
]
}
})
}
- static listFollowersForApi (actorId: number, start: number, count: number, sort: string, search?: string) {
+ static listFollowersForApi (options: {
+ actorId: number,
+ start: number,
+ count: number,
+ sort: string,
+ state?: FollowState,
+ actorType?: ActivityPubActorType,
+ search?: string
+ }) {
+ const { actorId, start, count, sort, search, state, actorType } = options
+
+ const followWhere = state ? { state } : {}
+ const followerWhere: WhereOptions = {}
+ const followerServerWhere: WhereOptions = {}
+
+ if (search) {
+ Object.assign(followerServerWhere, {
+ host: {
+ [ Op.iLike ]: '%' + search + '%'
+ }
+ })
+ }
+
+ if (actorType) {
+ Object.assign(followerWhere, { type: actorType })
+ }
+
const query = {
distinct: true,
offset: start,
limit: count,
- order: getSort(sort),
+ order: getFollowsSort(sort),
+ where: followWhere,
include: [
{
model: ActorModel,
required: true,
as: 'ActorFollower',
+ where: followerWhere,
include: [
{
model: ServerModel,
required: true,
- where: search ? {
- host: {
- [ Op.iLike ]: '%' + search + '%'
- }
- } : undefined
+ where: followerServerWhere
}
]
},
}
const selections: string[] = []
- if (distinct === true) selections.push('DISTINCT("Follows"."' + columnUrl + '") AS "url"')
- else selections.push('"Follows"."' + columnUrl + '" AS "url"')
+ if (distinct === true) selections.push(`DISTINCT("Follows"."${columnUrl}") AS "selectionUrl"`)
+ else selections.push(`"Follows"."${columnUrl}" AS "selectionUrl"`)
selections.push('COUNT(*) AS "total"')
let query = 'SELECT ' + selection + ' FROM "actor" ' +
'INNER JOIN "actorFollow" ON "actorFollow"."' + firstJoin + '" = "actor"."id" ' +
'INNER JOIN "actor" AS "Follows" ON "actorFollow"."' + secondJoin + '" = "Follows"."id" ' +
- 'WHERE "actor"."id" = ANY ($actorIds) AND "actorFollow"."state" = \'accepted\' '
+ `WHERE "actor"."id" = ANY ($actorIds) AND "actorFollow"."state" = 'accepted' AND "Follows"."${columnUrl}" IS NOT NULL `
if (count !== undefined) query += 'LIMIT ' + count
if (start !== undefined) query += ' OFFSET ' + start
}
const [ followers, [ dataTotal ] ] = await Promise.all(tasks)
- const urls: string[] = followers.map(f => f.url)
+ const urls: string[] = followers.map(f => f.selectionUrl)
return {
data: urls,