UNPKG

@haelp/teto

Version:

A typescript-based controllable TETR.IO client.

1 lines 18.1 kB
{"version":3,"sources":["../../../src/classes/social/index.ts"],"sourcesContent":["import { Events, type Social as SocialTypes } from \"../../types\";\nimport { APITypes } from \"../../utils\";\nimport type { Client } from \"../client\";\nimport { Relationship } from \"./relationship\";\n\ninterface SocialInitData {\n online: number;\n notifications: SocialTypes.Notification[];\n friends: ReturnType<typeof processRelationship>[];\n other: ReturnType<typeof processRelationship>[];\n blocked: SocialTypes.Blocked[];\n}\n\nconst processRelationship = (r: SocialTypes.Relationship, selfID: string) => ({\n ...r,\n user: {\n id: r.from._id === selfID ? r.to._id : r.from._id,\n username: r.from._id === selfID ? r.to.username : r.from.username,\n avatar:\n r.from._id === selfID ? r.to.avatar_revision : r.from.avatar_revision\n }\n});\n\nexport class Social {\n private client: Client;\n\n /** The current number of people online */\n public online: number;\n /** List of the client's friends */\n public friends: Relationship[];\n /** List of \"pending\" relationships (shows in `other` tab on TETR.IO) */\n public other: Relationship[];\n /** people you block */\n public blocked: SocialTypes.Blocked[];\n /** Notifications */\n public notifications: SocialTypes.Notification[];\n\n /** @hideconstructor */\n private constructor(client: Client, init: SocialInitData) {\n this.client = client;\n\n this.init();\n this.online = init.online;\n this.friends = init.friends.map(\n (r) =>\n new Relationship(\n {\n id: r.user.id,\n relationshipID: r._id,\n username: r.user.username,\n avatar: r.user.avatar\n },\n this,\n this.client\n )\n );\n this.other = init.other.map(\n (r) =>\n new Relationship(\n {\n id: r.user.id,\n relationshipID: r._id,\n username: r.user.username,\n avatar: r.user.avatar\n },\n this,\n\n this.client\n )\n );\n this.blocked = init.blocked;\n this.notifications = init.notifications;\n }\n\n static async create(\n client: Client,\n initData: Events.in.Client[\"client.ready\"][\"social\"]\n ) {\n const rel = initData.relationships.map((r) =>\n processRelationship(r, client.user.id)\n );\n const data: SocialInitData = {\n online: initData.total_online,\n notifications: initData.notifications,\n friends: rel.filter((r) => r.type === \"friend\"),\n other: rel.filter((r) => r.type === \"pending\"),\n\n blocked: rel\n .filter((r) => r.type === \"block\")\n .map((r) => ({\n id: r.user.id,\n username: r.user.username,\n avatar: r.user.avatar\n }))\n };\n\n return new Social(client, data);\n }\n\n private get api() {\n return this.client.api;\n }\n\n private init() {\n setTimeout(\n () =>\n this.notifications.forEach((n) => {\n if (n.type === \"friend\") {\n if (!n.seen) {\n const rel = processRelationship(\n n.data.relationship,\n this.client.user.id\n );\n this.client.emit(\"client.friended\", {\n id: rel.user.id,\n name: rel.user.username,\n avatar: rel.user.avatar\n });\n }\n }\n }),\n 0\n );\n\n this.client.on(\"social.online\", (count) => {\n this.online = count;\n });\n\n this.client.on(\"social.notification\", async (n) => {\n this.notifications.splice(0, 0, n);\n\n if (n.type === \"friend\") {\n const rel = processRelationship(\n n.data.relationship,\n this.client.user.id\n );\n this.client.emit(\"client.friended\", {\n id: rel.user.id,\n name: rel.user.username,\n avatar: rel.user.avatar\n });\n\n const user = this.get({ id: rel.user.id });\n\n if (!user) {\n this.other.push(\n new Relationship(\n {\n id: rel.user.id,\n username: rel.user.username,\n avatar: rel.user.avatar,\n relationshipID: \"\"\n },\n this,\n this.client\n )\n );\n }\n }\n });\n\n this.client.on(\"social.dm\", async (dm) => {\n let user = this.get({ id: dm.data.user });\n if (user) {\n if (!user.dmsLoaded) await user.loadDms();\n else user.dms.push(dm);\n } else {\n const u = await this.who(dm.data.user);\n this.other.push(\n new Relationship(\n {\n id: u._id,\n username: u.username,\n avatar: u.avatar_revision,\n relationshipID: \"\"\n },\n this,\n this.client\n )\n );\n\n user = this.get({ id: dm.data.user })!;\n await user.loadDms();\n }\n\n this.client.emit(\"client.dm\", {\n user,\n content: dm.data.content,\n reply: async (content: string) => {\n await this.dm(dm.data.user, content);\n }\n });\n });\n }\n\n /**\n * Marks all notifications as read\n * @example\n * client.social.markNotificationsAsRead();\n */\n markNotificationsAsRead() {\n this.client.emit(\"social.notification.ack\");\n }\n\n /**\n * Get a user + social data from the list of users and pending friends (OTHER tab in TETR.IO)\n * @example\n * const user = await client.social.get('halp')\n * @example\n * const user = await client.social.get('646f633d276f42a80ba44304');\n * @example\n * const user = await client.social.get({ username: 'halp' });\n * @example\n * const user = await client.social.get({ id: '646f633d276f42a80ba44304 });\n * @example\n * // You can then use the object to read user data and interact with the user\n * await user.dm('wanna play?');\n * await user.invite();\n */\n get(target: string): Relationship | null;\n get(target: { id: string }): Relationship | null;\n get(target: { username: string }): Relationship | null;\n get(\n target: string | { id: string } | { username: string }\n ): Relationship | null {\n if (typeof target === \"string\")\n return (\n this.friends.find((r) => r.id === target || r.username === target) ||\n this.other.find((r) => r.id === target || r.username === target) ||\n null\n );\n else if (\"id\" in target)\n return (\n this.friends.find((r) => r.id === target.id) ||\n this.other.find((r) => r.id === target.id) ||\n null\n );\n else\n return (\n this.friends.find((r) => r.username === target.username) ||\n this.other.find((r) => r.username === target.username) ||\n null\n );\n }\n\n /**\n * Get the user id given a username\n */\n async resolve(username: string) {\n return await this.api.users.resolve(username);\n }\n\n /** Get a users' information based on their userid or username\n * @example\n * const user = await client.social.who(await client.social.resolve('halp'));\n */\n who(id: string): Promise<APITypes.Users.User>;\n async who(id: string): Promise<APITypes.Users.User> {\n return this.api.users.get({ id });\n }\n\n /**\n * Send a message to a specified user (based on id)\n * @example\n * await client.social.dm(await client.social.resolve('halp'), 'what\\'s up?');\n */\n async dm(userID: string, message: string) {\n return await this.client.wrap(\n \"social.dm\",\n {\n recipient: userID,\n msg: message\n },\n \"social.dm\",\n [\"social.dm.fail\", \"client.error\"]\n );\n }\n\n /**\n * Send a user a friend request\n * @example\n * await client.social.friend(await client.social.resolve('halp'));\n * @returns false if the user is already friended, true otherwise\n * @throws {Error} If an error occurs (such as the user has blocked the client, etc)\n */\n async friend(userID: string) {\n if (this.friends.find((r) => r.id === userID)) return false;\n await this.api.social.friend(userID);\n const userData = await this.who(userID);\n this.friends.push(\n new Relationship(\n {\n id: userData._id,\n relationshipID: \"\",\n username: userData.username,\n avatar: userData.avatar_revision\n },\n this,\n this.client\n )\n );\n\n return true;\n }\n\n /**\n * Unfriend a user. Note: unfriending a user will unblock them if they are blocked.\n * @example\n * await client.social.unfriend(await client.social.resolve('halp'));\n * @returns false if the user is not unfriended, true otherwise\n */\n async unfriend(userID: string) {\n if (!this.friends.find((r) => r.id === userID)) return false;\n await this.api.social.unfriend(userID);\n this.friends = this.friends.filter((r) => r.id !== userID);\n\n return true;\n }\n\n /**\n * Block a user\n * @example\n * await client.social.block(await client.social.resolve('halp'));\n * @returns false if the user is already blocked, true otherwise\n */\n async block(userID: string) {\n if (this.blocked.find((r) => r.id === userID)) return false;\n await this.api.social.block(userID);\n }\n\n /**\n * Unblock a user. Note: unblocking a user will unfriend them if they are friended.\n * @example\n * await client.social.unblock(await client.social.resolve('halp'));\n * @returns false if the user is not unblocked, true otherwise\n */\n async unblock(userID: string) {\n await this.api.social.unblock(userID);\n }\n\n /**\n * Invite a user to your room\n * @example\n * await client.social.invite(await client.social.resolve('halp'));\n */\n invite(userID: string) {\n return new Promise<void>(async (resolve, reject) => {\n let r = false;\n this.client.emit(\"social.invite\", userID);\n const l = (e: string) => {\n if (r) return;\n r = true;\n reject(e);\n };\n this.client.once(\"client.error\", l);\n await new Promise((r) => setTimeout(r, 100));\n this.client.off(\"client.error\", l);\n r = true;\n resolve();\n });\n }\n\n /**\n * Set the client's status\n * @example\n * client.social.status('online', 'lobby:X-QP');\n */\n status(status: SocialTypes.Status, detail: SocialTypes.Detail | String = \"\") {\n this.client.emit(\"social.presence\", { status, detail });\n }\n}\n\nexport * from \"./relationship\";\n"],"names":["Relationship","processRelationship","r","selfID","user","id","from","_id","to","username","avatar","avatar_revision","Social","client","online","friends","other","blocked","notifications","init","map","relationshipID","create","initData","rel","relationships","data","total_online","filter","type","api","setTimeout","forEach","n","seen","relationship","emit","name","on","count","splice","get","push","dm","dmsLoaded","loadDms","dms","u","who","content","reply","markNotificationsAsRead","target","find","resolve","users","userID","message","wrap","recipient","msg","friend","social","userData","unfriend","block","unblock","invite","Promise","reject","l","e","once","off","status","detail"],"mappings":"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"}