Implemented partial support for conference hotlists ("Add To Hotlist"

button, Conferences sidebox).
This commit is contained in:
Eric J. Bowersox 2001-02-17 06:51:40 +00:00
parent bda25d9aa2
commit 7b7e6be996
16 changed files with 424 additions and 57 deletions

16
TODO
View File

@ -12,6 +12,16 @@ Lots!
- There's no system admin functionality AT ALL. We need to have this stuff
before we go live. (It plugs into the Administrative SIG features.)
- Unimplemented functions on the Top page:
Manage SIG list (SIG sidebox)
Manage Conference Hotlist (Conference sidebox)
Customize Sideboxes
- The plan for the "main" part of the Top page is to let a sysadmin put
notices there by "publishing" selected conference messages to the front page.
We may include a welcome message up top to be displayed if the user's not
logged in.
- Implement quick e-mail from the user profile display (engine support and
UI).
@ -23,14 +33,12 @@ Lots!
- Slippage during posting is still untested.
- Functions still to do on conferencing "topics" page:
Add Conference To Hotlist
- We need a "manage" button at conference list level so we can use that to
manage the ordering of conferences. This operation should be accessible
only to users with "create" privilege on the SIG.
- Implement conference hotlist for users.
- Conference hotlist is now partially implemented, but we need some more work
at engine level.
- Not everybody likes purple. Provide a way to change the default colors.
Probably via entries in render-config.xml. Of course, if we go to a

Binary file not shown.

Before

Width:  |  Height:  |  Size: 685 B

View File

@ -1325,6 +1325,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
# new users.
INSERT INTO sideboxes (uid, boxid, sequence, param)
VALUES (1, 1, 100, NULL), (1, 2, 200, NULL);
INSERT INTO confhotlist (uid, sequence, sigid, confid)
VALUES (1, 100, 2, 2);
# Add the 'Administrator' user to the users table.
# (UID = 2, CONTACTID = 2)
@ -1337,6 +1339,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
# Create the default view for Administrator.
INSERT INTO sideboxes (uid, boxid, sequence, param)
VALUES (2, 1, 100, NULL), (2, 2, 200, NULL);
INSERT INTO confhotlist (uid, sequence, sigid, confid)
VALUES (2, 100, 2, 2);
# Add the administration SIG to the SIGs table.
# (SIGID = 1, CONTACTID = 3)
@ -1432,6 +1436,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
VALUES (5, 'Test', 'User', 'Denver', 'CO', '80231', 'US', 'testuser@example.com', 3);
INSERT INTO sideboxes (uid, boxid, sequence, param)
VALUES (3, 1, 100, NULL), (3, 2, 200, NULL);
INSERT INTO confhotlist (uid, sequence, sigid, confid)
VALUES (3, 100, 2, 2);
INSERT INTO sigmember (sigid, uid, granted_lvl, locked)
VALUES (2, 3, 6500, 1);

View File

@ -141,4 +141,12 @@ public interface ConferenceContext
public abstract boolean canDeleteConference();
public abstract boolean isInHotlist();
public abstract void addToHotlist() throws DataException;
public abstract boolean canAddToHotlist();
public abstract SIGContext getEnclosingSIG();
} // end interface ConferenceContext

View File

@ -0,0 +1,26 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core;
public interface ConferenceHotlistEntry
{
public abstract ConferenceContext getConference();
public abstract int getSequence();
} // end interface ConferenceHotlistEntry

View File

@ -87,4 +87,6 @@ public interface UserContext extends SearchMode
public abstract List getSideBoxList() throws DataException;
public abstract List getConferenceHotlist() throws DataException;
} // end interface UserContext

View File

