summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Ostler <sostler@deathmachine.local>2010-01-19 23:25:29 -0500
committerScott Ostler <sostler@deathmachine.local>2010-01-19 23:25:29 -0500
commita91eb914edb95a5facd62b2eac00186b7b8c63c1 (patch)
tree9e5a331303d148aec0c91287e44b210d442be072
parent7d447a321dedf2c767f8f0d0ac885d529dd387f9 (diff)
Getting ready for commit
-rwxr-xr-xdb/0-create.psql13
-rwxr-xr-xsrc/site.clj34
-rwxr-xr-xstatic/index.html3
-rwxr-xr-xstatic/pichat.js77
-rwxr-xr-xtemplate/head.st2
5 files changed, 86 insertions, 43 deletions
diff --git a/db/0-create.psql b/db/0-create.psql
index ac0dac6..7c6b4b0 100755
--- a/db/0-create.psql
+++ b/db/0-create.psql
@@ -28,10 +28,23 @@ CREATE TABLE messages (
is_image bool NOT NULL
);
+-- Queries to support:
+-- 1) What are my favorite images? (By room, time, or author)
+-- 2) Who favorited me? (By user, image, or time)
+-- 3) What are the most favorited images? (By room, time, or author)
+CREATE TABLE favorites (
+ favorite_id SERIAL PRIMARY KEY,
+ src_user_id integer NOT NULL REFERENCES users,
+ message_id integer NOT NULL REFERENCES messages,
+ created_on timestamp NOT NULL DEFAULT now()
+);
+
CREATE INDEX user_id_idx ON messages (user_id);
CREATE INDEX room_id_idx ON messages (room_id);
CREATE INDEX created_on_idx ON messages (created_on);
+CREATE INDEX src_user_id_idx ON favorites (src_user_id);
+
INSERT INTO rooms (key, name, description, admin_only)
VALUES ('RoomA', 'Room A', 'Hangout', false);
INSERT INTO rooms (key, name, description, admin_only)
diff --git a/src/site.clj b/src/site.clj
index 5868f94..b89215c 100755
--- a/src/site.clj
+++ b/src/site.clj
@@ -23,7 +23,7 @@
(.setRefreshInterval template-group 3)
(defstruct user-struct :nick :user_id :avatar :last-seen)
-(defstruct message-struct :nick :content :created_on)
+(defstruct message-struct :nick :content :created_on :msg_id)
(defn user-struct-from-session [session]
(struct user-struct (session :nick) (session :user_id) (session :avatar)
@@ -123,6 +123,7 @@
(defn process-message-for-output [d]
{"nick" (encode-html-entities (d :nick))
+ "msg_id" (d :message_id)
"created_on" (.format formatter (d :created_on))
"content" (encode-html-entities (d :content))})
@@ -164,7 +165,7 @@
(defn fetch-messages-by-room
([room-id image-only] (fetch-messages-by-room room-id image-only 0))
([room-id image-only offset]
- (let [query (str "SELECT m.content, m.created_on, u.nick "
+ (let [query (str "SELECT m.content, m.message_id, m.created_on, u.nick "
"FROM messages m, users u "
"WHERE room_id = ? AND m.user_id = u.user_id "
(if image-only "AND m.is_image = true " "")
@@ -358,13 +359,13 @@
(re-find pic-regex (strip-params content)))
true false))
-(defn msg-db [user-id room-id msg]
- (let [content (.trim (msg :content))
- is-image (is-image? content)]
+(defn msg-db [user-id room-id content]
+ (let [is-image (is-image? content)
+ qry (str "INSERT INTO messages (user_id, room_id, content, is_image) "
+ "VALUES (?, ?, ?, ?) RETURNING message_id")]
(with-connection db
- (insert-values :messages
- [:user_id :room_id :content :is_image]
- [user-id room-id content is-image]))))
+ ((first (do-select [qry user-id room-id content is-image]))
+ :message_id))))
(defn msg [session params]
(let [user-id (session :user_id)
@@ -372,18 +373,17 @@
room-key (params :room)
room (@rooms room-key)
content (.trim (params :content))
- now (new Date)
- msg (struct message-struct nick content now)]
+ now (new Date)]
(cond (not room) (resp-error "BAD_ROOM")
(not nick) (resp-error "NOT_LOGGED_IN")
:else
- (do
- (dosync
- (if (not (contains? @(room :users) nick))
- (login-user (user-struct-from-session session) room))
- (add-message msg room))
- (msg-db user-id (room :room_id) msg)
- (resp-success "OK")))))
+ (let [msg-id (msg-db user-id (room :room_id) content)
+ msg (struct message-struct nick content now msg-id)]
+ (dosync
+ (if (not (contains? @(room :users) nick))
+ (login-user (user-struct-from-session session) room))
+ (add-message msg room))
+ (resp-success msg-id)))))
(defn validated-msg [session params]
(let [room-key (params :room)
diff --git a/static/index.html b/static/index.html
index 0ed1671..df36408 100755
--- a/static/index.html
+++ b/static/index.html
@@ -1,5 +1,6 @@
</html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
+ <script type="text/javascript" src="/static/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="static/sha1.js"></script>
<script type="text/javascript" src="static/home.js"></script>
<script type="text/javascript" src="static/background.js"></script>
@@ -231,4 +232,4 @@ onchange="this.beenchanged = true;"/>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/static/pichat.js b/static/pichat.js
index 559e775..eb0b76f 100755
--- a/static/pichat.js
+++ b/static/pichat.js
@@ -28,10 +28,17 @@ function buildMsgContent(content) {
}
}
-function buildMessageDiv(msg) {
+var SpinnerImage = '<img class="spinner" src="/static/spinner.gif" />';
+
+function buildMessageDiv(msg, isLoading) {
var nick = escapeHtml(msg.nick);
- return '<div class="msgDiv"><b><a href="/u/' + nick + ' ">' + nick + '</a>: </b>'
- + buildMsgContent(msg.content) + '</div>';
+ var msgId = 'msg-' + msg.msg_id || 0;
+ var spinnerHtml = isLoading ? SpinnerImage : '';
+ return '<div class="msgDiv" id="' + msgId + '">'
+ + '<b><a href="/u/' + nick + ' ">' + nick + '</a>: </b>'
+ + buildMsgContent(msg.content)
+ + spinnerHtml
+ + '</div>';
}
function buildGrowlDataAndPopDatShit(msg) {
@@ -43,12 +50,14 @@ function buildGrowlDataAndPopDatShit(msg) {
function buildUserDiv(user) {
if (user.avatar) {
- return '<div class="username"><a href="/u/' + escapeHtml(user.nick) + '">' +
- '<img src="' + user.avatar + '" width="50" height="50">' +
- escapeHtml(user.nick) + '</a></div>';
+ return '<div class="username">'
+ + '<a href="/u/' + escapeHtml(user.nick) + '" target="_blank">'
+ + '<img src="' + user.avatar + '" width="50" height="50">'
+ + escapeHtml(user.nick) + '</a></div>';
} else {
- return '<div class="username"><a href="/u/' + escapeHtml(user.nick) + '">' +
- escapeHtml(user.nick) + '</a></div>';
+ return '<div class="username">'
+ + '<a href="/u/' + escapeHtml(user.nick) + '" target="_blank">'
+ + escapeHtml(user.nick) + '</a></div>';
}
}
@@ -69,11 +78,14 @@ function submitMessage() {
PostedMessages.push(content);
$('#msgInput').val('');
- updateUI([{ 'nick': Nick, 'content': content}], null);
+ var msg = { 'nick': Nick, 'content': content };
+ var div = addNewMessage(msg, true);
- var onSuccess = function(json) {};
- var onError = function(resp, textStatus, errorThrown) {
- $('#msgInput, #msgSubmit').removeAttr('disabled');
+ var onSuccess = function(json) {
+ div.find('.spinner').remove();
+ };
+ var onError = function(resp, textStatus, errorThrown) {
+ div.remove();
handleMsgError(resp);
};
@@ -109,26 +121,40 @@ function delayedScrollToBottom(delay) {
setTimeout(scrollToBottom, delay, $('#messageList')[0]);
}
+function addNewMessages(msgs) {
+ var wasScrolledToBottom = isScrolledToBottom($('#messageList')[0]);
+ var msgStr = $.map(msgs, buildMessageDiv).join('');
+ $('#messageList').append(msgStr);
+
+ if (wasScrolledToBottom) { delayedScrollToBottom(500); }
+}
+
+function addNewMessage(msg, isLoading) {
+ var wasScrolledToBottom = isScrolledToBottom($('#messageList')[0]);
+ var msgStr = buildMessageDiv(msg, isLoading);
+ var div = $(msgStr).appendTo('#messageList');
+ if (wasScrolledToBottom) { delayedScrollToBottom(500); }
+ return div;
+}
+
+function setUserList(users) {
+ $("#userList").html($.map(users, buildUserDiv).join(''));
+}
+
function updateUI(msgs, users) {
- if (window['growlize'] && msgs !== null) {
- $.map(msgs, buildGrowlDataAndPopDatShit)
- }
- else if (msgs !== null) {
- var msgStr = $.map(msgs, buildMessageDiv).join('');
- var wasScrolledToBottom = isScrolledToBottom($('#messageList')[0]);
- $('#messageList').append(msgStr);
-
- if (wasScrolledToBottom) {
- delayedScrollToBottom(500);
- }
+ if (window['growlize'] && msgs && msgs.length > 0) {
+ $.map(msgs, buildGrowlDataAndPopDatShit)
+ } else if (msgs && msgs.length > 0) {
+ addNewMessages(msgs);
}
if (users !== null) {
- $("#userList").html($.map(users, buildUserDiv).join(''));
+ setUserList(users);
}
}
// A duplicate message is a message that was likely to have
// originated from this browser.
+// TODO: replace w/ msg_id checks.
function isDuplicateMessage(m) {
if (m.nick != Nick || $.inArray(m.content, PostedMessages) == -1) {
return false;
@@ -242,3 +268,6 @@ function growl(user, msg) {
text: msg
});
}
+
+// TODO
+function favoriteImage() {}; \ No newline at end of file
diff --git a/template/head.st b/template/head.st
index d46687f..66f8fb1 100755
--- a/template/head.st
+++ b/template/head.st
@@ -1,7 +1,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
-<!-- <script type="text/javascript" src="/static/jquery-1.3.2.min.js"></script> -->
+<script type="text/javascript" src="/static/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/static/sha1.js"></script>
<script type="text/javascript" src="/static/pichat.js"></script>