1 /* Copyright (C) 2016-2017 Shengyu Zhang <i@silverrainz.me>
2  *
3  * This file is part of Srain.
4  *
5  * Srain is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <glib.h>
20 
21 #include "core/core.h"
22 
23 #include "srain.h"
24 #include "utils.h"
25 
srn_message_new(SrnChat * chat,SrnChatUser * user,const char * content,SrnMessageType type)26 SrnMessage* srn_message_new(SrnChat *chat, SrnChatUser *user,
27         const char *content, SrnMessageType type){
28     SrnMessage *self;
29 
30     g_return_val_if_fail(chat, NULL);
31     g_return_val_if_fail(user, NULL);
32     g_return_val_if_fail(user->srv_user, NULL);
33 
34     self = g_malloc0(sizeof(SrnMessage));
35 
36     if (!content) {
37         g_warn_if_reached();
38         content = "";
39     }
40 
41     self->type = type;
42     self->sender = user;
43     self->chat = chat;
44     self->content = g_strdup(content);
45     self->time = g_date_time_new_now_local();
46 
47     // Inital render
48     self->rendered_sender = g_markup_escape_text(user->srv_user->nick, -1);
49     self->rendered_remark = g_markup_escape_text("", -1);
50     self->rendered_content = g_markup_escape_text(content, -1);
51     self->rendered_short_time = g_date_time_format(self->time, "%R");
52 #ifdef G_OS_WIN32
53     // FIXME: g_date_time_format(xxx, "%c") does not work on MS Windows
54     self->rendered_full_time = g_date_time_format(self->time, "%F %R");
55 #else
56     self->rendered_full_time = g_date_time_format(self->time, "%c");
57 #endif
58 
59     self->mentioned = FALSE;
60 
61     switch (self->type){
62         case SRN_MESSAGE_TYPE_SENT:
63             self->ui = sui_new_send_message(self);
64             break;
65         case SRN_MESSAGE_TYPE_RECV:
66             self->ui = sui_new_recv_message(self);
67             break;
68         case SRN_MESSAGE_TYPE_NOTICE:
69             self->ui = sui_new_recv_message(self);
70             break;
71         case SRN_MESSAGE_TYPE_MISC:
72             self->ui = sui_new_misc_message(self, SUI_MISC_MESSAGE_STYLE_NORMAL);
73             break;
74         case SRN_MESSAGE_TYPE_ERROR:
75             self->ui = sui_new_misc_message(self, SUI_MISC_MESSAGE_STYLE_ERROR);
76             break;
77         case SRN_MESSAGE_TYPE_ACTION:
78             self->ui = sui_new_misc_message(self, SUI_MISC_MESSAGE_STYLE_ACTION);
79             break;
80         default:
81             self->ui = sui_new_misc_message(self, SUI_MISC_MESSAGE_STYLE_NORMAL);
82             g_warn_if_reached();
83     }
84 
85     return self;
86 }
87 
srn_message_to_string(const SrnMessage * self)88 char* srn_message_to_string(const SrnMessage *self){
89     char *time_str;
90     char *msg_str;
91 
92     time_str = g_date_time_format(self->time, "%T");
93     g_return_val_if_fail(time_str, NULL);
94 
95     switch (self->type){
96         case SRN_MESSAGE_TYPE_SENT:
97             msg_str = g_strdup_printf("[%s] <%s*> %s",
98                     time_str, self->sender->srv_user->nick, self->content);
99             break;
100         case SRN_MESSAGE_TYPE_RECV:
101         case SRN_MESSAGE_TYPE_NOTICE:
102             msg_str = g_strdup_printf("[%s] <%s> %s",
103                     time_str, self->sender->srv_user->nick, self->content);
104             break;
105         case SRN_MESSAGE_TYPE_ACTION:
106             msg_str = g_strdup_printf("[%s] * %s %s",
107                     time_str, self->sender->srv_user->nick, self->content);
108             break;
109         case SRN_MESSAGE_TYPE_MISC:
110             msg_str = g_strdup_printf("[%s] = %s", time_str, self->content);
111             break;
112         case SRN_MESSAGE_TYPE_ERROR:
113             msg_str = g_strdup_printf("[%s] ! %s", time_str, self->content);
114             break;
115         case SRN_MESSAGE_TYPE_UNKNOWN:
116             msg_str = NULL;
117             break;
118         default:
119             g_warn_if_reached();
120             msg_str = NULL;
121             break;
122     }
123 
124     g_free(time_str);
125 
126     return msg_str;
127 }
128 
srn_message_free(SrnMessage * self)129 void srn_message_free(SrnMessage *self){
130     str_assign(&self->content, NULL);
131     g_date_time_unref(self->time);
132 
133     str_assign(&self->rendered_sender, NULL);
134     str_assign(&self->rendered_remark, NULL);
135     str_assign(&self->rendered_content, NULL);
136     str_assign(&self->rendered_short_time, NULL);
137     str_assign(&self->rendered_full_time, NULL);
138     g_list_free_full(self->urls, g_free);
139 
140     g_free(self);
141 }
142