[LON-CAPA-cvs] cvs: loncom /interface lonbulletin.pm lonfeedback.pm lonnavmaps.pm

raeburn lon-capa-cvs@mail.lon-capa.org
Wed, 05 May 2004 21:04:15 -0000


This is a MIME encoded message

--raeburn1083791055
Content-Type: text/plain

raeburn		Wed May  5 17:04:15 2004 EDT

  Modified files:              
    /loncom/interface	lonfeedback.pm lonbulletin.pm lonnavmaps.pm 
  Log:
  Posts in discussions now identified as "NEW" if posts were added since user's last visit to resource or bulletin board.  "Speech bubbles" in NAVMAP also displayed for each resource or bulletin board if posts have been added since last visit.
  
  User can set display to be all posts, or only unread posts.  To support cases where there are several "NEW" posts, the time of the previous visit is passed in a query string during hide/make visible, reply or delete operations so that the differentiation of "NEW" posts is retained until the user leaves the bulletin board.  This behavior does not currently apply to discussions associated with resources.
  
  
--raeburn1083791055
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20040505170415.txt"

Index: loncom/interface/lonfeedback.pm
diff -u loncom/interface/lonfeedback.pm:1.79 loncom/interface/lonfeedback.pm:1.80
--- loncom/interface/lonfeedback.pm:1.79	Wed Apr 28 19:59:53 2004
+++ loncom/interface/lonfeedback.pm	Wed May  5 17:04:14 2004
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Feedback
 #
-# $Id: lonfeedback.pm,v 1.79 2004/04/28 23:59:53 raeburn Exp $
+# $Id: lonfeedback.pm,v 1.80 2004/05/05 21:04:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -37,7 +37,7 @@
 use Apache::lonlocal;
 
 sub list_discussion {
-    my ($mode,$status,$symb)=@_;
+    my ($mode,$status,$symb,$previous)=@_;
 #    &Apache::lonnet::logthis("status is $status");
     if (!($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
 	  || $status eq 'OPEN')) {
@@ -56,33 +56,43 @@
     }
     unless ($symb) { return ''; }
 
-    my %dischash = &Apache::lonnet::restore($symb,'nohist_'.$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
-    my %readids = ();
-    my $showonlyunread;
+# backward compatibility (bulletin boards used to be 'wrapped')
+    my $ressymb=$symb;
+    if ($mode eq 'board') {
+        unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
+            $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
+        }
+    }
+
+# Get discussion display settings for this discussion
+    my $lastkey = $ressymb.'_lastread';
+    my $showkey = $ressymb.'_showonlyunread';
+    my $visitkey = $ressymb.'_visit';
+    my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$visitkey],$ENV{'user.domain'},$ENV{'user.name'});
+    my $showonlyunread = 0;
     my $prevread = 0;
+    my $visit = 0;
+    my $newpostsflag = 0;
 
-    foreach my $key (keys %dischash) {
-        if ($key eq 'lastread') {
-            $prevread = $dischash{$key};
-        }
-        if ($key eq 'showonlyunread') {
-            $showonlyunread = $dischash{$key};
-        } else {
-            if ($dischash{$key} eq 'read') {
-                $readids{$key} = 1;
-            }
-        }
+    if ($previous > 0) {
+        $prevread = $previous;
+    } elsif (defined($dischash{$lastkey})) {
+        $prevread = $dischash{$lastkey};
+    }
+
+    if (defined($dischash{$showkey})) {
+        $showonlyunread = $dischash{$showkey};
     }
 
+    if (defined($dischash{$visitkey})) {
+        $visit = $dischash{$visitkey};
+    }
+    $visit ++;
+
     my $seeid=&Apache::lonnet::allowed('rin',$crs);
     my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
 	&& ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));
     my @discussionitems=();
-    # backward compatibility (bulletin boards used to be 'wrapped')
-    my $ressymb=$symb;
-    if ($mode eq 'board') {
-	$ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
-    }
     my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
 			  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
 			  $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
@@ -92,6 +102,7 @@
     my @index=();
     my @replies=();
     my %alldiscussion=();
+    my %notshown = ();
     my $maxdepth=0;
 
     my $target='';
@@ -101,14 +112,19 @@
     }
     
     my $now = time;
