Source

classes/leader.ts

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;