Add to git.
[monolith.git] / chat / users_pane.c
1 /* Monolith chat users pane widget.
2  * - by Richard W.M. Jones <rich@annexia.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  * $Id: users_pane.c,v 1.6 2003/02/22 15:34:28 rich Exp $
19  */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #ifdef HAVE_ASSERT_H
27 #include <assert.h>
28 #endif
29
30 #ifdef HAVE_STRING_H
31 #include <string.h>
32 #endif
33
34 #include <pool.h>
35 #include <hash.h>
36 #include <pstring.h>
37
38 #include <monolith.h>
39 #include <ml_widget.h>
40 #include <ml_smarttext.h>
41
42 #include "chatroom.h"
43 #include "lib.h"
44
45 #include "users_pane.h"
46
47 static void repaint (void *, ml_session, const char *, io_handle);
48
49 struct ml_widget_operations users_pane_ops =
50   {
51     repaint: repaint
52   };
53
54 struct users_pane
55 {
56   struct ml_widget_operations *ops;
57   pool pool;                    /* Pool for allocations. */
58   ml_session session;           /* Current session. */
59   const char *conninfo;         /* Database connection. */
60   chatroom room;                /* The chatroom. */
61   int ie_bug_workaround;        /* Bug workaround for IE. */
62 };
63
64 users_pane
65 new_users_pane (pool pool, ml_session session, const char *conninfo,
66                 chatroom room, int ie_bug_workaround)
67 {
68   users_pane w = pmalloc (pool, sizeof *w);
69
70   w->ops = &users_pane_ops;
71   w->pool = pool;
72   w->session = session;
73   w->conninfo = conninfo;
74   w->room = room;
75   w->ie_bug_workaround = ie_bug_workaround;
76
77   return w;
78 }
79
80 static inline void
81 get_users (chatroom room, pool thread_pool,
82            int *nr_anon_rtn, vector *userids_rtn)
83 {
84   hash users = chatroom_users (room);
85   const int zero = 0;
86   int count;
87
88   /* Get the number of anonymous users. */
89   if (hash_get (users, zero, count))
90     *nr_anon_rtn = count;
91   else
92     *nr_anon_rtn = 0;
93
94   /* Get the list of other users. */
95   *userids_rtn = hash_keys_in_pool (users, thread_pool);
96 }
97
98 static void
99 repaint (void *vw, ml_session session, const char *windowid, io_handle io)
100 {
101   users_pane w = (users_pane) vw;
102   pool thread_pool = pth_get_pool (current_pth);
103   int nr_anon;
104   vector userids;
105   int userid;
106   char *username;
107   db_handle dbh;
108   st_handle sth;
109
110   /* Get the current list of users. */
111   get_users (w->room, thread_pool, &nr_anon, &userids);
112
113   /* Resolve userids to usernames and display. */
114   if (vector_size (userids) > 0)
115     {
116       dbh = get_db_handle (w->conninfo, DBI_THROW_ERRORS);
117
118       sth = st_prepare_cached
119         (dbh,
120          "select userid, username from ml_users where userid in (@) "
121          "order by 2",
122          DBI_VECTOR_INT);
123       st_execute (sth, userids);
124
125       st_bind (sth, 0, userid, DBI_INT);
126       st_bind (sth, 1, username, DBI_STRING);
127
128       while (st_fetch (sth))
129         {
130           io_fputs ("<span class=\"ml_chat_username\">", io);
131           ml_plaintext_print (io, username);
132           io_fputs ("</span><br>", io);
133         }
134
135       put_db_handle (dbh);
136     }
137
138   /* Display number of anonymous users. */
139   io_fprintf (io,
140               "%d&nbsp;<span class=\"ml_chat_username\">anonymous</span>",
141               nr_anon);
142
143   if (! w->ie_bug_workaround)
144     {
145       chat_fill_buffer (io, session, w->conninfo);
146
147       /* Wait for a change. */
148       chatroom_wait_enter_leave_event (w->room, session);
149
150       /* Send some javascript to force the browser to reload. */
151       io_fputs ("<script language=\"javascript\"><!--\n"
152                 "window.location.reload ();\n"
153                 "//--></script>\n",
154                 io);
155     }
156 }