-    my %discinfo = (
-                   'lastread' => $now,
-                   ); 
-    &Apache::lonnet::cstore(\%discinfo,$symb,'nohist_'.$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
+    my %discinfo = ();
+    $discinfo{$visitkey} = $visit;
+    $discinfo{$lastkey} = $now;
+
+    &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
 
     if ($contrib{'version'}) {
 	for (my $id=1;$id<=$contrib{'version'};$id++) {
 	    my $idx=$id;
+            my $posttime = $contrib{$idx.':timestamp'};
+            if ($prevread > 0 && $prevread <= $posttime) {
+                $newpostsflag = 1;
+            }
 	    my $hidden=($contrib{'hidden'}=~/\.$idx\./);
 	    my $deleted=($contrib{'deleted'}=~/\.$idx\./);
 	    my $origindex='0.';
@@ -172,13 +188,25 @@
 			if ($seeid) {
 			    if ($hidden) {
 				$sender.=' <a href="/adm/feedback?unhide='.
-				    $ressymb.':::'.$idx.'">'.&mt('Make Visible').'</a>';
+				    $ressymb.':::'.$idx;
+                                if ($newpostsflag) {
+                                    $sender .= '&previous='.$prevread;
+                                }
+                                $sender .= '">'.&mt('Make Visible').'</a>';
 			    } else {
 				$sender.=' <a href="/adm/feedback?hide='.
-				    $ressymb.':::'.$idx.'">'.&mt('Hide').'</a>';
+				    $ressymb.':::'.$idx;
+                                if ($newpostsflag) {
+                                    $sender .= '&previous='.$prevread;
+                                }
+                                $sender .= '">'.&mt('Hide').'</a>';
 			    }                     
 			    $sender.=' <a href="/adm/feedback?deldisc='.
-				$ressymb.':::'.$idx.'">'.&mt('Delete').'</a>';
+				$ressymb.':::'.$idx;
+                                if ($newpostsflag) {
+                                    $sender .= '&previous='.$prevread;
+                                }
+                                $sender .= '">'.&mt('Delete').'</a>';
 			}
 		    } else {
 			if ($screenname) {
@@ -189,19 +217,13 @@
 						 $ENV{'request.course.id'}.
 						 ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
 			$sender.=' <a href="/adm/feedback?replydisc='.
-			    $ressymb.':::'.$idx.'" '.$target.'>'.&mt('Reply').'</a>';
+			    $ressymb.':::'.$idx;
+                        if ($newpostsflag) {
+                            $sender .= '&previous='.$prevread;
+                        }
+                        $sender .= '" '.$target.'>'.&mt('Reply').'</a>';
 		    }
 		    my $vgrlink;
-                    my $ctlink;
-                    if ($readids{$idx} == 1) {
-                        $ctlink = '<b>'.&mt('Mark unread').'?</b>&nbsp;'.
-                            '<input type="checkbox" name="'.
-                            'postunread_'.$idx.'" />';
-                    } else {
-                        $ctlink = '<b>'.&mt('Mark read').'?</b>&nbsp;'.
-                            '<input type="checkbox" name="'.
-                            'postread_'.$idx.'" />';
-                    }
 		    if ($viewgrades) {
 			$vgrlink=&Apache::loncommon::submlink('Submissions',
             $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$symb);
@@ -213,70 +235,77 @@
 		    }
 		    $alldiscussion{$thisindex}=$idx;
 		    $index[$idx]=$thisindex;
-                    my $posttime = $contrib{$idx.':timestamp'};
                     my $spansize = 2;
-                    $discussionitems[$idx]='<p><table border="0" width="100%"><tr>';
-                    if ($prevread > 0 && $prevread < $posttime) {
-                        $discussionitems[$idx] .= '<td align="left" bgcolor="#FFFFFF"><font color="#FF0000">NEW</font></td>';
-                        $spansize ++;
-                    }
-                    $discussionitems[$idx] .= '<td align ="left">&nbsp;&nbsp;'.
-                        '<b>'.$subject.'</b>&nbsp;&nbsp;'.
-                        $sender.'</b> '.$vgrlink.' ('.
-                        localtime($posttime).')'.
-                        '</td><td align="right">&nbsp;&nbsp;'.
-                        $ctlink.'</td></tr>';
-                    if ($showonlyunread && $readids{$idx}) {
-                        $discussionitems[$idx] .= '<tr><td colspan="'.$spansize.'" align="right"><i><font size="-1">Check "Show all posts?" or "Mark unread?", then "Save read settings" to display message</font></i></td></tr></table>';
+                    if ($showonlyunread && $prevread > $posttime) {
+                        $notshown{$idx} = 1;
                     } else {
-                        $discussionitems[$idx] .= '</table><blockquote>'.$message.'</blockquote></p>';
+                        $discussionitems[$idx]='<p><table border="0" width="100%"><tr>';
+                        if ($prevread > 0 && $prevread <= $posttime) {
+                            $discussionitems[$idx] .= '<td align="left" bgcolor="#FFFFFF"><font color="#FF0000">NEW</font></td>';
+                        }
+                        $discussionitems[$idx] .= '<td align ="left">&nbsp;&nbsp;'.
+                            '<b>'.$subject.'</b>&nbsp;&nbsp;'.
+                            $sender.'</b> '.$vgrlink.' ('.
+                            localtime($posttime).')</td></tr>'.
+                            '</table><blockquote>'.$message.'</blockquote></p>';
                     }
                 }
             }
 	}
     }
