From 9bcfb2e0005233c40e78806fa679fa8461c1431b Mon Sep 17 00:00:00 2001
From: Gabriel Saldana <gabriel@gabrielsaldana.org>
Date: Sun, 22 May 2011 13:34:53 -0500
Subject: [PATCH 01/15] Fix pointer moving upon background dent loading. patch
 by Alexandre Oliva

The problem is that, when some other buffer is active, including the
minibuffer, we switch the wrong window to the identica-buffer, clear
the buffer (moving the point on the right window), then fill it in and
move the point on the wrong window.

The fix is to only clear and re-create the identica-buffer when it is
the active buffer, and defer updates otherwise.  Thus, if we're on
another window, including the minibuffer, we'll change the status
modeline to indicate there are pending dents.

If there are pending dents, process them instead of downloading more.
---
 identica-mode.el |   48 ++++++++++++++++++++++++++++++++++--------------
 1 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 2a6c229..0a9bfd6 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -509,8 +509,12 @@ ur1ca, tighturl, tinyurl, toly, google and isgd"
 (defvar identica-mode-string identica-method)
 
 (defun identica-set-mode-string (loading)
-  (setq mode-name
-	(if loading (concat "loading " identica-method "...") identica-method)))
+  (with-current-buffer (identica-buffer)
+    (setq mode-name
+	  (if loading (concat
+		       (if (stringp loading) loading "loading")
+		       " " identica-method "...") identica-method))
+    (debug-print mode-name)))
 
 (defvar identica-mode-hook nil
   "Identica-mode hook.")
@@ -705,11 +709,25 @@ arguments (if any) of the SENTINEL procedure."
     (set-buffer identica-buffer)
     (identica-set-mode-string t)))
 
+(defun identica-render-pending-dents ()
+  (interactive)
+  "If at the time an HTTP request for new dents finishes,
+identica-buffer is not active, we defer its update, to make sure
+we adjust point within the right frame."
+  (identica-render-timeline)
+  (when (> identica-new-dents-count 0)
+    (run-hooks 'identica-new-dents-hook)
+    (setq identica-new-dents-count 0))
+  (when identica-display-success-messages
+    (message (or success-message "Success: Get"))))
+
 (defun identica-http-get-default-sentinel
   (&optional status method-class method parameters success-message)
+  (debug-print (window-buffer))
   (let ((error-object (or (assoc :error status)
 			  (and (equal :error (car status))
-                               (cadr status)))))
+                               (cadr status))))
+	(active-p (eq (window-buffer) (identica-buffer))))
     (cond (error-object
 	   (let ((error-data (format "%s" (caddr error-object))))
 	     (when (cond
@@ -733,23 +751,23 @@ arguments (if any) of the SENTINEL procedure."
 	   ;;searching for > that closes the last tag, followed by
 	   ;;CRLF at (point-max)
 	   (let ((body (identica-get-response-body)))
-	     (when body
+	     (if (not body)
+		 (identica-set-mode-string nil)
 	       (setq identica-new-dents-count
-		     (count t (mapcar
-			       #'identica-cache-status-datum
-			       (reverse (identica-xmltree-to-status
-					 body)))))
+		     (+ identica-new-dents-count
+			(count t (mapcar
+				  #'identica-cache-status-datum
+				  (reverse (identica-xmltree-to-status
+					    body))))))
 					; Shorten the timeline if necessary
 	       (if (and identica-display-max-dents
 			(> (safe-length identica-timeline-data)
 			   identica-display-max-dents))
 		   (cl-set-nthcdr identica-display-max-dents
 				  identica-timeline-data nil))
-	       (identica-render-timeline)
-	       (if (> identica-new-dents-count 0)
-		   (run-hooks 'identica-new-dents-hook))
-	       (when identica-display-success-messages
-		 (message (or success-message "Success: Get"))))))))
+	       (if active-p
+		   (identica-render-pending-dents)
+		 (identica-set-mode-string "pending")))))))
   (unless (get-buffer-process (current-buffer))
     (kill-buffer (current-buffer))))
 
