import Collection from "@discordjs/collection";
import { UserType } from "../types/basicUser";
import Language from "../types/language";
import { SnowflakeString } from "../types/snowflake";
import File from "./file";
import { RequestContext } from "./requestContext";
import Snowflake from "./snowflake";
import User from "./user";
/**
* Used for getting and handling leaders
* @extends {User}
*/
class Leader extends User {
count: number;
/**
* Creates new leader object
*/
constructor({
id,
ctx,
name = "",
avatar,
description = "",
email = "",
auth = "",
password = "",
language = Language.EN,
type = UserType.MEMBER,
lastLogedIn,
count
}: {
id?: Snowflake,
ctx: RequestContext,
name?: string,
avatar?: File,
description?: string,
email?: string,
password?: string,
language?: Language,
auth?: string,
type?: UserType,
lastLogedIn?: Date,
count: number
}) {
super({
id,
ctx,
name,
avatar,
description,
email,
auth,
password,
language,
type,
lastLogedIn
});
this.count = count;
}
/**
* Extends user to leader class
* @param {Leader} user
* @param {number} count
* @return {Leader}
*/
static extend(user: User, count: number): Leader {
return new Leader({
...user,
count
});
}
/**
* Returns users with most animations
* @param {RequestContext} ctx
* @return {Promise<Collection<SnowflakeString, Leader>>}
*/
static getAnimationLeaders(ctx: RequestContext):
Promise<Collection<SnowflakeString, Leader>> {
const limit = 10;
return new Promise((resolve, reject) => {
ctx.conn.query(
`SELECT *, COUNT(animations.snowflake) as count FROM animations
GROUP BY animations.author ORDER BY count DESC LIMIT ?`,
[limit], async (err, res: any[]) => {
if(err) return reject(err);
const promises = res.map(async (a: any) => ({
user: await User.getUser(a.author, ctx),
count: a.count as number
}));
const result = new Collection<SnowflakeString, Leader>(
(await Promise.all(promises))
.map((partial) => {
return [
partial.user.id.toString(),
Leader.extend(partial.user, partial.count)
];
}));
resolve(result);
});
});
}
/**
* Returns follow leaders
* @param {RequestContext} ctx
* @return {Promise<Collection<SnowflakeString, Leader>>}
*/
static getFollowLeaders(ctx: RequestContext):
Promise<Collection<SnowflakeString, Leader>> {
const limit = 10;
return new Promise((resolve, reject) => {
ctx.conn.query(
`SELECT *, COUNT(user_relations.snowflake) as count FROM user_relations
GROUP BY user_relations.target ORDER BY count DESC LIMIT ?`,
[limit], async (err, res: any[]) => {
if(err) return reject(err);
const promises = res.map(async (a: any) => ({
user: await User.getUser(a.author, ctx),
count: a.count as number
}));
const result = new Collection<SnowflakeString, Leader>(
(await Promise.all(promises))
.map((partial) => {
return [
partial.user.id.toString(),
Leader.extend(partial.user, partial.count)
];
}));
resolve(result);
});
});
}
/**
* Returns users with most uploads
* @param {RequestContext} ctx
* @return {Promise<Collection<SnowflakeString, Leader>>}
*/
static getUploadLeaders(ctx: RequestContext):
Promise<Collection<SnowflakeString, Leader>> {
const limit = 10;
return new Promise((resolve, reject) => {
ctx.conn.query(
`SELECT *, COUNT(files.snowflake) as count FROM files
GROUP BY files.author ORDER BY count DESC LIMIT ?`,
[limit], async (err, res: any[]) => {
if(err) return reject(err);
const promises = res.map(async (a: any) => ({
user: await User.getUser(a.author, ctx),
count: a.count as number
}));
const result = new Collection<SnowflakeString, Leader>(
(await Promise.all(promises))
.map((partial) => {
return [
partial.user.id.toString(),
Leader.extend(partial.user, partial.count)
];
}));
resolve(result);
});
});
}
/**
* Returns users with most comments
* @param {RequestContext} ctx
* @return {Promise<Collection<SnowflakeString, Leader>>}
*/
static getCommentLeaders(ctx: RequestContext):
Promise<Collection<SnowflakeString, Leader>> {
const limit = 10;
return new Promise((resolve, reject) => {
ctx.conn.query(
`SELECT *, COUNT(comments.snowflake) as count FROM comments
GROUP BY comments.user ORDER BY count DESC LIMIT ?`,
[limit], async (err, res: any[]) => {
if(err) return reject(err);
const promises = res.map(async (a: any) => ({
user: await User.getUser(a.user, ctx),
count: a.count as number
}));
const result = new Collection<SnowflakeString, Leader>(
(await Promise.all(promises))
.map((partial) => {
return [
partial.user.id.toString(),
Leader.extend(partial.user, partial.count)
];
}));
resolve(result);
});
});
}
/**
* Returns users with most views
* @param {RequestContext} ctx
* @return {Promise<Collection<SnowflakeString, Leader>>}
*/
static getViewLeaders(ctx: RequestContext):
Promise<Collection<SnowflakeString, Leader>> {
const limit = 10;
return new Promise((resolve, reject) => {
ctx.conn.query(
`SELECT *, SUM(animations.views) as count FROM animations
GROUP BY animations.author ORDER BY count DESC LIMIT ?`,
[limit], async (err, res: any[]) => {
if(err) return reject(err);
const promises = res.map(async (a: any) => ({
user: await User.getUser(a.author, ctx),
count: a.count as number
}));
const result = new Collection<SnowflakeString, Leader>(
(await Promise.all(promises))
.map((partial) => {
return [
partial.user.id.toString(),
Leader.extend(partial.user, partial.count)
];
}));
resolve(result);
});
});
}
/**
* Returns users with most 5-star ratings
* @param {RequestContext} ctx
* @return {Promise<Collection<SnowflakeString, Leader>>}
*/
static getRatingLeaders(ctx: RequestContext):
Promise<Collection<SnowflakeString, Leader>> {
const limit = 10;
return new Promise((resolve, reject) => {
ctx.conn.query(
`SELECT *, COUNT(ratings.snowflake) as count FROM ratings WHERE ratings.stars = 5
GROUP BY ratings.author ORDER BY count DESC LIMIT ?`,
[limit], async (err, res: any[]) => {
if(err) return reject(err);
const promises = res.map(async (a: any) => ({
user: await User.getUser(a.author, ctx),
count: a.count as number
}));
const result = new Collection<SnowflakeString, Leader>(
(await Promise.all(promises))
.map((partial) => {
return [
partial.user.id.toString(),
Leader.extend(partial.user, partial.count)
];
}));
resolve(result);
});
});
}
/**
* Converts to JSON compatible object
* @return {object}
*/
toJSON() {
return {
...super.toJSON(),
count: this.count
};
}
};
export default Leader;
Source