+
     my $discussion='';
     if ($visible) {
-# Print a the discusssion
-        $discussion .= '<form name="readchoices" method="post" action="/adm/feedback?chgreads='.$symb.'">';
+# Print the discusssion
 	$discussion.='<table bgcolor="#AAAAAA" cellpadding="2" cellspacing="2" border="0">';
 	if ($visible>2) {
 	    my $colspan=$maxdepth+1;
-my $showoption = '<tr><td align="right" bgcolor="#FFFFFF" colspan="'.$colspan.'">';
-            my $showflag = 'all';
+	    $discussion.='<tr><td bgcolor="DDDDBB" colspan="'.$colspan.'">'.
+            '<table border="0" width="100%" bgcolor="#DDDDBB"><tr><td align="left">'.
+            '<a href="/adm/feedback?threadedon='.$ressymb.'">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.
+            '<a href="/adm/feedback?threadedoff='.$ressymb.'">'.&mt('Chronological View').'</a>&nbsp;&nbsp;</td>'.
+            '<td align="right"><a href="/adm/feedback?';
             if ($showonlyunread) {
-                $showoption .= '<b>Show all posts?</b><input type="checkbox"
-name="allposts" value="1"></td></tr>';
+                $discussion .= 'allposts='.$ressymb;
+                if ($newpostsflag) {
+                    $discussion .= '&previous='.$prevread;
+                }
+                $discussion .='">'.&mt('Show all posts').'?';
             } else {
-                $showoption .= '<b>Show only unread posts?</b><input type="checkbox" name="onlyunread" value="1"></td></tr>';
+                $discussion .= 'onlyunread='.$ressymb;
+                if ($newpostsflag) {
+                    $discussion .= '&previous='.$prevread;
+                }
+                $discussion .= '">'.&mt('Show only unread posts').'?';
             }
-            $discussion.=$showoption;
-	    $discussion.='<tr><td bgcolor="DDDDBB" colspan="'.$colspan.'">'.
-            '<table border="0" width="100%" bgcolor="#DDDDBB"><tr><td align="left">'.
-            '<a href="/adm/feedback?threadedon='.$symb.'">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.
-            '<a href="/adm/feedback?threadedoff='.$symb.'">'.&mt('Chronological View').'</a>&nbsp;&nbsp;</td>'.
-            '<td align="right"><a href="/adm/feedback?markread='.$symb.'">'.&mt('Mark all read').'</a>&nbsp;&nbsp;'.
-            '<a href="/adm/feedback?markunread='.$symb.'">'.&mt('Mark all unread').'</a>&nbsp;&nbsp;'.
-            '</td></tr></table></td></tr>';
+            $discussion .= '</a>&nbsp;&nbsp;</td></tr></table></td></tr>';
 	}
-
+        my $numhidden = keys %notshown;
+        if ($numhidden > 0) {
+            my $colspan = $maxdepth+1;
+            $discussion.="\n".'<tr><td bgcolor="#CCCCCC" colspan="'.$colspan.'">'.
+                         '<a href="/adm/feedback?allposts='.$ressymb;
+            if ($newpostsflag) {
+                $discussion .= '&previous='.$prevread;
+            }
+            $discussion .= '">'.&mt('Show all posts').'</a> '.&mt('to display').' '.
+                         $numhidden.' '.&mt('previously viewed posts').
+                         '<br/></td></tr>';
+        }
 	foreach (sort { $a <=> $b } keys %alldiscussion) {
-	    $discussion.="\n<tr>";
-	    my $thisdepth=$depth[$alldiscussion{$_}];
-	    for (1..$thisdepth) {
-		$discussion.='<td>&nbsp;&nbsp;&nbsp;</td>';
+            unless ($notshown{$alldiscussion{$_}} eq '1') {
+	        $discussion.="\n<tr>";
+	        my $thisdepth=$depth[$alldiscussion{$_}];
+	        for (1..$thisdepth) {
+		    $discussion.='<td>&nbsp;&nbsp;&nbsp;</td>';
+	        }
+	        my $colspan=$maxdepth-$thisdepth+1;
+                $discussion.='<td  bgcolor="#CCCCCC" colspan="'.$colspan.'">'.
+                             $discussionitems[$alldiscussion{$_}].
+	                     '</td></tr>';
 	    }
-	    my $colspan=$maxdepth-$thisdepth+1;
-            $discussion.='<td  bgcolor="#CCCCCC" colspan="'.$colspan.'">'.
-                         $discussionitems[$alldiscussion{$_}].
-	                 '</td></tr>';
-	}
-        my $colspan=$maxdepth+1;
-        $discussion.='<tr><td bgcolor="#FFFFFF" align="right" colspan="'.
-        $colspan.'"><br /><input type="hidden" name="storereads" value="0">'.            '<input type="hidden" name="discsymb" value="'.$symb.'">'.
-        '<input type="button" name="readoptions" '.
-        'value="Save read settings" onClick="this.form.storereads.value=1;this.form.submit();"></td></tr>';
-        $discussion .= '</table><br /><br /></form>';
+        }
+        $discussion.='</table><br /><br />';
     }
     if ($discussiononly) {
 	$discussion.=(<<ENDDISCUSS);
@@ -317,12 +346,13 @@
   if (!$title) { $title = $feedurl; }
   my $quote='';
   my $subject = '';
+  my $prevtag = '';
   if ($ENV{'form.replydisc'}) {
       my ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'});
       my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
 					   $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
 					   $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
-      unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) { 
+      unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) {
 	  my $message=$contrib{$idx.':message'};
 	  $message=~s/\n/\<br \/\>/g;
 	  $quote='<blockquote>'.&Apache::lontexconvert::msgtexconverted($message).'</blockquote>';
@@ -330,6 +360,9 @@
               $subject = 'Re: '.$contrib{$idx.':subject'};
           }
       }
