* SusiMail:

- Move delete and confirmation button in folder view to bottom left,
     page size form to bottom right
   - Attachment finals and cleanup
   - Increase max size for full download again
   - Fix repeated re-saves of mail to disk
   - Enable auto-deletion of downloaded mails
   - Consolidate check box processing
   - Button spacing tweaks
This commit is contained in:
zzz
2014-04-25 16:11:35 +00:00
parent 4e0c4f6f98
commit 04cabf40b5
5 changed files with 94 additions and 112 deletions

View File

@ -23,65 +23,35 @@
*/ */
package i2p.susi.webmail; package i2p.susi.webmail;
import i2p.susi.util.ReadBuffer;
/** /**
* @author user * @author user
*/ */
class Attachment { class Attachment {
private String fileName, contentType, transferEncoding; private final String fileName, contentType, transferEncoding;
private ReadBuffer buffer; private final String data;
private String data;
Attachment(String name, String type, String encoding, String data) {
fileName = name;
contentType = type;
transferEncoding = encoding;
this.data = data;
}
/** /**
* @return Returns the fileName. * @return Returns the fileName.
*/ */
public String getFileName() { public String getFileName() {
return fileName; return fileName;
} }
/**
* @param fileName The fileName to set.
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* @return Returns the buffer.
*/
public ReadBuffer getBuffer() {
return buffer;
}
/**
* @param buffer The buffer to set.
*/
public void setBuffer(ReadBuffer buffer) {
this.buffer = buffer;
}
public String getTransferEncoding() { public String getTransferEncoding() {
// TODO Auto-generated method stub
return transferEncoding; return transferEncoding;
} }
public String getContentType() { public String getContentType() {
// TODO Auto-generated method stub
return contentType; return contentType;
} }
/**
* @param contentType The contentType to set.
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* @param transferEncoding The transferEncoding to set.
*/
public void setTransferEncoding(String transferEncoding) {
this.transferEncoding = transferEncoding;
}
public void setData(String data ) {
this.data = data;
}
/** /**
* @return Returns the data. * @return Returns the data.
*/ */

View File

@ -53,7 +53,7 @@ class MailCache {
/** Includes header, headers are generally 1KB to 1.5 KB, /** Includes header, headers are generally 1KB to 1.5 KB,
* and bodies will compress well. * and bodies will compress well.
*/ */
private static final int FETCH_ALL_SIZE = 4096; private static final int FETCH_ALL_SIZE = 8192;
/** /**
* @param mailbox non-null * @param mailbox non-null
@ -137,14 +137,14 @@ class MailCache {
mail.setHeader(mailbox.getHeader(uidl)); mail.setHeader(mailbox.getHeader(uidl));
} else { } else {
if(!mail.hasBody()) { if(!mail.hasBody()) {
mail.setBody(mailbox.getBody(uidl)); ReadBuffer rb = mailbox.getBody(uidl);
} if (rb != null) {
} mail.setBody(rb);
if (disk != null) { if (disk != null && disk.saveMail(mail) &&
if (disk.saveMail(mail) && mail.hasBody() && !Boolean.parseBoolean(Config.getProperty(WebMail.CONFIG_LEAVE_ON_SERVER))) {
false && // TO ENABLE mailbox.queueForDeletion(mail.uidl);
!Boolean.parseBoolean(Config.getProperty(WebMail.CONFIG_LEAVE_ON_SERVER))) { }
mailbox.queueForDeletion(mail.uidl); }
} }
} }
return mail; return mail;
@ -237,7 +237,6 @@ class MailCache {
rv = true; rv = true;
if (disk != null) { if (disk != null) {
if (disk.saveMail(mail) && mail.hasBody() && if (disk.saveMail(mail) && mail.hasBody() &&
false && // TO ENABLE
!Boolean.parseBoolean(Config.getProperty(WebMail.CONFIG_LEAVE_ON_SERVER))) { !Boolean.parseBoolean(Config.getProperty(WebMail.CONFIG_LEAVE_ON_SERVER))) {
mailbox.queueForDeletion(mail.uidl); mailbox.queueForDeletion(mail.uidl);
} }

View File

@ -934,8 +934,13 @@ public class WebMail extends HttpServlet
*/ */
String uidl = null; String uidl = null;
if( sessionObject.state == STATE_LIST ) { if( sessionObject.state == STATE_LIST ) {
int pos = getCheckedMessage( request ); // these buttons are now hidden on the folder page,
uidl = sessionObject.folder.getElementAtPosXonCurrentPage( pos ); // but the idea is to use the first checked message
List<Integer> items = getCheckedItems(request);
if (!items.isEmpty()) {
int pos = items.get(0).intValue();
uidl = sessionObject.folder.getElementAtPosXonCurrentPage( pos );
}
} }
else { else {
uidl = sessionObject.showUIDL; uidl = sessionObject.showUIDL;
@ -1067,26 +1072,26 @@ public class WebMail extends HttpServlet
} }
} }
} }
/** /**
* Returns e.g. 3,5 for ?check3=1&check5=1 (or POST equivalent)
* @param request * @param request
* @return message number or -1 * @return non-null
*/ */
private static int getCheckedMessage(RequestWrapper request) { private static List<Integer> getCheckedItems(RequestWrapper request) {
List<Integer> rv = new ArrayList<Integer>(8);
for( Enumeration<String> e = request.getParameterNames(); e.hasMoreElements(); ) { for( Enumeration<String> e = request.getParameterNames(); e.hasMoreElements(); ) {
String parameter = e.nextElement(); String parameter = e.nextElement();
if( parameter.startsWith( "check" ) && request.getParameter( parameter ).equals("1")) { if( parameter.startsWith( "check" ) && request.getParameter( parameter ).equals("1")) {
String number = parameter.substring( 5 ); String number = parameter.substring( 5 );
try { try {
int n = Integer.parseInt( number ); rv.add(Integer.valueOf(number));
return n; } catch( NumberFormatException nfe ) {}
}
catch( NumberFormatException nfe ) {
}
} }
} }
return -1; return rv;
} }
/** /**
* @param sessionObject * @param sessionObject
* @param request * @param request
@ -1136,8 +1141,6 @@ public class WebMail extends HttpServlet
if( l > 0 ) { if( l > 0 ) {
byte buf[] = new byte[l]; byte buf[] = new byte[l];
in.read( buf ); in.read( buf );
Attachment attachment = new Attachment();
attachment.setFileName( filename );
String contentType = request.getContentType( NEW_FILENAME ); String contentType = request.getContentType( NEW_FILENAME );
Encoding encoding; Encoding encoding;
String encodeTo; String encodeTo;
@ -1148,12 +1151,12 @@ public class WebMail extends HttpServlet
encoding = EncodingFactory.getEncoding( encodeTo ); encoding = EncodingFactory.getEncoding( encodeTo );
try { try {
if( encoding != null ) { if( encoding != null ) {
attachment.setData( encoding.encode( buf ) ); String data = encoding.encode(buf);
attachment.setTransferEncoding( encodeTo );
attachment.setContentType( contentType );
if( sessionObject.attachments == null ) if( sessionObject.attachments == null )
sessionObject.attachments = new ArrayList<Attachment>(); sessionObject.attachments = new ArrayList<Attachment>();
sessionObject.attachments.add( attachment ); sessionObject.attachments.add(
new Attachment(filename, contentType, encodeTo, data)
);
} }
else { else {
sessionObject.error += _("No Encoding found for {0}", encodeTo) + "<br>"; sessionObject.error += _("No Encoding found for {0}", encodeTo) + "<br>";
@ -1170,22 +1173,13 @@ public class WebMail extends HttpServlet
} }
} }
else if( sessionObject.attachments != null && buttonPressed( request, DELETE_ATTACHMENT ) ) { else if( sessionObject.attachments != null && buttonPressed( request, DELETE_ATTACHMENT ) ) {
for( Enumeration<String> e = request.getParameterNames(); e.hasMoreElements(); ) { for (Integer item : getCheckedItems(request)) {
String parameter = e.nextElement(); int n = item.intValue();
if( parameter.startsWith( "check" ) && request.getParameter( parameter ).equals("1")) { for( int i = 0; i < sessionObject.attachments.size(); i++ ) {
String number = parameter.substring( 5 ); Attachment attachment = (Attachment)sessionObject.attachments.get( i );
try { if( attachment.hashCode() == n ) {
int n = Integer.parseInt( number ); sessionObject.attachments.remove( i );
for( int i = 0; i < sessionObject.attachments.size(); i++ ) { break;
Attachment attachment = (Attachment)sessionObject.attachments.get( i );
if( attachment.hashCode() == n ) {
sessionObject.attachments.remove( i );
break;
}
}
}
catch( NumberFormatException nfe ) {
} }
} }
} }
@ -1331,8 +1325,8 @@ public class WebMail extends HttpServlet
sessionObject.folder.lastPage(); sessionObject.folder.lastPage();
} }
else if( buttonPressed( request, DELETE ) ) { else if( buttonPressed( request, DELETE ) ) {
int m = getCheckedMessage( request ); int m = getCheckedItems(request).size();
if( m != -1 ) if (m > 0)
sessionObject.reallyDelete = true; sessionObject.reallyDelete = true;
else else
sessionObject.error += _("No messages marked for deletion.") + "<br>"; sessionObject.error += _("No messages marked for deletion.") + "<br>";
@ -1340,17 +1334,11 @@ public class WebMail extends HttpServlet
else { else {
if( buttonPressed( request, REALLYDELETE ) ) { if( buttonPressed( request, REALLYDELETE ) ) {
List<String> toDelete = new ArrayList<String>(); List<String> toDelete = new ArrayList<String>();
for( Enumeration<String> e = request.getParameterNames(); e.hasMoreElements(); ) { for (Integer item : getCheckedItems(request)) {
String parameter = e.nextElement(); int n = item.intValue();
if( parameter.startsWith( "check" ) && request.getParameter( parameter ).equals("1")) { String uidl = sessionObject.folder.getElementAtPosXonCurrentPage( n );
String number = parameter.substring( 5 ); if( uidl != null )
try { toDelete.add(uidl);
int n = Integer.parseInt( number );
String uidl = sessionObject.folder.getElementAtPosXonCurrentPage( n );
if( uidl != null )
toDelete.add(uidl);
} catch( NumberFormatException nfe ) {}
}
} }
int numberDeleted = toDelete.size(); int numberDeleted = toDelete.size();
if (numberDeleted > 0) { if (numberDeleted > 0) {
@ -1987,16 +1975,13 @@ public class WebMail extends HttpServlet
*/ */
private static void showFolder( PrintWriter out, SessionObject sessionObject, RequestWrapper request ) private static void showFolder( PrintWriter out, SessionObject sessionObject, RequestWrapper request )
{ {
if( sessionObject.reallyDelete ) {
out.println( "<p class=\"error\">" + _("Really delete the marked messages?") + " " + button( REALLYDELETE, _("Yes, really delete them!") ) + "</p>" );
}
out.println( button( NEW, _("New") ) + spacer + out.println( button( NEW, _("New") ) + spacer +
// In theory, these are valid and will apply to the first checked message, // In theory, these are valid and will apply to the first checked message,
// but that's not obvious and did it work? // but that's not obvious and did it work?
//button( REPLY, _("Reply") ) + //button( REPLY, _("Reply") ) +
//button( REPLYALL, _("Reply All") ) + //button( REPLYALL, _("Reply All") ) +
//button( FORWARD, _("Forward") ) + spacer + //button( FORWARD, _("Forward") ) + spacer +
button( DELETE, _("Delete") ) + spacer + //button( DELETE, _("Delete") ) + spacer +
button( REFRESH, _("Check Mail") ) + spacer); button( REFRESH, _("Check Mail") ) + spacer);
if (Config.hasConfigFile()) if (Config.hasConfigFile())
out.println(button( RELOAD, _("Reload Config") ) + spacer); out.println(button( RELOAD, _("Reload Config") ) + spacer);
@ -2006,14 +1991,14 @@ public class WebMail extends HttpServlet
out.println( out.println(
"<br>" + "<br>" +
( sessionObject.folder.isFirstPage() ? ( sessionObject.folder.isFirstPage() ?
button2( FIRSTPAGE, _("First") ) + button2( PREVPAGE, _("Previous") ) : button2( FIRSTPAGE, _("First") ) + "&nbsp;" + button2( PREVPAGE, _("Previous") ) :
button( FIRSTPAGE, _("First") ) + button( PREVPAGE, _("Previous") ) ) + button( FIRSTPAGE, _("First") ) + "&nbsp;" + button( PREVPAGE, _("Previous") ) ) +
" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
_("Page {0} of {1}", sessionObject.folder.getCurrentPage(), sessionObject.folder.getPages()) + _("Page {0} of {1}", sessionObject.folder.getCurrentPage(), sessionObject.folder.getPages()) +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " +
( sessionObject.folder.isLastPage() ? ( sessionObject.folder.isLastPage() ?
button2( NEXTPAGE, _("Next") ) + button2( LASTPAGE, _("Last") ) : button2( NEXTPAGE, _("Next") ) + "&nbsp;" + button2( LASTPAGE, _("Last") ) :
button( NEXTPAGE, _("Next") ) + button( LASTPAGE, _("Last") ) ) button( NEXTPAGE, _("Next") ) + "&nbsp;" + button( LASTPAGE, _("Last") ) )
); );
} }
@ -2078,17 +2063,33 @@ public class WebMail extends HttpServlet
} }
if (i == 0) if (i == 0)
out.println("<tr><td colspan=\"9\" align=\"center\"><i>" + _("No messages") + "</i></td></tr>\n</table>"); out.println("<tr><td colspan=\"9\" align=\"center\"><i>" + _("No messages") + "</i></td></tr>\n</table>");
out.println( "<tr><td colspan=\"9\"><hr></td></tr>\n</table>");
if (i > 0) { if (i > 0) {
out.println( out.println( "<tr><td colspan=\"9\"><hr></td></tr>");
button( MARKALL, _("Mark All") ) + out.println("<tr><td colspan=\"5\" align=\"left\">");
button( INVERT, _("Invert Selection") ) + if( sessionObject.reallyDelete ) {
button( CLEAR, _("Clear") ) + // TODO ngettext
"<br>"); out.println("<p class=\"error\">" + _("Really delete the marked messages?") +
out.println( "</p>" + button( REALLYDELETE, _("Yes, really delete them!") ) +
"<br>" + button( CLEAR, _("Cancel")));
} else {
// TODO js
out.println(button( DELETE, _("Delete Selected") ) + "<br>");
out.print(
button( CLEAR, _("Clear All") ) +
"&nbsp;" +
button( MARKALL, _("Mark All") ));
//"<br>" +
//button( INVERT, _("Invert Selection") ) +
//"<br>");
}
out.print("</td>\n<td colspan=\"4\" align=\"right\">");
out.print(
_("Page Size") + ":&nbsp;<input type=\"text\" style=\"text-align: right;\" name=\"" + PAGESIZE + "\" size=\"4\" value=\"" + sessionObject.folder.getPageSize() + "\">" + _("Page Size") + ":&nbsp;<input type=\"text\" style=\"text-align: right;\" name=\"" + PAGESIZE + "\" size=\"4\" value=\"" + sessionObject.folder.getPageSize() + "\">" +
"&nbsp;" +
button( SETPAGESIZE, _("Set") ) ); button( SETPAGESIZE, _("Set") ) );
out.println("</td>");
} }
out.println( "</table>");
} }
/** /**
* *

View File

@ -1,3 +1,15 @@
2014-04-25 zzz
* SusiMail:
- Add icons for new messages, attachments, and spam
- Different colors for new mail and spam
- Tweak sort button display based on current sort
- Display image attachments inline
- Don't rezip certain attachment types, just offer link
- Move delete and confirmation buttons
- Increase max size for full download again
- Fix repeated re-saves of mail to disk
- Enable auto-deletion of downloaded mails
2014-04-24 zzz 2014-04-24 zzz
* SusiMail: * SusiMail:
- Add background mail checker - Add background mail checker

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 11; public final static long BUILD = 12;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";