@haelp/teto
Version:
A typescript-based controllable TETR.IO client.
257 lines (256 loc) • 9.36 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Social", {
enumerable: true,
get: function() {
return Social;
}
});
const _relationship = _export_star(require("./relationship"), exports);
function _export_star(from, to) {
Object.keys(from).forEach(function(k) {
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
Object.defineProperty(to, k, {
enumerable: true,
get: function() {
return from[k];
}
});
}
});
return from;
}
const processRelationship = (r, selfID)=>({
...r,
user: {
id: r.from._id === selfID ? r.to._id : r.from._id,
username: r.from._id === selfID ? r.to.username : r.from.username,
avatar: r.from._id === selfID ? r.to.avatar_revision : r.from.avatar_revision
}
});
class Social {
client;
/** The current number of people online */ online;
/** List of the client's friends */ friends;
/** List of "pending" relationships (shows in `other` tab on TETR.IO) */ other;
/** people you block */ blocked;
/** Notifications */ notifications;
/** @hideconstructor */ constructor(client, init){
this.client = client;
this.init();
this.online = init.online;
this.friends = init.friends.map((r)=>new _relationship.Relationship({
id: r.user.id,
relationshipID: r._id,
username: r.user.username,
avatar: r.user.avatar
}, this, this.client));
this.other = init.other.map((r)=>new _relationship.Relationship({
id: r.user.id,
relationshipID: r._id,
username: r.user.username,
avatar: r.user.avatar
}, this, this.client));
this.blocked = init.blocked;
this.notifications = init.notifications;
}
static async create(client, initData) {
const rel = initData.relationships.map((r)=>processRelationship(r, client.user.id));
const data = {
online: initData.total_online,
notifications: initData.notifications,
friends: rel.filter((r)=>r.type === "friend"),
other: rel.filter((r)=>r.type === "pending"),
blocked: rel.filter((r)=>r.type === "block").map((r)=>({
id: r.user.id,
username: r.user.username,
avatar: r.user.avatar
}))
};
return new Social(client, data);
}
get api() {
return this.client.api;
}
init() {
setTimeout(()=>this.notifications.forEach((n)=>{
if (n.type === "friend") {
if (!n.seen) {
const rel = processRelationship(n.data.relationship, this.client.user.id);
this.client.emit("client.friended", {
id: rel.user.id,
name: rel.user.username,
avatar: rel.user.avatar
});
}
}
}), 0);
this.client.on("social.online", (count)=>{
this.online = count;
});
this.client.on("social.notification", async (n)=>{
this.notifications.splice(0, 0, n);
if (n.type === "friend") {
const rel = processRelationship(n.data.relationship, this.client.user.id);
this.client.emit("client.friended", {
id: rel.user.id,
name: rel.user.username,
avatar: rel.user.avatar
});
const user = this.get({
id: rel.user.id
});
if (!user) {
this.other.push(new _relationship.Relationship({
id: rel.user.id,
username: rel.user.username,
avatar: rel.user.avatar,
relationshipID: ""
}, this, this.client));
}
}
});
this.client.on("social.dm", async (dm)=>{
let user = this.get({
id: dm.data.user
});
if (user) {
if (!user.dmsLoaded) await user.loadDms();
else user.dms.push(dm);
} else {
const u = await this.who(dm.data.user);
this.other.push(new _relationship.Relationship({
id: u._id,
username: u.username,
avatar: u.avatar_revision,
relationshipID: ""
}, this, this.client));
user = this.get({
id: dm.data.user
});
await user.loadDms();
}
this.client.emit("client.dm", {
user,
content: dm.data.content,
reply: async (content)=>{
await this.dm(dm.data.user, content);
}
});
});
}
/**
* Marks all notifications as read
* @example
* client.social.markNotificationsAsRead();
*/ markNotificationsAsRead() {
this.client.emit("social.notification.ack");
}
get(target) {
if (typeof target === "string") return this.friends.find((r)=>r.id === target || r.username === target) || this.other.find((r)=>r.id === target || r.username === target) || null;
else if ("id" in target) return this.friends.find((r)=>r.id === target.id) || this.other.find((r)=>r.id === target.id) || null;
else return this.friends.find((r)=>r.username === target.username) || this.other.find((r)=>r.username === target.username) || null;
}
/**
* Get the user id given a username
*/ async resolve(username) {
return await this.api.users.resolve(username);
}
async who(id) {
return this.api.users.get({
id
});
}
/**
* Send a message to a specified user (based on id)
* @example
* await client.social.dm(await client.social.resolve('halp'), 'what\'s up?');
*/ async dm(userID, message) {
return await this.client.wrap("social.dm", {
recipient: userID,
msg: message
}, "social.dm", [
"social.dm.fail",
"client.error"
]);
}
/**
* Send a user a friend request
* @example
* await client.social.friend(await client.social.resolve('halp'));
* @returns false if the user is already friended, true otherwise
* @throws {Error} If an error occurs (such as the user has blocked the client, etc)
*/ async friend(userID) {
if (this.friends.find((r)=>r.id === userID)) return false;
await this.api.social.friend(userID);
const userData = await this.who(userID);
this.friends.push(new _relationship.Relationship({
id: userData._id,
relationshipID: "",
username: userData.username,
avatar: userData.avatar_revision
}, this, this.client));
return true;
}
/**
* Unfriend a user. Note: unfriending a user will unblock them if they are blocked.
* @example
* await client.social.unfriend(await client.social.resolve('halp'));
* @returns false if the user is not unfriended, true otherwise
*/ async unfriend(userID) {
if (!this.friends.find((r)=>r.id === userID)) return false;
await this.api.social.unfriend(userID);
this.friends = this.friends.filter((r)=>r.id !== userID);
return true;
}
/**
* Block a user
* @example
* await client.social.block(await client.social.resolve('halp'));
* @returns false if the user is already blocked, true otherwise
*/ async block(userID) {
if (this.blocked.find((r)=>r.id === userID)) return false;
await this.api.social.block(userID);
}
/**
* Unblock a user. Note: unblocking a user will unfriend them if they are friended.
* @example
* await client.social.unblock(await client.social.resolve('halp'));
* @returns false if the user is not unblocked, true otherwise
*/ async unblock(userID) {
await this.api.social.unblock(userID);
}
/**
* Invite a user to your room
* @example
* await client.social.invite(await client.social.resolve('halp'));
*/ invite(userID) {
return new Promise(async (resolve, reject)=>{
let r = false;
this.client.emit("social.invite", userID);
const l = (e)=>{
if (r) return;
r = true;
reject(e);
};
this.client.once("client.error", l);
await new Promise((r)=>setTimeout(r, 100));
this.client.off("client.error", l);
r = true;
resolve();
});
}
/**
* Set the client's status
* @example
* client.social.status('online', 'lobby:X-QP');
*/ status(status, detail = "") {
this.client.emit("social.presence", {
status,
detail
});
}
}
//# sourceMappingURL=index.js.map