+      if ($ENV{'form.previous'}) {
+          $prevtag = '<input type="hidden" name="previous" value="'.$ENV{'form.previous'}.'" />';
+      }
   }
   my $latexHelp = Apache::loncommon::helpLatexCheatsheet();
   my $send=&mt('Send');
@@ -386,6 +419,7 @@
 <h2><tt>$title</tt></h2>
 <form action="/adm/feedback" method="post" name="mailform"
 enctype="multipart/form-data">
+$prevtag
 <input type="hidden" name="postdata" value="$feedurl" />
 <input type="hidden" name="replydisc" value="$ENV{'form.replydisc'}" />
 Please check at least one of the following feedback types:
@@ -428,14 +462,25 @@
 }
 
 sub redirect_back {
-  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status) = @_;
+  my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous) = @_;
+  my $prevtag = '';
+  my $qrystr = '';
   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
+  if ($previous > 0) {
+      $qrystr = 'previous='.$previous;
+      if ($feedurl =~ /\?register=1/) {
+          $feedurl .= '&'.$qrystr;
+      } else {
+          $feedurl .= '?'.$qrystr;
+      }
+      $prevtag = '<input type="hidden" name="previous" value="'.$previous.'" />';
+  }
   $r->print (<<ENDREDIR);
 <html>
 <head>
 <title>Feedback sent</title>
 <meta http-equiv="pragma" content="no-cache" />
-<meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl">
+<meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
 </head>
 <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>
 <img align="right" src="/adm/lonIcons/lonlogos.gif" />
@@ -443,6 +488,7 @@
 <b>Sent $sendsomething message(s), and $sendposts post(s).</b>
 <font color="red">$status</font>
 <form name="reldt" action="$feedurl" target="loncapaclient">
+$prevtag
 </form>
 </body>
 </html>
@@ -754,75 +800,29 @@
 # --------------------------- Get query string for limited number of parameters
 
    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
-#         ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff']);
-         ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff','markread','markunread','storereads','onlyunread','allposts','chgreads']);
+         ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff','onlyunread','allposts','previous']);
 
