import Snowflake from "./snowflake";
import User from "./user";
import Animation, { BasicAnimation } from "./animation";
import { SnowflakeResolvable, SnowflakeString } from "../types/snowflake";
import UserClient from "./userClient";
import { UserResolvable } from "../types/user";
import { AnimationResolvable } from "../types/animation";
import { RequestContext } from "./requestContext";
import {
DBRating,
DBRatingFull,
DBRatingWithAnimation,
DBRatingWithAuthor,
prisma
} from "../../prisma";
/**
* Holds data about animation rating
*/
class Rating {
id: Snowflake;
ctx: RequestContext;
client?: UserClient;
user: User;
animation: BasicAnimation;
stars: number;
/**
* Creates animation rating data holder
* @param {object} data
*/
constructor({
id,
ctx,
user,
animation,
stars
}: {
id: Snowflake;
ctx: RequestContext;
user: User;
animation: BasicAnimation;
stars: number;
}) {
this.id = id;
this.ctx = ctx;
this.client = ctx.client;
this.user = user;
this.animation = animation;
this.stars = stars;
}
/**
* @param {DBRating | DBRatingWithAnimation | DBRatingWithAuthor | DBRatingFull} data
* @param {RequestContext} ctx
*/
static async fromDatabase(
data: DBRating | DBRatingWithAnimation | DBRatingWithAuthor | DBRatingFull,
ctx: RequestContext
) {
return new Rating({
id: new Snowflake(data.snowflake),
ctx,
user:
"author" in data ?
await User.fromDatabase(data.author, ctx) :
await User.getUser(data.authorId, ctx),
animation:
"animation" in data ?
await Animation.fromDatabase(data.animation, ctx) :
await Animation.getAnimation(data.animationId, ctx),
stars: data.stars
});
}
/**
* Updates the rating
* @return {Promise<void>}
*/
async update(): Promise<void> {
await prisma.rating.update({
where: {
snowflake: this.id.toBigInt()
},
data: {
stars: this.stars
}
});
}
/**
* Deletes the rating
* @return {Promise<void>}
*/
async delete(): Promise<void> {
await prisma.rating.delete({
where: {
snowflake: this.id.toBigInt()
}
});
}
/**
* Fetches a rating from given user and animation
* @param {UserResolvable} user
* @param {AnimationResolvable} animation
* @param {RequestContext} ctx
* @return {Promise}
*/
static async getUserRating(
user: UserResolvable,
animation: AnimationResolvable,
ctx: RequestContext
): Promise<Rating | null> {
const res = await prisma.rating.findUnique({
where: {
authorId_animationId: {
authorId: BigInt(User.resolveUserID(user)),
animationId: BigInt(Animation.resolveAnimationID(animation))
}
}
});
if(!res) return null;
return Rating.fromDatabase(res, ctx);
}
/**
* Returns rating with specified id
* @param {SnowflakeResolvable} id
* @param {RequestContext} ctx
* @return {Promise<Rating>}
*/
static async getRating(
id: SnowflakeResolvable,
ctx: RequestContext
): Promise<Rating> {
const res = await prisma.rating.findUniqueOrThrow({
where: {
snowflake: new Snowflake(id).toBigInt()
}
});
return Rating.fromDatabase(res, ctx);
}
/**
* Creates a JSON-compatible object
* @return {Object}
*/
toJSON() {
return {
id: this.id.getSnowflake(),
user: this.user.toJSON(),
animation: this.animation.toJSON(),
stars: this.stars,
time: this.id.time
};
}
}
export default Rating;
Source