# frozen_string_literal: true module Discorb # # Represents a user of discord. # class User < DiscordModel # @return [Boolean] Whether the user is verified. attr_reader :verified # @return [String] The user's username. attr_reader :username alias name username # @return [Discorb::Snowflake] The user's ID. attr_reader :id # @return [Discorb::User::Flag] The user's flags. attr_reader :flag # @return [String] The user's discriminator. attr_reader :discriminator # @return [Discorb::Asset, Discorb::DefaultAvatar] The user's avatar. attr_reader :avatar # @return [Boolean] Whether the user is a bot. attr_reader :bot alias bot? bot # @return [Time] The time the user was created. attr_reader :created_at include Discorb::Messageable # @!attribute [r] mention # @return [String] The user's mention. # # Initializes a new user. # @private # # @param [Discorb::Client] client The client. # @param [Hash] data The user data. # def initialize(client, data) @client = client @data = {} @dm_channel_id = nil _set_data(data) end # # Format the user as `Username#Discriminator` style. # # @return [String] The formatted username. # def to_s "#{@username}##{@discriminator}" end def mention "<@#{@id}>" end alias to_s_user to_s def inspect "#<#{self.class} #{self}>" end # # Whether the user is a owner of the client. # @async # # @param [Boolean] strict Whether don't allow if the user is a member of the team. # # @return [Async::Task] Whether the user is a owner of the client. # def bot_owner?(strict: false) Async do app = @client.fetch_application.wait if app.team.nil? app.owner == self elsif strict app.team.owner == self else app.team.members.any? { |m| m.user == self } end end end alias app_owner? bot_owner? # # Returns the dm channel id of the user. # @private # # @return [Async::Task] A task that resolves to the channel id. # def channel_id Async do next @dm_channel_id if @dm_channel_id _resp, dm_channel = @client .http .request( Route.new("/users/@me/channels", "//users/@me/channels", :post), { recipient_id: @id } ) .wait @dm_channel_id = dm_channel[:id] @dm_channel_id end end # # Represents the user's flags. # ## Flag fields # |`1 << 0`|`:staff`| # |`1 << 1`|`:partner`| # |`1 << 2`|`:hypesquad`| # |`1 << 3`|`:bug_hunter_level_1`| # |`1 << 6`|`:hypesquad_online_house_1`| # |`1 << 7`|`:hypesquad_online_house_2`| # |`1 << 8`|`:hypesquad_online_house_3`| # |`1 << 9`|`:premium_early_supporter`| # |`1 << 10`|`:team_psuedo_user`| # |`1 << 14`|`:bug_hunter_level_2`| # |`1 << 16`|`:verified_bot`| # |`1 << 17`|`:verified_developer`| # |`1 << 18`|`:certified_moderator`| # |`1 << 19`|`:bot_http_interactions`| # class Flag < Discorb::Flag @bits = { staff: 0, partner: 1, hypesquad: 2, bug_hunter_level_1: 3, hypesquad_online_house_1: 6, hypesquad_online_house_2: 7, hypesquad_online_house_3: 8, premium_early_supporter: 9, team_psuedo_user: 10, bug_hunter_level_2: 14, verified_bot: 16, verified_developer: 17, certified_moderator: 18, bot_http_interactions: 19 }.freeze end private def _set_data(data) @username = data[:username] @verified = data[:verified] @id = Snowflake.new(data[:id]) @flag = User::Flag.new(data[:public_flags] | (data[:flags] || 0)) @discriminator = data[:discriminator] @avatar = ( if data[:avatar] Asset.new(self, data[:avatar]) else DefaultAvatar.new(data[:discriminator]) end ) @bot = data[:bot] || false @raw_data = data @client.users[@id] = self unless data[:no_cache] @created_at = @id.timestamp @data.update(data) end end # # Represents a client user. # class ClientUser < User # # Edit the client user. # @async # @macro edit # # @param [String] name The new username. # @param [Discorb::Image] avatar The new avatar. # # @return [Async::Task] The task. # def edit(name: Discorb::Unset, avatar: Discorb::Unset) Async do payload = {} payload[:username] = name unless name == Discorb::Unset if avatar == Discorb::Unset # Nothing elsif avatar.nil? payload[:avatar] = nil else payload[:avatar] = avatar.to_s end @client .http .request(Route.new("/users/@me", "//users/@me", :patch), payload) .wait self end end end end