-  if (($ENV{'form.markread'}) || ($ENV{'form.markunread'})) {
-# ----------------------------------------------------------------- Modify read/unread for all
+  if (($ENV{'form.allposts'}) || ($ENV{'form.onlyunread'})) {
+# ----------------------------------------------------------------- Modify display setting for this discussion 
       &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
-      my $symb=$ENV{'form.markread'}?$ENV{'form.markread'}:$ENV{'form.markunread'};
-      my $ressymb = $symb;
+      my $symb=$ENV{'form.allposts'}?$ENV{'form.allposts'}:$ENV{'form.onlyunread'};
       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
-      $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
-      my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
+      my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                           $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                           $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
       my %readinghash = ();
                                                                                  
       if ($contrib{'version'}) {
-          for (my $id=1;$id<=$contrib{'version'};$id++) {
-              my $msgid = $id.':message';
-              if (defined($contrib{$msgid})) {
-                  if ($ENV{'form.markread'}) {
-                      $readinghash{$id} = 'read';
-                  } else {
-                       $readinghash{$id} = 'unread';
-                  }
-              }
-          }
           if ($ENV{'form.allposts'}) {
-              $readinghash{'showonlyunread'} = 0;
+              $readinghash{$symb.'_showonlyunread'} = 0;
           } elsif ($ENV{'form.onlyunread'}) {
-              $readinghash{'showonlyunread'} = 1;
+              $readinghash{$symb.'_showonlyunread'} = 1;
           }
-          &Apache::lonnet::cstore(\%readinghash,$symb,'nohist_'.$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
+          &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%readinghash,$ENV{'user.domain'},$ENV{'user.name'});
       }
-                                                                                 
-      &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed reading status'),'0','0');
+      &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed reading status').'<br />','0','0','',$ENV{'form.previous'});
       return OK;
-  } else {
-      my $symb = $ENV{'form.discsymb'};
-      my %readinghash = ();
-      my $chgcount = 0;
-      foreach my $key (keys %ENV) {
-          if ($key =~ m/^form\.postunread_(\d+)/) {
-              $readinghash{$1} = 'unread';
-              $chgcount ++;
-          } elsif ($key =~ m/^form\.postread_(\d+)/) {
-              $readinghash{$1} = 'read';
-              $chgcount ++;
-          }
-      }
-      if ($ENV{'form.allposts'}) {
-          $readinghash{'showonlyunread'} = 0;
-          $chgcount ++;
-      } elsif ($ENV{'form.onlyunread'}) {
-          $readinghash{'showonlyunread'} = 1;
-          $chgcount ++;
-      }
-                                                                                 
-      if ($chgcount > 0) {
-          &Apache::lonnet::cstore(\%readinghash,$symb,'nohist_'.$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
-      }
-  }
-
-  if ($ENV{'form.chgreads'}) {
-      &Apache::loncommon::content_type($r,'text/html');
-      $r->send_http_header;
-      my ($map,$ind,$url)=&Apache::lonnet::decode_symb($ENV{'form.chgreads'});
-      &redirect_back($r,&Apache::lonnet::clutter($url),
-       &mt('Changed read status').'<br />','0','0');
   } elsif (($ENV{'form.hide'}) || ($ENV{'form.unhide'})) {
 # ----------------------------------------------------------------- Hide/unhide
     &Apache::loncommon::content_type($r,'text/html');
@@ -852,7 +852,7 @@
 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
 
     &redirect_back($r,&Apache::lonnet::clutter($url),
-       &mt('Changed discussion status').'<br />','0','0');
+       &mt('Changed discussion status').'<br />','0','0','',$ENV{'form.previous'});
   } elsif (($ENV{'form.threadedon'}) || ($ENV{'form.threadedoff'})) {
       &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
@@ -866,7 +866,7 @@
       my $symb=$ENV{'form.threadedon'}?$ENV{'form.threadedon'}:$ENV{'form.threadedoff'};
       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
       &redirect_back($r,&Apache::lonnet::clutter($url),
-		     &mt('Changed discussion view mode').'<br />','0','0');
+		     &mt('Changed discussion view mode').'<br />','0','0','',$ENV{'form.previous'});
   } elsif ($ENV{'form.deldisc'}) {
 # --------------------------------------------------------------- Hide for good
     &Apache::loncommon::content_type($r,'text/html');
@@ -893,7 +893,7 @@
 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
 
     &redirect_back($r,&Apache::lonnet::clutter($url),
-       &mt('Changed discussion status').'<br />','0','0');
+       &mt('Changed discussion status').'<br />','0','0','',$ENV{'form.previous'});
   } elsif ($ENV{'form.preview'}) {
 # -------------------------------------------------------- User wants a preview
       $r->content_type('text/html');
@@ -1006,7 +1006,7 @@
 
 
 # Receipt screen and redirect back to where came from
-      &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$status);
+      &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$status,$ENV{'form.previous'});
 
     }
    } else {
Index: loncom/interface/lonbulletin.pm
diff -u loncom/interface/lonbulletin.pm:1.20 loncom/interface/lonbulletin.pm:1.21
--- loncom/interface/lonbulletin.pm:1.20	Fri Apr 30 19:13:52 2004
+++ loncom/interface/lonbulletin.pm	Wed May  5 17:04:14 2004
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Bulletin Board Handler
 #
-# $Id: lonbulletin.pm,v 1.20 2004/04/30 23:13:52 albertel Exp $
+# $Id: lonbulletin.pm,v 1.21 2004/05/05 21:04:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -42,6 +42,7 @@
     $r->send_http_header;
     return OK if $r->header_only;
 
+    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous']);
 # ------------------------------------------------------------ Print the screen
     $r->print(<<ENDDOCUMENT);
 <html>
@@ -193,7 +194,7 @@
     }
     $r->print(&Apache::lonfeedback::list_discussion
 	      ('board','OPEN','bulletin___'.$marker.'___'.
-	       $r->uri).'</body></html>');
+	       $r->uri,$ENV{'form.previous'}).'</body></html>');
     return OK;
 } 
 
Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.258 loncom/interface/lonnavmaps.pm:1.259
--- loncom/interface/lonnavmaps.pm:1.258	Tue Apr 13 11:49:42 2004
+++ loncom/interface/lonnavmaps.pm	Wed May  5 17:04:14 2004
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Navigate Maps Handler
 #
