tkMOO-light

Experimental Mail Reader Application

This is a first-pass at trying to understand what would be needed to build a GUI to the MOO mail system on JHCore. The GUI takes the form of 3 scrollable windows, at the top is the list of folders that the player can subscribe to, in the middle is the list of messages in the selected folder and at the bottom is the selected message.

To simplify matters, little if any stateful information is passed between server and client. Clicking on any line in the folders or messages windows invokes a verb defined on the player which causes the server to send back relevant information. The client responds to the server's XMCP/1.1 messages by displaying new information in one of the 3 windows.

Clicking on one of the folders issues the command @xmcp-messages on #folder. Clicking on one of the messages issues the command @xmcp-message on #folder. @xmcp-message is analogous to MOO's @peek command, that is the contents of a message can be viewed but no attempt is made to update the server side state of the folder being read.

The client is able to cache information received from the server. Once a message has been read any subsequent visits to the same message result in the display being refreshed from the cache. There is also scope for backgrounding download (uugh, jargon), that is, the client might chose to download the several messages following the current message while the user is still reading the current message. The user will then be able to select the next message in the sequence with no appreciable delay since the next message will have already been cached in the client.

Server-side verbs

@program me:@xmail-folders none none none
folders = {player, @player.mail_lists, @$mail_agent.contents};
kv = {};
lines = {};
for f in (folders)
  if ((f == player) || ((f:is_usable_by(this) || f:is_readable_by(this)) && f:subscribed(this)))
    folder = f;
    len = f:length_all_msgs();
    foldersum = tostr(f.name, " ", len, " message", (len == 1) ? "" | "s");
    line = tostr("folder: ", folder, " foldersum: ", $string_utils:print(foldersum));
    lines = {@lines, line};
  endif
endfor
player.xdr2:client_notify(player, "xmail-folders", kv, lines);
.

@program me:@xmail-messages any any any
sequence_info = player:parse_mailread_cmd("@mail", args, "last:15", "on");
if (!sequence_info)
  return;
endif
folder = sequence_info[1];
seq = sequence_info[2];
last = sequence_info[3];
messages = folder:messages_in_seq(seq);
kv = {};
kv = {@kv, {"folder", tostr(folder)}};
kv = {@kv, {"last", tostr(last[2])}};
data = {};
for m in (messages)
  summary = player:msg_summary_line(@m[2]);
  msgtime = m[2][1];
  message_number = m[1];
  line = tostr("msgno: ", message_number, " msgtime: ", msgtime, " msgsum: ", $string_utils:print(summary));
  data = {@data, line};
endfor
player.xdr2:client_notify(player, "xmail-messages", kv, data);
.

@program me:@xmail-message any any any
p = this:parse_mailread_cmd("@read", args, "", "on");
folder = p[1];
seq = p[2];
msgs = folder:messages_in_seq(@seq);
lines = player:msg_text(@msgs[2]);
"fiiine so long as you only target one message at a time, and not ranges";
msgno = msgs[1];
kv = {};
kv = {@kv, {"folder", tostr(folder)}};
kv = {@kv, {"msgno", tostr(msgno)}};
data = {};
for line in (lines)
  text = tostr("text: ", $string_utils:print(line));
  data = {@data, text};
endfor
player.xdr2:client_notify(player, "xmail-message", kv, data);
.