@@ -1652,7 +1670,9 @@ this dictionary, only if identica-urlshortening-service is 'google.
 
 (defun identica-current-timeline ()
   (interactive)
-  (identica-get-timeline))
+  (if (> identica-new-dents-count 0)
+      (identica-render-pending-dents)
+    (identica-get-timeline)))
 
 (defun identica-update-status-interactive ()
   (interactive)
-- 
1.7.4.4


From 93c0f348683a1a95e7ce6fd4c6251ddead6cadce Mon Sep 17 00:00:00 2001
From: Gabriel Saldana <gabriel@gabrielsaldana.org>
Date: Sun, 22 May 2011 13:44:06 -0500
Subject: [PATCH 02/15] OAuth support patch by Kevin Granade

---
 identica-mode.el |   74 +++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 0a9bfd6..16dbe40 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -23,6 +23,7 @@
 ;;     Alexande Oliva <oliva@lsd.ic.unicamp.br> (fix for icon placement on reverse order dents)
 ;;     Aidan Gauland <aidalgol@no8wireless.co.nz> (variable scope code cleanup)
 ;;     Joel J. Adamson <adamsonj@email.unc.edu> Added countdown minibuffer-prompt style
+;;     Kevin Granade <kevin.granade@gmail.com> (OAuth support)
 
 
 
@@ -52,6 +53,8 @@
 ;; if using Emacs22 or previous, you'll need json.el
 ;; get it from http://edward.oconnor.cx/2006/03/json.el
 ;; json.el is part of Emacs23
+;; To use the OAuth support, you need oauth.el
+;; Downloadable from http://github.com/psanford/emacs-oauth/
 
 ;; Installation
 
@@ -85,9 +88,14 @@
 (require 'url-http)
 (require 'json)
 (require 'image)
+(require 'oauth)
 
 (defconst identica-mode-version "1.1")
 
+(defvar identica-mode-oauth-consumer-key "53e8e7bf7d1be8e58ef1024b31478d2b")
+
+(defvar identica-mode-oauth-consumer-secret "1ab0876f14bd82c4eb450f720a0e84ae")
+
 ;;url-basepath fix for emacs22
 (unless (fboundp 'url-basepath)
   (defalias 'url-basepath 'url-file-directory))
@@ -176,11 +184,34 @@ If non-nil, dents over this amount will bre removed.")
   :type '(choice (const :tag "Ask" nil) (string))
   :group 'identica-mode)
 
+(defcustom identica-auth-mode "password"
+  "Authorization mode used, options are password and oauth"
+  :type 'string
+  :group 'identica-mode)
+
 (defcustom statusnet-server "identi.ca"
   "Statusnet instance url"
   :type 'string
   :group 'identica-mode)
 
+(defcustom statusnet-request-url
+  "http://identi.ca/api/oauth/request_token"
+  "Statusnet oauth request_token url"
+  :type 'string
+  :group 'identica-mode)
+
+(defcustom statusnet-access-url
+  "http://identi.ca/api/oauth/access_token"
+  "Statusnet oauth access_token url"
+  :type 'string
+  :group 'identica-mode)
+
+(defcustom statusnet-authorize-url
+  "http://identi.ca/api/oauth/authorize"
+  "Statusnet authorization url"
+  :type 'string
+  :group 'identica-mode)
+
 (defcustom statusnet-port 80
   "Port on which StatusNet instance listens"
   :type 'integer
@@ -698,14 +729,28 @@ arguments (if any) of the SENTINEL procedure."
 	(url-package-version identica-mode-version)
 	(url-show-status nil))
     (identica-set-proxy)
-    (identica-set-auth url)
+    (if (equal identica-auth-mode "oauth")
+	(or (and (boundp 'oauth-access-token) oauth-access-token)
+	    (setq oauth-access-token
+		  (oauth-authorize-app identica-mode-oauth-consumer-key
+				       identica-mode-oauth-consumer-secret
+				       statusnet-request-url statusnet-access-url
+				       statusnet-authorize-url))
+	    (print oauth-access-token))
+      (identica-set-auth url))
     (when (get-buffer-process identica-http-buffer)
       (delete-process identica-http-buffer)
       (kill-buffer identica-http-buffer))
-    (setq identica-http-buffer
-	  (url-retrieve url sentinel
-			(append (list method-class method parameters)
-				sentinel-arguments)))
+    (if (and (equal identica-auth-mode "oauth") oauth-access-token)
+	(setq identica-http-buffer
+	      (oauth-url-retrieve oauth-access-token url sentinel
+				  (append (list method-class method parameters)
+					  sentinel-arguments)))
+        (setq identica-http-buffer
+	      (url-retrieve url sentinel
+			    (append (list method-class method parameters)
+				    sentinel-arguments))))
+    (set-buffer identica-buffer)
     (set-buffer identica-buffer)
     (identica-set-mode-string t)))
 
@@ -962,13 +1007,24 @@ PARAMETERS is alist of URI parameters. ex) ((\"mode\" . \"view\") (\"page\" . \"
 	   ;; (url-request-extra-headers '(("Content-Length" . "0"))))
 	 (url-show-status nil))
     (identica-set-proxy)
-    (identica-set-auth url)
+    (if (equal identica-auth-mode "oauth")
+	(or (and (boundp 'oauth-access-token) oauth-access-token)
+	    (setq oauth-access-token
+		  (oauth-authorize-app identica-mode-oauth-consumer-key
+				       identica-mode-oauth-consumer-secret
+				       statusnet-request-url statusnet-access-url
+				       statusnet-authorize-url)))
+        (identica-set-auth url))
     (when (get-buffer-process identica-http-buffer)
       (delete-process identica-http-buffer)
       (kill-buffer identica-http-buffer))
-    (url-retrieve url sentinel
-		  (append (list method-class method parameters)
-			  sentinel-arguments))))
+    (if (equal identica-auth-mode "oauth")
+	(oauth-url-retrieve oauth-access-token url sentinel
+			    (append (list method-class method parameters)
+				    sentinel-arguments))
+        (url-retrieve url sentinel
+		      (append (list method-class method parameters)
+			      sentinel-arguments)))))
 
 (defun identica-http-post-default-sentinel
   (&optional status method-class method parameters success-message)
-- 
1.7.4.4


From 4b4a1fe7cbdf1d3a2f29162ef4f8eefcae5204fd Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Fri, 27 May 2011 20:57:47 -0500
Subject: [PATCH 03/15] Initialized oauth-token variable properly so checking
 it is less messy.

---
 identica-mode.el |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 16dbe40..8fa1617 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -212,6 +212,8 @@ If non-nil, dents over this amount will bre removed.")
   :type 'string
   :group 'identica-mode)
 
+(defvar oauth-access-token nil)
+
 (defcustom statusnet-port 80
   "Port on which StatusNet instance listens"
   :type 'integer
@@ -730,7 +732,7 @@ arguments (if any) of the SENTINEL procedure."
 	(url-show-status nil))
     (identica-set-proxy)
     (if (equal identica-auth-mode "oauth")
-	(or (and (boundp 'oauth-access-token) oauth-access-token)
+	(or oauth-access-token
 	    (setq oauth-access-token
 		  (oauth-authorize-app identica-mode-oauth-consumer-key
 				       identica-mode-oauth-consumer-secret
@@ -1008,7 +1010,7 @@ PARAMETERS is alist of URI parameters. ex) ((\"mode\" . \"view\") (\"page\" . \"
 	 (url-show-status nil))
     (identica-set-proxy)
     (if (equal identica-auth-mode "oauth")
-	(or (and (boundp 'oauth-access-token) oauth-access-token)
+	(or oauth-access-token
 	    (setq oauth-access-token
 		  (oauth-authorize-app identica-mode-oauth-consumer-key
 				       identica-mode-oauth-consumer-secret
-- 
1.7.4.4


From dd57628b5279fe913a0f5d52bc8efd5d93403fc9 Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Fri, 27 May 2011 20:58:28 -0500
Subject: [PATCH 04/15] Removed leftover debug call.

---
 identica-mode.el |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 8fa1617..e87d83a 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -737,8 +737,7 @@ arguments (if any) of the SENTINEL procedure."
 		  (oauth-authorize-app identica-mode-oauth-consumer-key
 				       identica-mode-oauth-consumer-secret
 				       statusnet-request-url statusnet-access-url
-				       statusnet-authorize-url))
-	    (print oauth-access-token))
+				       statusnet-authorize-url)))
       (identica-set-auth url))
     (when (get-buffer-process identica-http-buffer)
       (delete-process identica-http-buffer)
-- 
1.7.4.4


From 5f451b3b99308a660284256cc33924cb5ae36e51 Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Fri, 27 May 2011 20:59:13 -0500
Subject: [PATCH 05/15] Added a wrapper function to store and load oauth
 token.

---
 identica-mode.el |   48 ++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index e87d83a..5e4ecc8 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -702,6 +702,42 @@ read from identica-mode variables `identica-username'
 			      (base64-encode-string auth))
 			(cdr-safe server-double-alist))))))))
 
+(defun identica-initialize-oauth ()
+  "Get authentication token unless we have one stashed already.
+Shamelessly stolen from yammer.el"
+  (if (file-exists-p "~/.identica-oauth-token")
+      (progn
+        (save-excursion
+          (find-file "~/.identica-oauth-token")
+          (let ((str (buffer-substring (point-min) (point-max))))
+            (if (string-match "\\([^:]*\\):\\(.*\\)"
+                              (buffer-substring (point-min) (point-max)))
+                (setq oauth-access-token
+                      (make-oauth-access-token
+                       :consumer-key identica-mode-oauth-consumer-key
+                       :consumer-secret identica-mode-oauth-consumer-secret
+                       :auth-t (make-oauth-t
+                                :token (match-string 1 str)
+                                :token-secret (match-string 2 str))))))
+          (save-buffer)
+          (kill-this-buffer))))
+  (unless oauth-access-token
+    (setq oauth-access-token
+	  (oauth-authorize-app identica-mode-oauth-consumer-key
+			       identica-mode-oauth-consumer-secret
+			       statusnet-request-url statusnet-access-url
+			       statusnet-authorize-url))
+    (save-excursion
+      (find-file "~/.identica-oauth-token")
+      (end-of-buffer)
+      (let ((token (oauth-access-token-auth-t oauth-access-token)))
+        (insert (format "%s:%s\n"
+                        (oauth-t-token token)
+                        (oauth-t-token-secret token))))
+      (save-buffer)
+      (kill-this-buffer)))
+  oauth-access-token)
+
 (defun identica-http-get (method-class method &optional parameters
 				       sentinel sentinel-arguments)
   "Basic function which communicates with server.
@@ -733,11 +769,7 @@ arguments (if any) of the SENTINEL procedure."
     (identica-set-proxy)
     (if (equal identica-auth-mode "oauth")
 	(or oauth-access-token
-	    (setq oauth-access-token
-		  (oauth-authorize-app identica-mode-oauth-consumer-key
-				       identica-mode-oauth-consumer-secret
-				       statusnet-request-url statusnet-access-url
-				       statusnet-authorize-url)))
+	    (identica-initialize-oauth))
       (identica-set-auth url))
     (when (get-buffer-process identica-http-buffer)
       (delete-process identica-http-buffer)
@@ -1010,11 +1042,7 @@ PARAMETERS is alist of URI parameters. ex) ((\"mode\" . \"view\") (\"page\" . \"
     (identica-set-proxy)
     (if (equal identica-auth-mode "oauth")
 	(or oauth-access-token
-	    (setq oauth-access-token
-		  (oauth-authorize-app identica-mode-oauth-consumer-key
-				       identica-mode-oauth-consumer-secret
-				       statusnet-request-url statusnet-access-url
-				       statusnet-authorize-url)))
+	    (identica-initialize-oauth))
         (identica-set-auth url))
     (when (get-buffer-process identica-http-buffer)
       (delete-process identica-http-buffer)
-- 
1.7.4.4


From 7919ee2d869907c12bdd757793c82cc9af6726c9 Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Mon, 30 May 2011 18:49:55 -0500
Subject: [PATCH 06/15] Prototype 'striping' feature.  Every other status
 entry is highlighted when this is enabled.

---
 identica-mode.el |   38 ++++++++++++++++++++++++++++----------
 1 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 16dbe40..894dd51 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -317,6 +317,9 @@ ur1ca, tighturl, tinyurl, toly, google and isgd"
 (defvar identica-timeline-data nil)
 (defvar identica-timeline-last-update nil)
 
+(defvar enable-striping nil)
+(defvar stripe-entry nil)
+
 (defvar identica-username-face 'identica-username-face)
 (defvar identica-uri-face 'identica-uri-face)
 (defvar identica-reply-face 'identica-reply-face)
@@ -816,6 +819,16 @@ we adjust point within the right frame."
   (unless (get-buffer-process (current-buffer))
     (kill-buffer (current-buffer))))
 
+(defun merge-text-properties (start end property)
+  (while (not (eq start end))
+    (let ((prop (get-text-property start 'face))
+          (next-change
+           (or (next-single-property-change start 'face (current-buffer))
+               end)))
+      (if prop (add-text-properties start next-change (list 'face (list prop property)))
+        (add-text-properties start next-change (list 'face property)))
+      (setq start next-change))))
+
 (defun identica-render-timeline ()
   (with-current-buffer (identica-buffer)
     (let ((point (point))
@@ -827,17 +840,22 @@ we adjust point within the right frame."
       (setq buffer-read-only nil)
       (erase-buffer)
       (when wrapped (funcall wrapped -1))
+      (setq stripe-entry nil)
       (mapc (lambda (status)
-	      (insert (identica-format-status
-		       status identica-status-format)
-		      "\n\n")
-	      (if (not wrapped)
-		  (progn
-		    (fill-region-as-paragraph
-		     (save-excursion (beginning-of-line -1) (point)) (point))))
-	      (insert "\n")
-	      (if identica-oldest-first
-		  (goto-char (point-min))))
+              (and enable-striping (setq stripe-entry (not stripe-entry)))
+              (let ((before-status (point-marker)))
+		(insert (identica-format-status
+			 status identica-status-format)
+			"\n\n")
+		(if (not wrapped)
+		    (progn
+		      (fill-region-as-paragraph
+		       (save-excursion (beginning-of-line -1) (point)) (point))))
+		(insert "\n")
+		(and stripe-entry (merge-text-properties before-status (point)
+							 '(:background "LightSlateGrey")))
+		(if identica-oldest-first
+		    (goto-char (point-min)))))
 	    identica-timeline-data)
       (if (and identica-image-stack window-system)
 	  (clear-image-cache))
-- 
1.7.4.4


From 630ad401dac3032f13a204b84fd07f38654ec8fd Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Sat, 4 Jun 2011 13:29:55 -0500
Subject: [PATCH 07/15] Adjusted identica-percent-encode to invoke
 oauth-hexify-string when in oauth mode.

---
 identica-mode.el |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 5e4ecc8..7c78f8a 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -1284,18 +1284,20 @@ If STATUS-DATUM is already in DATA-VAR, return nil. If not, return t."
 	    ret)))
 
 (defun identica-percent-encode (str &optional coding-system)
-  (if (or (null coding-system)
-	  (not (coding-system-p coding-system)))
-      (setq coding-system 'utf-8))
-  (mapconcat
-   (lambda (c)
-     (cond
-      ((identica-url-reserved-p c)
-       (char-to-string c))
-      ((eq c ? ) "+")
-      (t (format "%%%x" c))))
-   (encode-coding-string str coding-system)
-   ""))
+  (if (eq identica-auth-mode "oauth")
+      (oauth-hexify-string str)
+    (if (or (null coding-system)
+	    (not (coding-system-p coding-system)))
+	(setq coding-system 'utf-8))
+    (mapconcat
+     (lambda (c)
+       (cond
+	((identica-url-reserved-p c)
+	 (char-to-string c))
+	((eq c ? ) "+")
+	(t (format "%%%x" c))))
+     (encode-coding-string str coding-system)
+     "")))
 
 (defun identica-url-reserved-p (ch)
   (or (and (<= ?A ch) (<= ch ?z))
-- 
1.7.4.4


From 2a880a94f37a065da53236fe2fcfde304f7e8fcc Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Sat, 4 Jun 2011 23:05:34 -0500
Subject: [PATCH 08/15] Rearanged variables governing striping to avoid
 cluttering namespace.

---
 identica-mode.el |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 7662761..01c32e8 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -319,8 +319,7 @@ ur1ca, tighturl, tinyurl, toly, google and isgd"
 (defvar identica-timeline-data nil)
 (defvar identica-timeline-last-update nil)
 
-(defvar enable-striping nil)
-(defvar stripe-entry nil)
+(defvar identica-enable-striping nil)
 
 (defvar identica-username-face 'identica-username-face)
 (defvar identica-uri-face 'identica-uri-face)
@@ -868,14 +867,14 @@ we adjust point within the right frame."
 	  (end (point-max))
           (wrapped (cond (longlines-mode 'longlines-mode)
                          (visual-line-mode 'visual-line-mode)
-                         (t nil))))
+                         (t nil)))
+	  (stripe-entry nil))
 
       (setq buffer-read-only nil)
       (erase-buffer)
       (when wrapped (funcall wrapped -1))
-      (setq stripe-entry nil)
       (mapc (lambda (status)
-              (and enable-striping (setq stripe-entry (not stripe-entry)))
+              (and identica-enable-striping (setq stripe-entry (not stripe-entry)))
               (let ((before-status (point-marker)))
 		(insert (identica-format-status
 			 status identica-status-format)
-- 
1.7.4.4


From 5971172174a6a14da34323a91acaf30c04b02693 Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Sun, 5 Jun 2011 17:58:16 -0500
Subject: [PATCH 09/15] Refactored striping code to retrieve and apply
 background attribute from a new stripe face instead
 of hardcoding the background attribute in the code.

---
 identica-mode.el |   29 ++++++++++++++++++++++-------
 1 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 01c32e8..5c445b4 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -515,9 +515,14 @@ ur1ca, tighturl, tinyurl, toly, google and isgd"
   (copy-face 'font-lock-string-face 'identica-reply-face)
   (set-face-attribute 'identica-reply-face nil :foreground "white")
   (set-face-attribute 'identica-reply-face nil :background "DarkSlateGray")
-  (defface identica-uri-face
+
+  (defface identica-stripe-face
     `((t nil)) "" :group 'faces)
+  (copy-face 'font-lock-string-face 'identica-stripe-face)
+  (set-face-attribute 'identica-stripe-face nil :background "LightSlateGray")
 
+  (defface identica-uri-face
+    `((t nil)) "" :group 'faces)
   (set-face-attribute 'identica-uri-face nil :underline t)
   (add-to-list 'minor-mode-alist '(identica-icon-mode " id-icon"))
   (add-to-list 'minor-mode-alist '(identica-scroll-mode " id-scroll")))
@@ -851,14 +856,23 @@ we adjust point within the right frame."
   (unless (get-buffer-process (current-buffer))
     (kill-buffer (current-buffer))))
 
-(defun merge-text-properties (start end property)
+(defun merge-text-attribute (start end new-face attribute)
+  "If we just add the new face its attributes somehow get overridden by
+the attributes of the underlying face, so instead we just add the attribute
+we are interested in."
   (while (not (eq start end))
-    (let ((prop (get-text-property start 'face))
+    (let ((bg (face-attribute new-face attribute))
+	  (prop (get-text-property start 'face))
           (next-change
            (or (next-single-property-change start 'face (current-buffer))
                end)))
-      (if prop (add-text-properties start next-change (list 'face (list prop property)))
-        (add-text-properties start next-change (list 'face property)))
+      (if prop
+	  (add-text-properties start next-change
+			       (list 'face 
+				     (list prop 
+					   (list attribute bg))))
+        (add-text-properties start next-change 
+			     (list 'face (list attribute bg))))
       (setq start next-change))))
 
 (defun identica-render-timeline ()
@@ -884,8 +898,9 @@ we adjust point within the right frame."
 		      (fill-region-as-paragraph
 		       (save-excursion (beginning-of-line -1) (point)) (point))))
 		(insert "\n")
-		(and stripe-entry (merge-text-properties before-status (point)
-							 '(:background "LightSlateGrey")))
+		(and stripe-entry
+		     (merge-text-attribute before-status (point)
+					   'identica-stripe-face :background))
 		(if identica-oldest-first
 		    (goto-char (point-min)))))
 	    identica-timeline-data)
-- 
1.7.4.4


From 84e7fc9a46f933510f19a67cf23eee5127f6301b Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Sun, 5 Jun 2011 18:17:18 -0500
Subject: [PATCH 10/15] Added definition of identica-stripe-face variable to
 match other faces.

---
 identica-mode.el |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 5c445b4..6e7c314 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -324,6 +324,7 @@ ur1ca, tighturl, tinyurl, toly, google and isgd"
 (defvar identica-username-face 'identica-username-face)
 (defvar identica-uri-face 'identica-uri-face)
 (defvar identica-reply-face 'identica-reply-face)
+(defvar identica-stripe-face 'identica-stripe-face)
 
 (defun identica-get-or-generate-buffer (buffer)
   (if (bufferp buffer)
-- 
1.7.4.4


From aca6f6b6feb9d6869285f4925420003115d2fa20 Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Sun, 5 Jun 2011 18:21:56 -0500
Subject: [PATCH 11/15] Converted identica-enable-striping to a customizable
 variable.

---
 identica-mode.el |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 6e7c314..d757171 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -319,7 +319,11 @@ ur1ca, tighturl, tinyurl, toly, google and isgd"
 (defvar identica-timeline-data nil)
 (defvar identica-timeline-last-update nil)
 
-(defvar identica-enable-striping nil)
+(defcustom identica-enable-striping nil
+  "If non-nil, set the background of every second entry to the background
+of identica-stripe-face."
+  :type 'boolean
+  :group 'identica-mode)
 
 (defvar identica-username-face 'identica-username-face)
 (defvar identica-uri-face 'identica-uri-face)
-- 
1.7.4.4


From 0c1ad4baaaf78892802302bbd51371572de3ae82 Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Sun, 5 Jun 2011 18:49:18 -0500
Subject: [PATCH 12/15] Added identica-entry-spacing to configure number of
 newlines to insert between entries.

---
 identica-mode.el |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index d757171..70a44f0 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -319,6 +319,9 @@ ur1ca, tighturl, tinyurl, toly, google and isgd"
 (defvar identica-timeline-data nil)
 (defvar identica-timeline-last-update nil)
 
+(defvar identica-entry-spacing 2
+  "The number of spaces to insert between entries.")
+
 (defcustom identica-enable-striping nil
   "If non-nil, set the background of every second entry to the background
 of identica-stripe-face."
@@ -897,7 +900,7 @@ we are interested in."
               (let ((before-status (point-marker)))
 		(insert (identica-format-status
 			 status identica-status-format)
-			"\n\n")
+			(make-string identica-entry-spacing ?\n))
 		(if (not wrapped)
 		    (progn
 		      (fill-region-as-paragraph
-- 
1.7.4.4


From 9719131bab91e7c8d0613a73fad85dce2ce9e6d8 Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Mon, 6 Jun 2011 22:29:10 -0500
Subject: [PATCH 13/15] Added a helper function memq-face to determine when a
 face or property is a member of a face. Updated
 functions where appropriate to use memq-face. This
 resolves the errors where identica-goto-* functions
 would skip entries with differing backgrounds when
 striping is enabled.

---
 identica-mode.el |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 5daeda8..2688e91 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -1913,11 +1913,17 @@ this dictionary, only if identica-urlshortening-service is 'google.
 	(goto-char pos)
       (message "End of status."))))
 
+(defun memq-face (face property)
+  "Check whether face is present in property."
+  (if (listp property)
+      (memq face property)
+    (eq property face)))
+
 (defun identica-get-next-username-face-pos (pos)
   (interactive)
   (let ((prop))
     (catch 'not-found
-      (while (and pos (not (eq prop identica-username-face)))
+      (while (and pos (not (memq-face identica-username-face prop)))
 	(setq pos (next-single-property-change pos 'face))
 	(when (eq pos nil) (throw 'not-found nil))
 	(setq prop (get-text-property pos 'face)))
@@ -1936,7 +1942,7 @@ this dictionary, only if identica-urlshortening-service is 'google.
   (interactive)
   (let ((prop))
     (catch 'not-found
-      (while (and pos (not (eq prop identica-username-face)))
+      (while (and pos (not (memq-face identica-username-face prop)))
 	(setq pos (previous-single-property-change pos 'face))
 	(when (eq pos nil) (throw 'not-found nil))
 	(setq prop (get-text-property pos 'face)))
@@ -1974,7 +1980,7 @@ this dictionary, only if identica-urlshortening-service is 'google.
   (let ((start-pos pos)
 	(end-pos))
     (catch 'not-found
-      (while (eq (get-text-property start-pos 'face) identica-username-face)
+      (while (memq-face identica-username-face (get-text-property start-pos 'face))
 	(setq start-pos (1- start-pos))
 	(when (or (eq start-pos nil) (eq start-pos 0)) (throw 'not-found nil)))
       (setq start-pos (1+ start-pos))
-- 
1.7.4.4


From 41b714ad271a10e0005be0d42941b407397b192b Mon Sep 17 00:00:00 2001
From: Kevin Granade <kevin.granade@gmail.com>
Date: Wed, 8 Jun 2011 21:52:16 -0500
Subject: [PATCH 14/15] Fix brain-dead eq/equal error.

---
 identica-mode.el |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 2688e91..60b95ef 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -1324,7 +1324,7 @@ If STATUS-DATUM is already in DATA-VAR, return nil. If not, return t."
 	    ret)))
 
 (defun identica-percent-encode (str &optional coding-system)
-  (if (eq identica-auth-mode "oauth")
+  (if (equal identica-auth-mode "oauth")
       (oauth-hexify-string str)
     (if (or (null coding-system)
 	    (not (coding-system-p coding-system)))
-- 
1.7.4.4


From 42d9f1adb76b2c26c4d6191544318d4641c65d29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Franco?= <tezcatl@riseup.net>
Date: Wed, 15 Jun 2011 07:15:57 -0500
Subject: [PATCH 15/15] Easy functions for join/leave groups

---
 identica-mode.el |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/identica-mode.el b/identica-mode.el
index 60b95ef..b6949f9 100644
--- a/identica-mode.el
+++ b/identica-mode.el
@@ -160,8 +160,11 @@ If non-nil, dents over this amount will bre removed.")
       ["Public timeline" identica-public-timeline t]
       ["Replies timeline" identica-replies-timeline t]
       ["User timeline" identica-user-timeline t]
-      ["Group timeline" identica-group-timeline t]
       ["Tag timeline" identica-tag-timeline t]
+      ["--" nil nil]
+      ["Group timeline" identica-group-timeline t]
+      ["Join to this group" identica-group-join t]
+      ["Leave this group" identica-group-leave t]
 )))
 
 (defcustom identica-idle-time 20
@@ -464,6 +467,8 @@ of identica-stripe-face."
       (define-key km "\C-c\C-r" 'identica-replies-timeline)
       (define-key km "\C-c\C-a" 'identica-public-timeline)
       (define-key km "\C-c\C-g" 'identica-group-timeline)
+;;      (define-ley km "\C-c\C-j" 'identica-group-join)
+;;      (define-ley km "\C-c\C-l" 'identica-group-leave)
       (define-key km "\C-c\C-t" 'identica-tag-timeline)
       (define-key km "\C-c\C-k" 'identica-stop)
       (define-key km "\C-c\C-u" 'identica-user-timeline)
@@ -1864,6 +1869,18 @@ this dictionary, only if identica-urlshortening-service is 'google.
   (interactive)
   (identica-follow t))
 
+(defun identica-group-join (&optional leaving)
+"Simple functions to join/leave a group we are visiting."
+  (setq identica-method-class "statusnet/groups")
+  (string-match "\\([^\\]*\\)\\(/.*\\)" identica-method)
+  (setq group-method (replace-match
+		      (if leaving "leave"
+			"join") nil nil identica-method 1))
+  (identica-http-post identica-method-class group-method nil))
+
+(defun identica-group-leave ()
+  (identica-group-join t))
+
 (defun identica-favorite ()
   (interactive)
     (if (y-or-n-p "Do you want to favor this notice? ")
-- 
1.7.4.4