-# $Id: lonnavmaps.pm,v 1.258 2004/04/13 15:49:42 albertel Exp $
+# $Id: lonnavmaps.pm,v 1.259 2004/05/05 21:04:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1813,6 +1813,7 @@
 
 sub generate_email_discuss_status {
     my $self = shift;
+    my $symb = shift;
     if ($self->{EMAIL_DISCUSS_GENERATED}) { return; }
 
     my $cid=$ENV{'request.course.id'};
@@ -1825,6 +1826,15 @@
 			   $courseLeaveTime : $logoutTime);
     my %discussiontime = &Apache::lonnet::dump('discussiontimes', 
 					       $cdom, $cnum);
+    my %lastread = &Apache::lonnet::dump('nohist_'.$cid.'_discuss',
+                                        $ENV{'user.domain'},$ENV{'user.name'},'lastread');
+    my %lastreadtime = ();
+    foreach (keys %lastread) {
+        my $key = $_;
+        $key =~ s/_lastread$//;
+        $lastreadtime{$key} = $lastread{$_};
+    }
+
     my %feedback=();
     my %error=();
     my $keys = &Apache::lonnet::reply('keys:'.
@@ -1858,6 +1868,7 @@
     $self->{ERROR_MSG} = \%error; # what is this? JB
     $self->{DISCUSSION_TIME} = \%discussiontime;
     $self->{EMAIL_STATUS} = \%emailstatus;
+    $self->{LAST_READ} = \%lastreadtime;
     
     $self->{EMAIL_DISCUSS_GENERATED} = 1;
 }
@@ -1926,8 +1937,20 @@
     if (!defined($self->{DISCUSSION_TIME})) { return 0; }
 
     #return defined($self->{DISCUSSION_TIME}->{$symb});
-    return $self->{DISCUSSION_TIME}->{$symb} >
-           $self->{LAST_CHECK};
+
+# backward compatibility (bulletin boards used to be 'wrapped')
+    my $ressymb = $symb;
+    if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) {
+        unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
+            $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
+        }
+    }
+
+    if ( defined ( $self->{LAST_READ}->{$ressymb} ) ) {
+        return $self->{DISCUSSION_TIME}->{$ressymb} > $self->{LAST_READ}->{$ressymb};
+    } else {
+        return $self->{DISCUSSION_TIME}->{$ressymb} >  $self->{LAST_CHECK};
+    }
 }
 
 # Private method: Does the given resource (as a symb string) have

--raeburn1083791055--