Skip to content

Commit

Permalink
Merge pull request #52 from mineral-dart/implement-news-channel
Browse files Browse the repository at this point in the history
feat: Implement news channel
  • Loading branch information
LeadcodeDev authored Jul 31, 2022
2 parents 5a329a8 + 584b06f commit 8a496cb
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 138 deletions.
1 change: 1 addition & 0 deletions lib/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export 'src/api/channels/voice_channel.dart' show VoiceChannel;
export 'src/api/channels/text_based_channel.dart' show TextBasedChannel;
export 'src/api/channels/text_channel.dart' show TextChannel;
export 'src/api/channels/category_channel.dart' show CategoryChannel;
export 'src/api/channels/news_channel.dart' show NewsChannel;
export 'src/api/channels/permission_overwrite.dart' show PermissionOverwrite, PermissionOverwriteType;

export 'src/api/messages/message.dart' show Message;
Expand Down
3 changes: 2 additions & 1 deletion lib/src/api/channels/channel.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:http/http.dart';
import 'package:mineral/api.dart';
import 'package:mineral/core.dart';
import 'package:mineral/src/api/channels/news_channel.dart';
import 'package:mineral/src/api/channels/partial_channel.dart';
import 'package:mineral/src/api/managers/webhook_manager.dart';
import 'package:mineral/src/api/managers/permission_overwrite_manager.dart';
Expand Down Expand Up @@ -29,7 +30,7 @@ Map<ChannelType, Channel Function(Guild? guild, dynamic payload)> channels = {
ChannelType.guildVoice: (Guild? guild, dynamic payload) => VoiceChannel.from(guild, payload),
// 'GROUP_DM': () => ,
ChannelType.guildCategory: (Guild? guild, dynamic payload) => CategoryChannel.from(guild, payload),
// 'GUILD_NEWS': () => ,
ChannelType.guildNews: (Guild? guild, dynamic payload) => NewsChannel.from(guild, payload),
// 'GUILD_NEWS_THREAD': () => ,
// 'GUILD_PUBLIC_THREAD': () => ,
// 'GUILD_PRIVATE_THREAD': () => ,
Expand Down
70 changes: 70 additions & 0 deletions lib/src/api/channels/news_channel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:mineral/api.dart';
import 'package:mineral/console.dart';
import 'package:mineral/core.dart';
import 'package:mineral/src/api/managers/message_manager.dart';
import 'package:mineral/src/api/managers/permission_overwrite_manager.dart';
import 'package:mineral/src/api/managers/thread_manager.dart';
import 'package:mineral/src/api/managers/webhook_manager.dart';

class NewsChannel extends TextBasedChannel {
NewsChannel(
super._id,
super._type,
super._position,
super._label,
super._applicationId,
super._flags,
super._webhooks,
super.permissionOverwrites,
super._guild,
super.description,
super.nsfw,
super.lastMessageId,
super.lastPinTimestamp,
super._messages,
super._threads,
);

Future<void> follow (Snowflake webhookId) async {
if (type != ChannelType.guildNews) {
Console.warn(message: 'Impossible to follow the channel $id as it is not an announcement channel');
return;
}

Http http = ioc.singleton(ioc.services.http);
await http.post(url: '/channels/$id/followers', payload: {
'webhook_channel_id': webhookId
});
}

factory NewsChannel.from(Guild? guild, dynamic payload) {
final permissionOverwriteManager = PermissionOverwriteManager();
for(dynamic element in payload['permission_overwrites']) {
final PermissionOverwrite overwrite = PermissionOverwrite.from(payload: element);
permissionOverwriteManager.cache.putIfAbsent(overwrite.id, () => overwrite);
}

NewsChannel channel = NewsChannel(
payload['id'],
ChannelType.guildNews,
payload['position'],
payload['name'],
payload['application_id'],
payload['flags'],
WebhookManager(),
permissionOverwriteManager,
guild,
payload['topic'],
payload['nsfw'] ?? false,
payload['last_message_id'],
payload['last_pin_timestamp'] != null ? DateTime.parse(payload['last_pin_timestamp']) : null,
MessageManager(),
ThreadManager(guildId: guild?.id),
);

channel.webhooks?.channel = channel;
channel.threads.channel = channel;

return channel;
}
}
8 changes: 0 additions & 8 deletions lib/src/api/client/mineral_client.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:mineral/api.dart';
import 'package:mineral/console.dart';
import 'package:mineral/core.dart';
import 'package:mineral/src/api/managers/dm_channel_manager.dart';
import 'package:mineral/src/api/managers/guild_manager.dart';
Expand Down Expand Up @@ -139,13 +138,6 @@ class MineralClient {

Future<void> registerGuildCommands ({ required Guild guild, required List<SlashCommand> commands, required List<MineralContextMenu> contextMenus }) async {
Http http = ioc.singleton(ioc.services.http);

Console.info(message: 'commands');
print([
...commands.map((command) => command.toJson()).toList(),
...contextMenus.map((contextMenus) => contextMenus.toJson()).toList()
]);

await http.put(
url: "/applications/${_application.id}/guilds/${guild.id}/commands",
payload: [
Expand Down
2 changes: 1 addition & 1 deletion lib/src/api/managers/thread_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ThreadManager extends CacheManager<Channel> {
'auto_archive_duration': '60',
'type': 11
});
print(response.body);

if (response.statusCode == 200) {
PublicThread thread = PublicThread.from(payload: jsonDecode(response.body));
return thread;
Expand Down
74 changes: 31 additions & 43 deletions lib/src/api/messages/dm_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,22 @@ import 'package:mineral/src/api/messages/partial_message.dart';
class DmMessage extends PartialMessage<DmChannel> {
User author;

DmMessage({
required id,
required content,
required tts,
required embeds,
required allowMentions,
required reference,
required components,
required stickers,
required payload,
required attachments,
required flags,
required channelId,
required channel,
required this.author,
}): super(
id: id,
content: content,
tts: tts,
embeds: embeds,
allowMentions: allowMentions,
reference: reference,
components: components,
stickers: stickers,
payload: payload,
attachments: attachments,
flags: flags,
channelId: channelId,
channel: channel,
DmMessage(
super.id,
super.content,
super.tts,
super.embeds,
super.allowMentions,
super.reference,
super.components,
super.stickers,
super.payload,
super.attachments,
super.flags,
super.pinned,
super.channelId,
super.channel,
this.author,
);

factory DmMessage.from({ required DmChannel channel, required dynamic payload }) {
Expand Down Expand Up @@ -105,20 +92,21 @@ class DmMessage extends PartialMessage<DmChannel> {
}

return DmMessage(
id: payload['id'],
content: payload['content'],
tts: payload['tts'] ?? false,
allowMentions: payload['allow_mentions'] ?? false,
reference: payload['reference'],
flags: payload['flags'],
channelId: channel.id,
channel: channel,
author: user!,
embeds: embeds,
components: components,
payload: payload['payload'],
stickers: stickers,
attachments: messageAttachments,
payload['id'],
payload['content'],
payload['tts'] ?? false,
embeds,
payload['allow_mentions'] ?? false,
payload['reference'],
components,
stickers,
payload['payload'],
messageAttachments,
payload['flags'],
payload['pinned'],
channel.id,
channel,
user!,
);
}
}
129 changes: 74 additions & 55 deletions lib/src/api/messages/message.dart
Original file line number Diff line number Diff line change
@@ -1,60 +1,49 @@
import 'package:http/http.dart';
import 'package:mineral/api.dart';
import 'package:mineral/console.dart';
import 'package:mineral/core.dart';
import 'package:mineral/src/api/components/component.dart';
import 'package:mineral/src/api/messages/message_attachment.dart';
import 'package:mineral/src/api/messages/message_sticker_item.dart';
import 'package:mineral/src/api/messages/partial_message.dart';

class Message extends PartialMessage<TextBasedChannel> {
GuildMember author;

Message({
required id,
required content,
required tts,
required embeds,
required allowMentions,
required reference,
required components,
required stickers,
required payload,
required attachments,
required flags,
required channelId,
required channel,
required this.author,
}): super(
id: id,
content: content,
tts: tts,
embeds: embeds,
allowMentions: allowMentions,
reference: reference,
components: components,
stickers: stickers,
payload: payload,
attachments: attachments,
flags: flags,
channelId: channelId,
channel: channel,
GuildMember? _author;

Message(
super._id,
super._content,
super._tts,
super._embeds,
super._allowMentions,
super._reference,
super._components,
super._stickers,
super._payload,
super._attachments,
super._flags,
super._pinned,
super._channelId,
super._channel,
this._author,
);

GuildMember? get author => _author;

Future<Message> edit ({ String? content, List<MessageEmbed>? embeds, List<Row>? components, bool? tts }) async {
Http http = ioc.singleton(ioc.services.http);

Response response = await http.patch(
url: '/channels/$channelId/messages/$id',
payload: {
'content': content,
'embeds': embeds,
'flags': flags,
'allowed_mentions': allowMentions,
'components': components,
}
url: '/channels/$channelId/messages/$id',
payload: {
'content': content,
'embeds': embeds,
'flags': flags,
'allowed_mentions': allowMentions,
'components': components,
}
);

print(response.body);
if (response.statusCode == 200) {
this.content = content ?? this.content;
this.embeds = embeds ?? this.embeds;
Expand All @@ -64,8 +53,37 @@ class Message extends PartialMessage<TextBasedChannel> {
return this;
}

Future<void> crossPost () async {
if (channel.type != ChannelType.guildNews) {
Console.warn(message: 'Message $id cannot be cross-posted as it is not in an announcement channel');
return;
}

Http http = ioc.singleton(ioc.services.http);
await http.post(url: '/channels/${super.channel.id}/messages/${super.id}/crosspost', payload: {});
}

Future<void> pin (Snowflake webhookId) async {
if (isPinned) {
Console.warn(message: 'Message $id is already pinned');
return;
}

Http http = ioc.singleton(ioc.services.http);
await http.put(url: '/channels/${channel.id}/pins/$id', payload: {});
}

Future<void> unpin () async {
if (!isPinned) {
Console.warn(message: 'Message $id isn\'t pinned');
return;
}

Http http = ioc.singleton(ioc.services.http);
await http.destroy(url: '/channels/${channel.id}/pins/$id');
}

factory Message.from({ required TextBasedChannel channel, required dynamic payload }) {
print(channel.guild);
GuildMember? guildMember = channel.guild?.members.cache.get(payload['author']['id']);
List<MessageEmbed> embeds = [];

Expand Down Expand Up @@ -129,20 +147,21 @@ class Message extends PartialMessage<TextBasedChannel> {
}

return Message(
id: payload['id'],
content: payload['content'],
tts: payload['tts'] ?? false,
allowMentions: payload['allow_mentions'] ?? false,
reference: payload['reference'],
flags: payload['flags'],
channelId: channel.id,
channel: channel,
author: guildMember!,
embeds: embeds,
components: components,
payload: payload['payload'],
stickers: stickers,
attachments: messageAttachments,
payload['id'],
payload['content'],
payload['tts'] ?? false,
embeds,
payload['allow_mentions'] ?? false,
payload['reference'],
components,
stickers,
payload['payload'],
messageAttachments,
payload['flags'],
payload['pinned'],
channel.id,
channel,
guildMember,
);
}
}
Loading

0 comments on commit 8a496cb

Please sign in to comment.