You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
7.3 KiB
Lua
282 lines
7.3 KiB
Lua
--[=[
|
|
@c GuildChannel x Channel
|
|
@t abc
|
|
@d Defines the base methods and properties for all Discord guild channels.
|
|
]=]
|
|
|
|
local json = require('json')
|
|
local enums = require('enums')
|
|
local class = require('class')
|
|
local Channel = require('containers/abstract/Channel')
|
|
local PermissionOverwrite = require('containers/PermissionOverwrite')
|
|
local Invite = require('containers/Invite')
|
|
local Cache = require('iterables/Cache')
|
|
local Resolver = require('client/Resolver')
|
|
|
|
local isInstance = class.isInstance
|
|
local classes = class.classes
|
|
local channelType = enums.channelType
|
|
|
|
local insert, sort = table.insert, table.sort
|
|
local min, max, floor = math.min, math.max, math.floor
|
|
local huge = math.huge
|
|
|
|
local GuildChannel, get = class('GuildChannel', Channel)
|
|
|
|
function GuildChannel:__init(data, parent)
|
|
Channel.__init(self, data, parent)
|
|
self.client._channel_map[self._id] = parent
|
|
self._permission_overwrites = Cache({}, PermissionOverwrite, self)
|
|
return self:_loadMore(data)
|
|
end
|
|
|
|
function GuildChannel:_load(data)
|
|
Channel._load(self, data)
|
|
return self:_loadMore(data)
|
|
end
|
|
|
|
function GuildChannel:_loadMore(data)
|
|
return self._permission_overwrites:_load(data.permission_overwrites, true)
|
|
end
|
|
|
|
--[=[
|
|
@m setName
|
|
@t http
|
|
@p name string
|
|
@r boolean
|
|
@d Sets the channel's name. This must be between 2 and 100 characters in length.
|
|
]=]
|
|
function GuildChannel:setName(name)
|
|
return self:_modify({name = name or json.null})
|
|
end
|
|
|
|
--[=[
|
|
@m setCategory
|
|
@t http
|
|
@p id Channel-ID-Resolvable
|
|
@r boolean
|
|
@d Sets the channel's parent category.
|
|
]=]
|
|
function GuildChannel:setCategory(id)
|
|
id = Resolver.channelId(id)
|
|
return self:_modify({parent_id = id or json.null})
|
|
end
|
|
|
|
local function sorter(a, b)
|
|
if a.position == b.position then
|
|
return tonumber(a.id) < tonumber(b.id)
|
|
else
|
|
return a.position < b.position
|
|
end
|
|
end
|
|
|
|
local function getSortedChannels(self)
|
|
|
|
local channels
|
|
local t = self._type
|
|
if t == channelType.text or t == channelType.news then
|
|
channels = self._parent._text_channels
|
|
elseif t == channelType.voice then
|
|
channels = self._parent._voice_channels
|
|
elseif t == channelType.category then
|
|
channels = self._parent._categories
|
|
end
|
|
|
|
local ret = {}
|
|
for channel in channels:iter() do
|
|
insert(ret, {id = channel._id, position = channel._position})
|
|
end
|
|
sort(ret, sorter)
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
local function setSortedChannels(self, channels)
|
|
local data, err = self.client._api:modifyGuildChannelPositions(self._parent._id, channels)
|
|
if data then
|
|
return true
|
|
else
|
|
return false, err
|
|
end
|
|
end
|
|
|
|
--[=[
|
|
@m moveUp
|
|
@t http
|
|
@p n number
|
|
@r boolean
|
|
@d Moves a channel up its list. The parameter `n` indicates how many spaces the
|
|
channel should be moved, clamped to the highest position, with a default of 1 if
|
|
it is omitted. This will also normalize the positions of all channels.
|
|
]=]
|
|
function GuildChannel:moveUp(n)
|
|
|
|
n = tonumber(n) or 1
|
|
if n < 0 then
|
|
return self:moveDown(-n)
|
|
end
|
|
|
|
local channels = getSortedChannels(self)
|
|
|
|
local new = huge
|
|
for i = #channels - 1, 0, -1 do
|
|
local v = channels[i + 1]
|
|
if v.id == self._id then
|
|
new = max(0, i - floor(n))
|
|
v.position = new
|
|
elseif i >= new then
|
|
v.position = i + 1
|
|
else
|
|
v.position = i
|
|
end
|
|
end
|
|
|
|
return setSortedChannels(self, channels)
|
|
|
|
end
|
|
|
|
--[=[
|
|
@m moveDown
|
|
@t http
|
|
@p n number
|
|
@r boolean
|
|
@d Moves a channel down its list. The parameter `n` indicates how many spaces the
|
|
channel should be moved, clamped to the lowest position, with a default of 1 if
|
|
it is omitted. This will also normalize the positions of all channels.
|
|
]=]
|
|
function GuildChannel:moveDown(n)
|
|
|
|
n = tonumber(n) or 1
|
|
if n < 0 then
|
|
return self:moveUp(-n)
|
|
end
|
|
|
|
local channels = getSortedChannels(self)
|
|
|
|
local new = -huge
|
|
for i = 0, #channels - 1 do
|
|
local v = channels[i + 1]
|
|
if v.id == self._id then
|
|
new = min(i + floor(n), #channels - 1)
|
|
v.position = new
|
|
elseif i <= new then
|
|
v.position = i - 1
|
|
else
|
|
v.position = i
|
|
end
|
|
end
|
|
|
|
return setSortedChannels(self, channels)
|
|
|
|
end
|
|
|
|
--[=[
|
|
@m createInvite
|
|
@t http
|
|
@op payload table
|
|
@r Invite
|
|
@d Creates an invite to the channel. Optional payload fields are: max_age: number
|
|
time in seconds until expiration, default = 86400 (24 hours), max_uses: number
|
|
total number of uses allowed, default = 0 (unlimited), temporary: boolean whether
|
|
the invite grants temporary membership, default = false, unique: boolean whether
|
|
a unique code should be guaranteed, default = false
|
|
]=]
|
|
function GuildChannel:createInvite(payload)
|
|
local data, err = self.client._api:createChannelInvite(self._id, payload)
|
|
if data then
|
|
return Invite(data, self.client)
|
|
else
|
|
return nil, err
|
|
end
|
|
end
|
|
|
|
--[=[
|
|
@m getInvites
|
|
@t http
|
|
@r Cache
|
|
@d Returns a newly constructed cache of all invite objects for the channel. The
|
|
cache and its objects are not automatically updated via gateway events. You must
|
|
call this method again to get the updated objects.
|
|
]=]
|
|
function GuildChannel:getInvites()
|
|
local data, err = self.client._api:getChannelInvites(self._id)
|
|
if data then
|
|
return Cache(data, Invite, self.client)
|
|
else
|
|
return nil, err
|
|
end
|
|
end
|
|
|
|
--[=[
|
|
@m getPermissionOverwriteFor
|
|
@t mem
|
|
@p obj Role/Member
|
|
@r PermissionOverwrite
|
|
@d Returns a permission overwrite object corresponding to the provided member or
|
|
role object. If a cached overwrite is not found, an empty overwrite with
|
|
zero-permissions is returned instead. Therefore, this can be used to create a
|
|
new overwrite when one does not exist. Note that the member or role must exist
|
|
in the same guild as the channel does.
|
|
]=]
|
|
function GuildChannel:getPermissionOverwriteFor(obj)
|
|
local id, type
|
|
if isInstance(obj, classes.Role) and self._parent == obj._parent then
|
|
id, type = obj._id, 'role'
|
|
elseif isInstance(obj, classes.Member) and self._parent == obj._parent then
|
|
id, type = obj._user._id, 'member'
|
|
else
|
|
return nil, 'Invalid Role or Member: ' .. tostring(obj)
|
|
end
|
|
local overwrites = self._permission_overwrites
|
|
return overwrites:get(id) or overwrites:_insert(setmetatable({
|
|
id = id, type = type, allow = 0, deny = 0
|
|
}, {__jsontype = 'object'}))
|
|
end
|
|
|
|
--[=[
|
|
@m delete
|
|
@t http
|
|
@r boolean
|
|
@d Permanently deletes the channel. This cannot be undone!
|
|
]=]
|
|
function GuildChannel:delete()
|
|
return self:_delete()
|
|
end
|
|
|
|
--[=[@p permissionOverwrites Cache An iterable cache of all overwrites that exist in this channel. To access an
|
|
overwrite that may exist, but is not cached, use `GuildChannel:getPermissionOverwriteFor`.]=]
|
|
function get.permissionOverwrites(self)
|
|
return self._permission_overwrites
|
|
end
|
|
|
|
--[=[@p name string The name of the channel. This should be between 2 and 100 characters in length.]=]
|
|
function get.name(self)
|
|
return self._name
|
|
end
|
|
|
|
--[=[@p position number The position of the channel, where 0 is the highest.]=]
|
|
function get.position(self)
|
|
return self._position
|
|
end
|
|
|
|
--[=[@p guild Guild The guild in which this channel exists.]=]
|
|
function get.guild(self)
|
|
return self._parent
|
|
end
|
|
|
|
--[=[@p category GuildCategoryChannel/nil The parent channel category that may contain this channel.]=]
|
|
function get.category(self)
|
|
return self._parent._categories:get(self._parent_id)
|
|
end
|
|
|
|
--[=[@p private boolean Whether the "everyone" role has permission to view this
|
|
channel. In the Discord channel, private text channels are indicated with a lock
|
|
icon and private voice channels are not visible.]=]
|
|
function get.private(self)
|
|
local overwrite = self._permission_overwrites:get(self._parent._id)
|
|
return overwrite and overwrite:getDeniedPermissions():has('readMessages')
|
|
end
|
|
|
|
return GuildChannel
|