|
|
@ -1,10 +1,12 @@
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "weechat-plugin.h"
|
|
|
|
#include "weechat-plugin.h"
|
|
|
|
#include "slack.h"
|
|
|
|
#include "slack.h"
|
|
|
|
#include "slack-workspace.h"
|
|
|
|
#include "slack-workspace.h"
|
|
|
|
|
|
|
|
#include "slack-user.h"
|
|
|
|
#include "slack-channel.h"
|
|
|
|
#include "slack-channel.h"
|
|
|
|
#include "slack-input.h"
|
|
|
|
#include "slack-input.h"
|
|
|
|
#include "slack-buffer.h"
|
|
|
|
#include "slack-buffer.h"
|
|
|
@ -73,7 +75,7 @@ struct t_gui_buffer *slack_channel_create_buffer(struct t_slack_workspace *works
|
|
|
|
const char *name)
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct t_gui_buffer *ptr_buffer;
|
|
|
|
struct t_gui_buffer *ptr_buffer;
|
|
|
|
int buffer_created, current_buffer_number;
|
|
|
|
int buffer_created;
|
|
|
|
const char *short_name, *localvar_channel;
|
|
|
|
const char *short_name, *localvar_channel;
|
|
|
|
char buffer_name[256];
|
|
|
|
char buffer_name[256];
|
|
|
|
|
|
|
|
|
|
|
@ -89,9 +91,6 @@ struct t_gui_buffer *slack_channel_create_buffer(struct t_slack_workspace *works
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
current_buffer_number = weechat_buffer_get_integer(
|
|
|
|
|
|
|
|
weechat_current_buffer(), "number");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ptr_buffer = weechat_buffer_new(buffer_name,
|
|
|
|
ptr_buffer = weechat_buffer_new(buffer_name,
|
|
|
|
&slack_input_data_cb, NULL, NULL,
|
|
|
|
&slack_input_data_cb, NULL, NULL,
|
|
|
|
&slack_buffer_close_cb, NULL, NULL);
|
|
|
|
&slack_buffer_close_cb, NULL, NULL);
|
|
|
@ -181,6 +180,7 @@ struct t_slack_channel *slack_channel_new(struct t_slack_workspace *workspace,
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct t_slack_channel *new_channel, *ptr_channel;
|
|
|
|
struct t_slack_channel *new_channel, *ptr_channel;
|
|
|
|
struct t_gui_buffer *ptr_buffer;
|
|
|
|
struct t_gui_buffer *ptr_buffer;
|
|
|
|
|
|
|
|
struct t_hook *typing_timer;
|
|
|
|
char buffer_name[SLACK_CHANNEL_NAME_MAX_LEN + 2];
|
|
|
|
char buffer_name[SLACK_CHANNEL_NAME_MAX_LEN + 2];
|
|
|
|
|
|
|
|
|
|
|
|
if (!workspace || !id || !name || !name[0])
|
|
|
|
if (!workspace || !id || !name || !name[0])
|
|
|
@ -202,6 +202,10 @@ struct t_slack_channel *slack_channel_new(struct t_slack_workspace *workspace,
|
|
|
|
if ((new_channel = malloc(sizeof(*new_channel))) == NULL)
|
|
|
|
if ((new_channel = malloc(sizeof(*new_channel))) == NULL)
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typing_timer = weechat_hook_timer(1 * 1000, 0, 0,
|
|
|
|
|
|
|
|
&slack_channel_typing_cb,
|
|
|
|
|
|
|
|
new_channel, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
new_channel->type = type;
|
|
|
|
new_channel->type = type;
|
|
|
|
new_channel->id = strdup(id);
|
|
|
|
new_channel->id = strdup(id);
|
|
|
|
new_channel->name = strdup(name);
|
|
|
|
new_channel->name = strdup(name);
|
|
|
@ -228,6 +232,9 @@ struct t_slack_channel *slack_channel_new(struct t_slack_workspace *workspace,
|
|
|
|
|
|
|
|
|
|
|
|
new_channel->is_user_deleted = 0;
|
|
|
|
new_channel->is_user_deleted = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new_channel->typing_hook_timer = typing_timer;
|
|
|
|
|
|
|
|
new_channel->typings = NULL;
|
|
|
|
|
|
|
|
new_channel->last_typing = NULL;
|
|
|
|
new_channel->members = NULL;
|
|
|
|
new_channel->members = NULL;
|
|
|
|
new_channel->last_member = NULL;
|
|
|
|
new_channel->last_member = NULL;
|
|
|
|
new_channel->buffer = ptr_buffer;
|
|
|
|
new_channel->buffer = ptr_buffer;
|
|
|
@ -244,6 +251,137 @@ struct t_slack_channel *slack_channel_new(struct t_slack_workspace *workspace,
|
|
|
|
return new_channel;
|
|
|
|
return new_channel;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void slack_channel_typing_free(struct t_slack_channel *channel,
|
|
|
|
|
|
|
|
struct t_slack_channel_typing *typing)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct t_slack_channel_typing *new_typings;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!channel || !typing)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* remove typing from typings list */
|
|
|
|
|
|
|
|
if (channel->last_typing == typing)
|
|
|
|
|
|
|
|
channel->last_typing = typing->prev_typing;
|
|
|
|
|
|
|
|
if (typing->prev_typing)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
(typing->prev_typing)->next_typing = typing->next_typing;
|
|
|
|
|
|
|
|
new_typings = channel->typings;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
new_typings = typing->next_typing;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (typing->next_typing)
|
|
|
|
|
|
|
|
(typing->next_typing)->prev_typing = typing->prev_typing;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* free typing data */
|
|
|
|
|
|
|
|
if (typing->id)
|
|
|
|
|
|
|
|
free(typing->id);
|
|
|
|
|
|
|
|
if (typing->name)
|
|
|
|
|
|
|
|
free(typing->name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
free(typing);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
channel->typings = new_typings;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void slack_channel_typing_free_all(struct t_slack_channel *channel)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
while (channel->typings)
|
|
|
|
|
|
|
|
slack_channel_typing_free(channel, channel->typings);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int slack_channel_typing_cb(const void *pointer,
|
|
|
|
|
|
|
|
void *data,
|
|
|
|
|
|
|
|
int remaining_calls)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct t_slack_channel_typing *ptr_typing, *next_typing;
|
|
|
|
|
|
|
|
struct t_slack_channel *channel;
|
|
|
|
|
|
|
|
unsigned typecount;
|
|
|
|
|
|
|
|
time_t now;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(void) data;
|
|
|
|
|
|
|
|
(void) remaining_calls;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!pointer)
|
|
|
|
|
|
|
|
return WEECHAT_RC_ERROR;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
channel = (struct t_slack_channel *)pointer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
now = time(NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typecount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (ptr_typing = channel->typings; ptr_typing;
|
|
|
|
|
|
|
|
ptr_typing = ptr_typing->next_typing)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
next_typing = ptr_typing->next_typing;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (ptr_typing && now - ptr_typing->ts > 5)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
slack_channel_typing_free(channel, ptr_typing);
|
|
|
|
|
|
|
|
ptr_typing = next_typing;
|
|
|
|
|
|
|
|
if (ptr_typing)
|
|
|
|
|
|
|
|
next_typing = ptr_typing->next_typing;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!ptr_typing)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typecount++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
weechat_buffer_set(channel->buffer,
|
|
|
|
|
|
|
|
"localvar_set_typing",
|
|
|
|
|
|
|
|
typecount > 0 ? "1" : "0");
|
|
|
|
|
|
|
|
weechat_bar_item_update("slack_typing");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return WEECHAT_RC_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct t_slack_channel_typing *slack_channel_typing_search(
|
|
|
|
|
|
|
|
struct t_slack_channel *channel,
|
|
|
|
|
|
|
|
const char *id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct t_slack_channel_typing *ptr_typing;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!channel || !id)
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (ptr_typing = channel->typings; ptr_typing;
|
|
|
|
|
|
|
|
ptr_typing = ptr_typing->next_typing)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (weechat_strcasecmp(ptr_typing->id, id) == 0)
|
|
|
|
|
|
|
|
return ptr_typing;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void slack_channel_add_typing(struct t_slack_channel *channel,
|
|
|
|
|
|
|
|
struct t_slack_user *user)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct t_slack_channel_typing *new_typing;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new_typing = slack_channel_typing_search(channel, user->id);
|
|
|
|
|
|
|
|
if (!new_typing)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
new_typing = malloc(sizeof(*new_typing));
|
|
|
|
|
|
|
|
new_typing->id = strdup(user->id);
|
|
|
|
|
|
|
|
new_typing->name = strdup(user->profile.display_name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new_typing->prev_typing = channel->last_typing;
|
|
|
|
|
|
|
|
new_typing->next_typing = NULL;
|
|
|
|
|
|
|
|
if (channel->last_typing)
|
|
|
|
|
|
|
|
(channel->last_typing)->next_typing = new_typing;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
channel->typings = new_typing;
|
|
|
|
|
|
|
|
channel->last_typing = new_typing;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
new_typing->ts = time(NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
slack_channel_typing_cb(channel, NULL, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void slack_channel_member_free(struct t_slack_channel *channel,
|
|
|
|
void slack_channel_member_free(struct t_slack_channel *channel,
|
|
|
|
struct t_slack_channel_member *member)
|
|
|
|
struct t_slack_channel_member *member)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -252,7 +390,7 @@ void slack_channel_member_free(struct t_slack_channel *channel,
|
|
|
|
if (!channel || !member)
|
|
|
|
if (!channel || !member)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
/* remove member from members list */
|
|
|
|
/* remove member from members list */
|
|
|
|
if (channel->last_member == member)
|
|
|
|
if (channel->last_member == member)
|
|
|
|
channel->last_member = member->prev_member;
|
|
|
|
channel->last_member = member->prev_member;
|
|
|
|
if (member->prev_member)
|
|
|
|
if (member->prev_member)
|
|
|
@ -289,7 +427,7 @@ void slack_channel_free(struct t_slack_workspace *workspace,
|
|
|
|
if (!workspace || !channel)
|
|
|
|
if (!workspace || !channel)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
/* remove channel from channels list */
|
|
|
|
/* remove channel from channels list */
|
|
|
|
if (workspace->last_channel == channel)
|
|
|
|
if (workspace->last_channel == channel)
|
|
|
|
workspace->last_channel = channel->prev_channel;
|
|
|
|
workspace->last_channel = channel->prev_channel;
|
|
|
|
if (channel->prev_channel)
|
|
|
|
if (channel->prev_channel)
|
|
|
@ -303,7 +441,12 @@ void slack_channel_free(struct t_slack_workspace *workspace,
|
|
|
|
if (channel->next_channel)
|
|
|
|
if (channel->next_channel)
|
|
|
|
(channel->next_channel)->prev_channel = channel->prev_channel;
|
|
|
|
(channel->next_channel)->prev_channel = channel->prev_channel;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* free hooks */
|
|
|
|
|
|
|
|
if (channel->typing_hook_timer)
|
|
|
|
|
|
|
|
weechat_unhook(channel->typing_hook_timer);
|
|
|
|
|
|
|
|
|
|
|
|
/* free linked lists */
|
|
|
|
/* free linked lists */
|
|
|
|
|
|
|
|
slack_channel_typing_free_all(channel);
|
|
|
|
slack_channel_member_free_all(channel);
|
|
|
|
slack_channel_member_free_all(channel);
|
|
|
|
|
|
|
|
|
|
|
|
/* free channel data */
|
|
|
|
/* free channel data */
|
|
|
@ -313,18 +456,18 @@ void slack_channel_free(struct t_slack_workspace *workspace,
|
|
|
|
free(channel->name);
|
|
|
|
free(channel->name);
|
|
|
|
if (channel->name_normalized)
|
|
|
|
if (channel->name_normalized)
|
|
|
|
free(channel->name_normalized);
|
|
|
|
free(channel->name_normalized);
|
|
|
|
if (channel->topic.value)
|
|
|
|
if (channel->topic.value)
|
|
|
|
free(channel->topic.value);
|
|
|
|
free(channel->topic.value);
|
|
|
|
if (channel->topic.creator)
|
|
|
|
if (channel->topic.creator)
|
|
|
|
free(channel->topic.creator);
|
|
|
|
free(channel->topic.creator);
|
|
|
|
if (channel->purpose.value)
|
|
|
|
if (channel->purpose.value)
|
|
|
|
free(channel->purpose.value);
|
|
|
|
free(channel->purpose.value);
|
|
|
|
if (channel->purpose.creator)
|
|
|
|
if (channel->purpose.creator)
|
|
|
|
free(channel->purpose.creator);
|
|
|
|
free(channel->purpose.creator);
|
|
|
|
if (channel->creator)
|
|
|
|
if (channel->creator)
|
|
|
|
free(channel->creator);
|
|
|
|
free(channel->creator);
|
|
|
|
if (channel->buffer_as_string)
|
|
|
|
if (channel->buffer_as_string)
|
|
|
|
free (channel->buffer_as_string);
|
|
|
|
free(channel->buffer_as_string);
|
|
|
|
|
|
|
|
|
|
|
|
free(channel);
|
|
|
|
free(channel);
|
|
|
|
|
|
|
|
|
|
|
|