lib/chatrix/user.rb
# encoding: utf-8
# frozen_string_literal: true
require 'chatrix/events'
require 'wisper'
module Chatrix
# Describes a user.
class User
include Wisper::Publisher
# @return [String] The user ID of this user.
attr_reader :id
# @return [String,nil] The display name of this user, if one has
# been set.
attr_reader :displayname
# @return [String,nil] This user's avatar URL, if one has been set.
attr_reader :avatar
# Initializes a new User instance.
# @param id [String] The user ID.
def initialize(id)
@id = id
# room_id => membership
@memberships = {}
end
# Get this user's power level in a room.
#
# @param room [Room] The room to check.
# @return [Fixnum] The user's power level in the specified room.
def power_in(room)
return 0 unless @memberships.key? room
@memberships[room][:power] || 0
end
# Checks if this user is a member of the specified room.
# @param room [Room] The room to check.
# @return [Boolean] `true` if the user is a member in the room,
# otherwise `false`.
def member?(room)
@memberships.key?(room) && @memberships[room][:type] == :join
end
# Process a member event.
#
# @param room [Room] The room that sent the event.
# @param event [Hash] Event data.
def process_member_event(room, event)
membership = (@memberships[room] ||= {})
type = event['content']['membership'].to_sym
# Only update the membership status if we are currently not in the room
# or if the new state is that we have left.
if membership[:type] != :join || type == :leave
membership[:type] = type
broadcast(:membership, self, room, membership)
end
update(event['content'])
Events.processed event
end
# Process a power level update in a room.
#
# @param room [Room] The room where the level updated.
# @param level [Fixnum] The new power level.
def process_power_level(room, level)
membership = (@memberships[room] ||= {})
membership[:power] = level
broadcast(:power_level, self, room, level)
end
# Process an invite to a room.
# @param room [Room] The room the user was invited to.
# @param sender [User] The user who sent the invite.
# @param event [Hash] Event data.
def process_invite(room, sender, event)
# Return early if we're already part of this room
membership = (@memberships[room] ||= {})
return if membership[:type] == :join
process_member_event room, event
broadcast(:invited, self, room, sender)
end
# Converts this User object to a string representation of it.
# @return [String] Returns the user's display name if one is set,
# otherwise returns the ID.
def to_s
@id
end
private
# Updates metadata for this user.
# @param data [Hash{String=>String}] User metadata.
def update(data)
update_avatar(data['avatar_url']) if data.key? 'avatar_url'
update_displayname(data['displayname']) if data.key? 'displayname'
end
# Sets a new avatar URL for this user.
# @param url [String] The new URL to set.
def update_avatar(url)
@avatar = url
broadcast(:avatar, self, @avatar)
end
# Sets a new display name for this user.
# @param name [String] The new name to set.
def update_displayname(name)
@displayname = name
broadcast(:displayname, self, @displayname)
end
end
end