@ -116,6 +116,37 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end class FixSeenHelper
/*--------------------------------------------------------------------------------
* Static class used to return hot list entries
*--------------------------------------------------------------------------------
*/
static class MyHotlist implements ConferenceHotlistEntry
{
private ConferenceContext conf;
private int seq;
MyHotlist(ConferenceContext conf, int seq)
{
this.conf = conf;
this.seq = seq;
} // end constructor
public ConferenceContext getConference()
{
return conf;
} // end getConference
public int getSequence()
{
return seq;
} // end getSequence
} // end class MyHotlist
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
@ -515,8 +546,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (post>create)
{ // Post level should be no greater than Create
if (logger.isDebugEnabled())
logger.debug("Post level (" + String.valueOf(post) + ") was greater than create level ("
+ String.valueOf(create) + "), correcting");
logger.debug("Post level (" + post + ") was greater than create level (" + create + "), correcting");
post = create;
} // end if
@ -524,8 +554,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (read>post)
{ // Read level should be no greater than Post
if (logger.isDebugEnabled())
logger.debug("Read level (" + String.valueOf(read) + ") was greater than post level ("
+ String.valueOf(post) + "), correcting");
logger.debug("Read level (" + read + ") was greater than post level (" + post + "), correcting");
read = post;
} // end if
@ -533,8 +562,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (change>delete)
{ // Change level should be no greater than Delete
if (logger.isDebugEnabled())
logger.debug("Change level (" + String.valueOf(change) + ") was greater than delete level ("
+ String.valueOf(delete) + "), correcting");
logger.debug("Change level (" + change + ") was greater than delete level (" + delete
+ "), correcting");
change = delete;
} // end if
@ -542,8 +571,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (nuke>delete)
{ // Nuke level should be no greater than Delete
if (logger.isDebugEnabled())
logger.debug("Nuke level (" + String.valueOf(nuke) + ") was greater than delete level ("
+ String.valueOf(delete) + "), correcting");
logger.debug("Nuke level (" + nuke + ") was greater than delete level (" + delete + "), correcting");
nuke = delete;
} // end if
@ -551,8 +579,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (hide>nuke)
{ // Hide level should be no greater than Nuke
if (logger.isDebugEnabled())
logger.debug("Hide level (" + String.valueOf(hide) + ") was greater than nuke level ("
+ String.valueOf(nuke) + "), correcting");
logger.debug("Hide level (" + hide + ") was greater than nuke level (" + nuke + "), correcting");
hide = nuke;
} // end if
@ -791,7 +818,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
public boolean anyUnread()
{
if (deleted)
if (deleted || sig.userIsAnonymous())
return false;
Connection conn = null; // pooled database connection
@ -1228,6 +1255,110 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end canDeleteConference
public boolean isInHotlist()
{
Connection conn = null;
try
{ // retrieve a connection from the datapool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// do a quickie query
StringBuffer sql = new StringBuffer("SELECT sequence FROM confhotlist WHERE uid = ");
sql.append(sig.realUID()).append(" AND sigid = ").append(sig.realSIGID()).append(" AND confid = ");
sql.append(confid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
return rs.next();
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error checking hotlist: " + e.getMessage(),e);
return false;
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end isInHotlist
public void addToHotlist() throws DataException
{
Connection conn = null;
try
{ // retrieve a connection from the datapool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
stmt.executeUpdate("LOCK TABLES confhotlist WRITE;");
try
{ // do a quickie query to see if we're already in the hotlist
StringBuffer sql = new StringBuffer("SELECT sequence FROM confhotlist WHERE uid = ");
sql.append(sig.realUID()).append(" AND sigid = ").append(sig.realSIGID()).append(" AND confid = ");
sql.append(confid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next())
return; // already in hotlist - this is a no-op
// find a sequence number for the new entry
sql.setLength(0);
sql.append("SELECT MAX(sequence) FROM confhotlist WHERE uid = ").append(sig.realUID()).append(';');
rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
throw new InternalStateError("bogus query result on addToHotlist");
int new_sequence = rs.getInt(1) + 100;
// add the new record
sql.setLength(0);
sql.append("INSERT INTO confhotlist (uid, sequence, sigid, confid) VALUES (").append(sig.realUID());
sql.append(", ").append(new_sequence).append(", ").append(sig.realSIGID()).append(", ");
sql.append(confid).append(");");
stmt.executeUpdate(sql.toString());
} // end try
finally
{ // make sure the table is unlocked before we go
Statement ulk_stmt = conn.createStatement();
ulk_stmt.executeUpdate("UNLOCK TABLES;");
} // end finally
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error adding to hotlist: " + e.getMessage(),e);
throw new DataException("error adding to hotlist: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end addToHotList
public boolean canAddToHotlist()
{
if (sig.userIsAnonymous())
return false;
return !(isInHotlist());
} // end canAddToHotlist
public SIGContext getEnclosingSIG()
{
return sig.selfSIG();
} // end getEnclosingSIG
/*--------------------------------------------------------------------------------
* Implementations from interface UserBackend
*--------------------------------------------------------------------------------
@ -1268,6 +1399,12 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
*--------------------------------------------------------------------------------
*/
public SIGContext selfSIG()
{
return sig.selfSIG();
} // end selfsig;
public int realSIGID()
{
return sig.realSIGID();
@ -1468,8 +1605,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
static List getSIGConferences(EngineBackend engine, SIGBackend sig, DataPool datapool) throws DataException
{
if (logger.isDebugEnabled())
logger.debug("getSIGConferences for SIG # " + String.valueOf(sig.realSIGID()) + ", user #"
+ String.valueOf(sig.realUID()));
logger.debug("getSIGConferences for SIG # " + sig.realSIGID() + ", user #" + sig.realUID());
Vector rc = new Vector(); // return from this function
Connection conn = null; // pooled database connection
@ -1529,8 +1665,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
int confid) throws DataException
{
if (logger.isDebugEnabled())
logger.debug("getConference(#" + String.valueOf(confid) + ") for SIG # "
+ String.valueOf(sig.realSIGID()) + ", user #" + String.valueOf(sig.realUID()));
logger.debug("getConference(#" + confid + ") for SIG # " + sig.realSIGID() + ", user #" + sig.realUID());
Connection conn = null; // pooled database connection
@ -1553,8 +1688,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
// Run that monster query!
ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
throw new DataException("conference ID#" + String.valueOf(confid) + " not found in SIG#"
+ String.valueOf(sig.realSIGID()));
throw new DataException("conference ID#" + confid + " not found in SIG#" + sig.realSIGID());
// pass back the new object
return new ConferenceUserContextImpl(engine,sig,datapool,confid,rs.getString(2),
@ -1581,8 +1715,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
String alias) throws DataException
{
if (logger.isDebugEnabled())
logger.debug("getConference(\"" + alias + "\") for SIG # " + String.valueOf(sig.realSIGID())
+ ", user #" + String.valueOf(sig.realUID()));
logger.debug("getConference(\"" + alias + "\") for SIG # " + sig.realSIGID() + ", user #"
+ sig.realUID());
Connection conn = null; // pooled database connection
@ -1607,8 +1741,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
// Run that monster query!
ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
throw new DataException("conference \"" + alias + "\" not found in SIG#"
+ String.valueOf(sig.realSIGID()));
throw new DataException("conference \"" + alias + "\" not found in SIG#" + sig.realSIGID());
// pass back the new object
return new ConferenceUserContextImpl(engine,sig,datapool,rs.getInt(1),rs.getString(3),rs.getString(4),
@ -1630,4 +1763,77 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end getConference
static List getUserHotlist(EngineBackend engine, UserBackend user, DataPool datapool) throws DataException
{
if (logger.isDebugEnabled())
logger.debug("getUserHotlist for user #" + user.realUID());
Connection conn = null; // pooled database connection
Vector rc = new Vector(); // return from this function
try
{ // get a database connection
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// Build a monster query! We pull the SIGID and ConfID entries from the confhotlist table,
// but we need to pull in "confs" and "confmember" (left joined) to get enough data to create
// a ConferenceUserContextImpl object.
StringBuffer sql =
new StringBuffer("SELECT h.sigid, h.confid, c.name, c.descr, c.createdate, s.granted_lvl, "
+ "f.granted_lvl, h.sequence FROM confhotlist h, sigtoconf s, confs c "
+ "LEFT JOIN confmember f ON h.confid = f.confid AND h.uid = f.uid "
+ "WHERE h.confid = s.confid AND c.confid = h.confid AND h.uid = ");
sql.append(user.realUID()).append(" ORDER BY h.sequence ASC;");
if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString());
// Run that puppy!
ResultSet rs = stmt.executeQuery(sql.toString());
// Create some temporary data structures to assist us in building the return list.
HashMap sig_backend_cache = new HashMap();
while (rs.next())
{ // retrieve the sigid from the resultset first
Integer sigid = new Integer(rs.getInt(1));
// we need a SIG backend for our conference, so make sure we have one
SIGBackend sig = (SIGBackend)(sig_backend_cache.get(sigid));
if (sig==null)
{ // get it and make sure it's in the cache for next time
sig = SIGUserContextImpl.getSIGBackend(engine,user,datapool,conn,sigid.intValue());
sig_backend_cache.put(sigid,sig);
} // end if
// make the new ConferenceContext
ConferenceContext conf =
new ConferenceUserContextImpl(engine,sig,datapool,rs.getInt(2),rs.getString(3),rs.getString(4),
SQLUtil.getFullDateTime(rs,5),rs.getInt(6),rs.getInt(7),conn);
// and create the actual return value
ConferenceHotlistEntry hle = new MyHotlist(conf,rs.getInt(8));
rc.add(hle);
} // end while
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error reading hotlist entries: " + e.getMessage(),e);
throw new DataException("unable to retrieve hotlist information: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
return new ReadOnlyVector(rc);
} // end getUserHotlist
} // end class ConferenceUserContextImpl

View File

@ -7,7 +7,7 @@
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Community System.
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
@ -18,9 +18,12 @@
package com.silverwrist.venice.core.impl;
import com.silverwrist.venice.core.DataException;
import com.silverwrist.venice.core.SIGContext;
public interface SIGBackend extends UserBackend
{
public abstract SIGContext selfSIG();
public abstract int realSIGID();
public abstract boolean userHideHiddenConferences();

View File

@ -229,6 +229,38 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
} // end testConferenceAccess
private static SIGUserContextImpl getSIGPrivate(EngineBackend engine, UserBackend user, DataPool datapool,
Connection conn, int sigid) throws DataException
{
try
{ // create the query to find the SIG in the table
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("SELECT signame, alias FROM sigs WHERE sigid = ");
sql.append(sigid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
{ // the SIG entry was not found
logger.error("SIG " + String.valueOf(sigid) + " not found in database");
throw new DataException("SIG #" + String.valueOf(sigid) + " was not found in the database.");
} // end if
// initialize the object and check membership info
SIGUserContextImpl sc = new SIGUserContextImpl(engine,user,datapool,sigid,rs.getString("signame"),
rs.getString("alias"));
sc.checkMembership(conn);
return sc;
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error reading SIG entry: " + e.getMessage(),e);
throw new DataException("unable to retrieve SIG information: " + e.getMessage(),e);
} // end catch
} // end getSIGPrivate
/*--------------------------------------------------------------------------------
* Implementations from class SIGContext
*--------------------------------------------------------------------------------
@ -1132,6 +1164,12 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
*--------------------------------------------------------------------------------
*/
public SIGContext selfSIG()
{
return this;
} // end selfsig;
public int realSIGID()
{
return sigid;
@ -1248,23 +1286,8 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
{ // get a database connection
conn = datapool.getConnection();
// create the query to find the SIG in the table
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("SELECT signame, alias FROM sigs WHERE sigid = ");
sql.append(sigid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
{ // the SIG entry was not found
logger.error("SIG " + String.valueOf(sigid) + " not found in database");
throw new DataException("SIG #" + String.valueOf(sigid) + " was not found in the database.");
} // end if
// initialize the object and check membership info
SIGUserContextImpl sc = new SIGUserContextImpl(engine,user,datapool,sigid,rs.getString("signame"),
rs.getString("alias"));
sc.checkMembership(conn);
return sc;
// return the SIG we want
return getSIGPrivate(engine,user,datapool,conn,sigid);
} // end try
catch (SQLException e)
@ -1325,6 +1348,13 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
} // end getSIGContext
static SIGBackend getSIGBackend(EngineBackend engine, UserBackend user, DataPool datapool, Connection conn,
int sigid) throws DataException
{
return getSIGPrivate(engine,user,datapool,conn,sigid);
} // end getSIGBackend
static List searchForSIGs(EngineBackend engine, UserBackend user, DataPool datapool, int field,
int mode, String term, int offset, int count) throws DataException
{

View File

@ -862,6 +862,12 @@ class UserContextImpl implements UserContext, UserBackend
} // end getSideBoxList
public List getConferenceHotlist() throws DataException
{
return ConferenceUserContextImpl.getUserHotlist(engine,this,datapool);
} // end getConferenceHotlist
/*--------------------------------------------------------------------------------
* Implementations from interface UserBackend
*--------------------------------------------------------------------------------

View File

@ -874,7 +874,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
{ // look to see if the user name is already present
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
stmt.executeUpdate("LOCK TABLES users WRITE, userprefs WRITE, sigmember WRITE, sideboxes WRITE;");
stmt.executeUpdate("LOCK TABLES users WRITE, userprefs WRITE, sigmember WRITE, sideboxes WRITE, "
+ "confhotlist WRITE;");
try
{ // make sure the user name isn't there already
ResultSet rs = stmt.executeQuery("SELECT uid FROM users WHERE username = '" + encode_username + "';");
@ -967,6 +968,31 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
if (logger.isDebugEnabled())
logger.debug("...loaded default sidebox config");
// get the hotlist configuration for this user
rs = stmt.executeQuery("SELECT confhotlist.sequence, confhotlist.sigid, confhotlist.confid FROM "
+ "confhotlist, users WHERE confhotlist.uid = users.uid AND users.is_anon = 1;");
sql.setLength(0);
while (rs.next())
{ // set up to insert into the confhotlist table
if (sql.length()==0)
sql.append("INSERT INTO confhotlist (uid, sequence, sigid, confid) VALUES ");
else
sql.append(", ");
sql.append('(').append(new_uid).append(", ").append(rs.getInt(1)).append(", ").append(rs.getInt(2));
sql.append(", ").append(rs.getInt(3)).append(')');
} // end while
if (sql.length()>0)
{ // execute the big update
sql.append(';');
stmt.executeUpdate(sql.toString());
} // end if
if (logger.isDebugEnabled())
logger.debug("...loaded default hotlist config");
} // end try
finally
{ // make sure the tables get unlocked before we go

View File

@ -326,6 +326,28 @@ public class ConfOperations extends VeniceServlet
} // end if ("M" command)
if (cmd.equals("H"))
{ // "H" = "Add Conference To Hotlist" (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,sig,true,on_error);
on_error = "confdisp?sig=" + sig.getSIGID() + "&conf=" + conf.getConfID();
try
{ // add to the hotlist
conf.addToHotlist();
// and trap back to the conference display
throw new RedirectResult(on_error);
} // end try
catch (DataException de)
{ // something wrong in the database
return new ErrorBox("Database Error","Database error adding to hotlist: " + de.getMessage(),
on_error);
} // end catch
} // end if ("H" command)
if (cmd.equals("DEL"))
{ // "DEL" = "Delete Conference (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,sig,true,on_error);

View File

@ -19,6 +19,7 @@ package com.silverwrist.venice.servlets.format;
import java.io.*;
import java.util.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*;
public class SideBoxConferences implements ContentRender
@ -29,15 +30,17 @@ public class SideBoxConferences implements ContentRender
*/
private UserContext uc;
private List hotlist;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public SideBoxConferences(UserContext uc, String parameter)
public SideBoxConferences(UserContext uc, String parameter) throws DataException
{
this.uc = uc;
this.hotlist = uc.getConferenceHotlist();
} // end constructor
@ -62,14 +65,34 @@ public class SideBoxConferences implements ContentRender
public void renderHere(Writer out, RenderData rdat) throws IOException
{
/* BEGIN TEMP */
out.write("<FONT FACE=\"Arial, Helvetica\" SIZE=2><UL>\n");
out.write("<LI>BOFH (Benevolent Dictators)</LI>\n");
out.write("<LI>Playground (Electric Minds)</LI>\n");
out.write("<LI>Commons (Electric Minds)</LI>\n");
out.write("<LI>Top Ten Lists (Pamela's Lounge)</LI>\n");
out.write("</UL></FONT>\n");
/* END TEMP */
out.write(rdat.getStdFontTag(null,2) + "\n");
if (hotlist.size()>0)
{ // display the list of conferences
out.write("<TABLE ALIGN=CENTER BORDER=0 CELLPADDING=0 CELLSPACING=2>\n");
Iterator it = hotlist.iterator();
while (it.hasNext())
{ // display the names of the conferences and SIGs one by one
ConferenceHotlistEntry hle = (ConferenceHotlistEntry)(it.next());
ConferenceContext conf = hle.getConference();
String href = "confdisp?sig=" + conf.getEnclosingSIG().getSIGID() + "&conf=" + conf.getConfID();
out.write("<TR VALIGN=MIDDLE>\n<TD ALIGN=CENTER WIDTH=14><IMG SRC=\""
+ rdat.getFullImagePath("purple-ball.gif")
+ "\" ALT=\"*\" WIDTH=14 HEIGHT=14 BORDER=0></TD>\n");
out.write("<TD ALIGN=LEFT>\n" + rdat.getStdFontTag(null,2) + "<B><A HREF=\""
+ rdat.getEncodedServletPath(href) + "\">" + StringUtil.encodeHTML(conf.getName())
+ "</A></B> (" + StringUtil.encodeHTML(conf.getEnclosingSIG().getName()) + ")</FONT>\n");
if (conf.anyUnread())
out.write("&nbsp;<IMG SRC=\"" + rdat.getFullImagePath("tag_new.gif")
+ "\" ALT=\"New!\" BORDER=0 WIDTH=40 HEIGHT=20>\n");
out.write("</TD>\n</TR>\n");
} // end while
out.write("</TABLE>\n");
} // end if
else
out.write(rdat.getStdFontTag(null,2) + "<EM>You have no conferences in your hotlist.</EM></FONT>\n");
// write the link at the end
out.write("<P>" + rdat.getStdFontTag(null,1) + "<B>[ <A HREF=\"" + rdat.getEncodedServletPath("TODO")

View File

@ -154,7 +154,7 @@ public class TopicListing implements JSPRender
public boolean canAddToHotlist()
{
return false; // TODO: fix this
return conf.canAddToHotlist();
} // end canAddToHotlist

View File

@ -44,12 +44,13 @@
SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>" ALT="Read New" WIDTH=80 HEIGHT=24
BORDER=0></A>&nbsp;
<% } // end if %>
<A HREF="<%= "confops?" + data.getLocator() + "&cmd=Q" %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=Q") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>" ALT="Manage" WIDTH=80 HEIGHT=24
BORDER=0></A>&nbsp;
<% if (data.canAddToHotlist()) { %>
<A HREF="TODO"><IMG SRC="<%= rdat.getFullImagePath("bn_add_to_hotlist.gif") %>"
ALT="Add to HotList" WIDTH=80 HEIGHT=24 BORDER=0></A>&nbsp;
<A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=H") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_add_to_hotlist.gif") %>" ALT="Add to HotList" WIDTH=80
HEIGHT=24 BORDER=0></A>&nbsp;
<% } // end if %>
</DIV>
<% if (data.anyTopics()) { %>

BIN
web/images/tag_new.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B