Message reading navigation, enable tagging a specific message area

This commit is contained in:
Deon George 2022-12-15 23:28:25 +11:00
parent e7b9ed73d0
commit ab91db2efa
8 changed files with 125 additions and 21 deletions

View File

@ -1,6 +1,6 @@
load('load/string.js');
load('load/funcs.js');
load('ansitex/load/msgbases.js');
if (argv.length !== 1) {
writeln('ERROR: Need a msgbase page prefix');

View File

@ -1,5 +1,6 @@
/**
* Go through our messages and tag a frame id for messages without one.
* @note: May need to run jsexec with -m 32MB to overcome memory issues
*/
load('load/string.js');
@ -7,6 +8,9 @@ load('ansitex/load/msgbases.js');
const ma = new MsgAreas()
for (var i=0;i<ma.areas.length;i++) {
if (argv[0] && (argv[0] !== ma.areas[i].msgbase.cfg.code))
continue;
writeln('Area : '+ma.areas[i].full_name);
writeln('Total Messages : '+ma.areas[i].headers.length);
writeln('- Tagged Messages : '+ma.areas[i].list_tagged.length);

View File

@ -59,9 +59,6 @@ function echomail(page) {
pageframe.scroll(0,-1);
read = '';
break;
case '*':
break;
}
pageframe.cycle();

View File

@ -45,7 +45,7 @@ function FrameAnsi() {
this.settings.LOGIN_ERROR = '\1n\1h\1RERROR LOGGING IN, PLEASE TRY AGAIN *00';
this.settings.CANCEL_MSG = '\1n\1h\1GPRESS 2 TO CANCEL';
this.settings.SYS_ERROR = '\1n\1h\1RSYSTEM ERROR DETECTED - TRY AGAIN OR TELL US *08';
this.settings.LOADING = '\1n\1h\1Wloading...';
this.settings.LOADING = '\1n\1h\1Kloading...';
/**
* Set the attribute at the current position

View File

@ -194,6 +194,7 @@ PageFrame.prototype.loadMessage = function(page) {
this.isAccessible = true;
// @todo Keys should map to next/previous/send, etc as indicated in the template frame.
this.key = [this.frame.substr(0,7)+'1',null,null,null,null,null,null,null,null,null];
// @todo validate that FRAME_TYPE_MESSAGE is a message template
this.type = FRAME_TYPE_MESSAGE;
// Load our message
@ -242,30 +243,54 @@ PageFrame.prototype.loadMessage = function(page) {
// if this message is to the user, and the msg number > scan_ptr and it is the next message on the user's new mail list
var newmsgs = area.newMsgsToMe();
var next;
log(LOG_DEBUG,'User has: '+newmsgs.length+' msgs to read to ME');
if (newmsgs.length) {
var next = newmsgs[0];
next = newmsgs[1];
log(LOG_DEBUG,'- NEXT is: '+next.tags+', this is: '+msg.tags);
//log(LOG_DEBUG,'- NEXT is: '+next.tags+', this is: '+msg.tags);
if (next.tags === msg.tags) {
log(LOG_DEBUG,'- Updating scan_ptr to: '+next.number);
stats.scan_ptr = next.number;
}
// Last message
next = newmsgs[0];
log(LOG_DEBUG,'- LAST TO ME is: '+next.tags);
if (next !== undefined) {
this.key[1] = area.page(next.tags);
}
// Next new message
next = newmsgs[2];
log(LOG_DEBUG,'- NEXT TO ME is: '+next.tags);
if (next !== undefined)
this.key[2] = area.page(next.tags);
}
// if this message is the next message, update last_read
var newmsgs = area.newMsgs();
newmsgs = area.newMsgs();
log(LOG_DEBUG,'User has: '+newmsgs.length+' msgs to read');
if (newmsgs.length) {
var next = newmsgs[0];
next = newmsgs[0];
log(LOG_DEBUG,'- NEXT is: '+next.tags+', this is: '+msg.tags);
//log(LOG_DEBUG,'- NEXT is: '+next.tags+', this is: '+msg.tags);
if (next.tags === msg.tags) {
log(LOG_DEBUG,'- Updating last_read to: '+next.number);
stats.last_read = next.number;
}
}
// Previous Message
x = area.MessagePrev(this.frame);
if (x)
this.key[4] = area.page(x.tags);
// Next Message
x = area.MessageNext(this.frame);
if (x)
this.key[6] = area.page(x.tags);
log(LOG_DEBUG,'Built frame: ['+this.frame+']['+this.index+'] ('+this.page+')');
}

View File

@ -217,7 +217,7 @@ function atcode(field,length,pad,context) {
var x = context.newMsgsToMe();
result = x.length ? x.shift().date : '';
result = x.length > 1 ? x[1].date : '';
break;
case 'msg_area_msgtome_page':
@ -227,7 +227,7 @@ function atcode(field,length,pad,context) {
}
var x = context.newMsgsToMe();
return x.length ? context.getMessagePage(x.shift().number) : null;
return x.length > 1 ? context.getMessagePage(x[1].number) : null;
// Count of unread messages
case 'msg_area_new':
@ -251,7 +251,7 @@ function atcode(field,length,pad,context) {
break;
}
result = ''+context.newMsgsToMe().length;
result = ''+(context.newMsgsToMe().length > 1 ? context.newMsgsToMe().length-1 : 0);
break;
// Is this message area in my new scan list

View File

@ -63,8 +63,12 @@ function MsgArea() {
try {
if (this.msgbase.open()) {
// @todo If there are more than 10,000, take only the last 10,000.
this.headers = this.msgbase.get_all_msg_headers(false,false) || [];
headers = this.msgbase.get_all_msg_headers(false,false) || [];
// Just take the last MAX_MESSAGES
this.headers = Object.keys(headers).slice(-(MAX_PAGE_NUM+1)).map(function(key) { return headers[key]; });
headers = undefined;
this.msgbase.close();
} else {
@ -76,8 +80,6 @@ function MsgArea() {
log(LOG_ERROR,code+' cannot be opened:'+e.message);
this.headers = [];
}
log(LOG_DEBUG,'msgbase:'+JSON.stringify(this.msgbase));
}
});
@ -166,7 +168,8 @@ function MsgArea() {
}
/**
* Unread messages
* Unread messages [1..]
* Array key 0 returns the last read message
*
* @returns {*[]}
*/
@ -194,12 +197,21 @@ MsgArea.prototype.newMsgs = function() {
MsgArea.prototype.newMsgsToMe = function() {
var msgs = [];
var stats = this.getUserStats();
var last = null;
//log(LOG_DEBUG,'Users scan_ptr pointer: '+JSON.stringify(stats.scan_ptr));
for(var x in this.list_tagged) {
// Advance past our last scan_ptr
if (this.list_tagged[x].number <= stats.scan_ptr)
if (this.list_tagged[x].number <= stats.scan_ptr) {
if ((this.list_tagged[x].to === user.name) || (this.list_tagged[x].to === user.alias))
last = x;
continue;
}
// Add our previous to me message
if (msgs.length === 0)
msgs.push(last !== null ? this.list_tagged[last] : []);
if ((this.list_tagged[x].to === user.name) || (this.list_tagged[x].to === user.alias))
msgs.push(this.list_tagged[x]);
@ -270,15 +282,77 @@ MsgArea.prototype.getUserStats = function() {
return this.msgbase.cfg ? msg_area.grp_list[this.msgbase.cfg.grp_number].sub_list[msg_area.sub[this.msgbase.cfg.code].index] : [];
}
MsgArea.prototype.MessageNext = function(page) {
var x = null;
if (! page)
return undefined;
var msgid = page.substr(7,4);
for(x in this.list_tagged) {
if (this.list_tagged[x].tags === msgid) {
break;
}
write(); // @todo This is needed for this to work?
}
//log(LOG_DEBUG,'- Next Message is:'+JSON.stringify(this.list_tagged[(parseInt(x)+1)])+', msgid:'+msgid+', page:'+page+', x:'+x);
/*
= Our next message is either
+ x+1 if x < this.list_tagged.length
+ x=0 if x == this.list_tagged.length (-1)
+ null if this.list_tagged.length == null; (thus no messages)
*/
return x === null ? null : this.list_tagged[(parseInt(x) === this.list_tagged.length-1) ? 0 : (parseInt(x)+1)];
}
MsgArea.prototype.MessagePrev = function(page) {
var prev = null;
var x = null;
if (! page)
return undefined;
var msgid = page.substr(7,4);
for(x in this.list_tagged) {
if (this.list_tagged[x].tags === msgid) {
break;
} else {
prev = x;
}
write(); // @todo This is needed for this to work?
}
/*
= Our previous message is either
+ prev if a tag was found, unless
+ prev is null, in which case it is this.list_tagged.length -1
+ null if x is still null (thus no messages)
*/
// If prev is still null, then our last message must be the last one, unless x is null then there are no messages
return x === null ? null : this.list_tagged[(prev === null) ? this.list_tagged.length-1 : parseInt(prev)];
}
/**
* Tag messages with a frame number
* @note: May need to run jsexec with -m 32MB to overcome memory issues
*
* @returns {boolean}
*/
MsgArea.prototype.tag_msgs = function() {
var msgs = this.list_untagged;
// See if we need to something
writeln("We have "+msgs.length+" messages to tag.");
// See if we need to tag something
if (! msgs.length)
return;
@ -308,6 +382,10 @@ MsgArea.prototype.tag_msgs = function() {
return true;
}
MsgArea.prototype.page = function(msgid) {
return '1'+this.page_prefix+msgid;
}
MsgAreas.prototype.getArea = function(area) {
log(LOG_DEBUG,'- AREA:'+JSON.stringify(area));
if (area === undefined)

View File

@ -1 +1 @@
{"version":1,"frame":198,"index":"a","owner":1,"cost":0,"content":"G1swbRtbNzZDG1sxbS4bWzBtDQogG1szM20bWG1zZ19ncnBfbmFtZTs0MBtcG1szMEMbWzM3bRtbMW3awr/Cv7+zG1swbQ0KIBtbMzZtG1htc2dfYXJlYV9hcmVhdGFnOzQwG1wbWzMwQxtbMzdtsyCzwrSzsw0KIBtbMTszNm0bWG1zZ19hcmVhX2Rlc2M7NDAbXBtbMzBDG1sxOzM3bVN1bW1hcnkbWzBtDQobWzE7MzBtxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSzxMTExMTExMTExMTExMTExMTExMTExMTExMTExBtbMG0NCiAbWERBVEVUSU1FOzI0G1wbWzI1QxtbMTszMG2zG1swbSAbWzFtTmV3IE1lc3NhZ2VzIHRvIFlvdRtbMG06IBtbMTszMW0bWG1zZ19hcmVhX25ld3RvbWU7LTUbXBtbMG0NChtbNTBDG1sxOzMwbbMbWzBtICAgICAbWzFtVW5yZWFkIE1lc3NhZ2VzG1swbTogG1sxOzMxbRtYbXNnX2FyZWFfbmV3Oy01G1wbWzBtDQogG1sxOzMybTEbWzM3bSBGaXJzdCB0byB5b3UgICAbWzM0bRtYbXNnX2FyZWFfbXNnb3RvbWVfZGF0ZTszMRtcG1swbSAbWzE7MzBtsxtbMG0gICAgICAbWzFtVG90YWwgTWVzc2FnZXMbWzBtOiAbWzE7MzFtG1htc2dfYXJlYV90b3RhbDstNRtcG1swbQ0KIBtbMTszMm0yG1swbSAbWzFtRmlyc3QgdW5yZWFkICAgG1sxOzM0bRtYbXNnX2FyZWFfbXNndW5yZWFkX2RhdGU7MzEbXBtbMG0gG1sxOzMwbbMbWzBtDQobWzUwQxtbMTszMG2zG1swbSAgICBQZW5kaW5nIE1lc3NhZ2VzOiAbWzMxbRtYbXNnX2FyZWFfcGVuZGluZzstNRtcG1szN20NCiAbWzE7MzJtMyAbWzM3bU9sZGVzdCBNZXNzYWdlIBtbMzRtG1htc2dfYXJlYV9tc2dvbGRlc3RfZGF0ZTszMRtcG1szN20gG1sxOzMwbbMbWzBtDQogG1sxOzMybTQgG1szN21MYXRlc3QgTWVzc2FnZSAbWzM0bRtYbXNnX2FyZWFfbXNnbmV3ZXN0X2RhdGU7MzEbXBtbMzdtIBtbMTszMG2zG1swbSAgICAgICAgICAbWzMybTkbWzBtIE5ldyBTY2FuOiAgIBtbMTszMm0bWG1zZ19hcmVhX25ld3NjYW47LTMbXBtbMG0NChtbNTBDG1sxOzMwbcEbWzBtDQogG1szMm01G1sxbSAbWzBtV3JpdGUgTmV3IE1lc3NhZ2UgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzQ0bdXNzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NzbgbWzBtDQogG1szMm02G1sxbSAbWzBtU2VhcmNoIGZvciBNZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzQ0bbMbWzMzbSCvIE1lc3NhZ2UgUmVhZGluZyBOYXZpZ2F0aW9uIK4bWzA7MzM7NDRtIBtbMTszN22zG1swbQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzQ0bbMbWzMzbSAbWzMybRgbWzM2bSBTY3JvbGwgVVAgG1swOzQ0bSAgG1sxbbMbWzA7NDRtIBtbMTszMm0ZG1szNm0gU2Nyb2xsIERPV04bWzA7NDRtIBtbMTszM20gG1szN22zG1swbQ0KIBtbMzJtOBtbMzdtIEFyZWEgU3VtbWFyeSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTs0NG2zG1szM20gG1swOzMyOzQ0bTQbWzE7MzZtIBtbMDszNjs0NG1QcmV2aW91cxtbMW0gIBtbMDs0NG0gIBtbMW2zG1swOzQ0bSAbWzMybTMbWzE7MzZtIBtbMDszNjs0NG1QcmV2IFRocmVhZBtbMzdtIBtbMTszM20gG1szN22zG1swbQ0KIBtbMTszMm0wG1swOzMybSAbWzE7MzdtQXJlYSBEZXNjcmlwdGlvbiAgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzQ0bbMbWzMzbSAbWzA7MzI7NDRtNhtbMTszNm0gG1swOzM2OzQ0bU5leHQbWzFtIBtbMDs0NG0gICAgICAgG1sxbbMbWzA7NDRtIBtbMzJtNxtbMzdtIBtbMzZtTmV4dCBUaHJlYWQbWzM3bSAbWzE7MzNtIBtbMzdtsxtbMG0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTs0NG2zG1swOzQ0bSAbWzMybTUbWzM3bSAbWzM2bVdyaXRlIE5ldxtbMzdtICAgG1sxbbMbWzA7NDRtIBtbMzJtOBtbMzdtIBtbMzZtUmVwbHkbWzM3bSAgICAgICAbWzE7MzNtIBtbMzdtsxtbMG0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTs0NG2zG1swOzQ0bSAbWzMybSMbWzM3bSAbWzM2bU1zZyBBdHRycyAgG1szN20gG1sxbbMbWzA7NDRtIBtbMTszMm0wG1szN20gG1sxOzM2bVJldHVybiBoZXJlG1szN20gG1sxOzMzbSAbWzM3bbMbWzBtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzE7NDRt1M3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NvhtbMG0NCg==","isPublic":0,"isAccessible":1,"type":"m","key":[null,null,null,null,null,null,null,null,null,null],"date":"2022-04-29T00:00:00.000Z"}
{"version":1,"frame":198,"index":"a","owner":1,"cost":0,"content":"G1swbRtbNzZDG1sxbS4bWzBtDQogG1szM20bWG1zZ19ncnBfbmFtZTs0MBtcG1szMEMbWzM3bRtbMW3awr/Cv7+zG1swbQ0KIBtbMzZtG1htc2dfYXJlYV9hcmVhdGFnOzQwG1wbWzMwQxtbMzdtsyCzwrSzsw0KIBtbMTszNm0bWG1zZ19hcmVhX2Rlc2M7NDAbXBtbMzBDG1sxOzM3bVN1bW1hcnkbWzBtDQobWzE7MzBtxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSzxMTExMTExMTExMTExMTExMTExMTExMTExMTExBtbMG0NCiAbWERBVEVUSU1FOzI0G1wbWzI1QxtbMTszMG2zG1swbSAbWzFtTmV3IE1lc3NhZ2VzIHRvIFlvdRtbMG06IBtbMTszMW0bWG1zZ19hcmVhX25ld3RvbWU7LTUbXBtbMG0NChtbNTBDG1sxOzMwbbMbWzBtICAgICAbWzFtVW5yZWFkIE1lc3NhZ2VzG1swbTogG1sxOzMxbRtYbXNnX2FyZWFfbmV3Oy01G1wbWzBtDQogG1sxOzMybTEbWzM3bSBGaXJzdCB0byB5b3UgICAbWzM0bRtYbXNnX2FyZWFfbXNnb3RvbWVfZGF0ZTszMRtcG1swbSAbWzE7MzBtsxtbMG0gICAgICAbWzFtVG90YWwgTWVzc2FnZXMbWzBtOiAbWzE7MzFtG1htc2dfYXJlYV90b3RhbDstNRtcG1swbQ0KIBtbMTszMm0yG1swbSAbWzFtRmlyc3QgdW5yZWFkICAgG1sxOzM0bRtYbXNnX2FyZWFfbXNndW5yZWFkX2RhdGU7MzEbXBtbMG0gG1sxOzMwbbMbWzBtDQobWzUwQxtbMTszMG2zG1swbSAgICBQZW5kaW5nIE1lc3NhZ2VzOiAbWzMxbRtYbXNnX2FyZWFfcGVuZGluZzstNRtcG1szN20NCiAbWzE7MzJtMyAbWzM3bU9sZGVzdCBNZXNzYWdlIBtbMzRtG1htc2dfYXJlYV9tc2dvbGRlc3RfZGF0ZTszMRtcG1szN20gG1sxOzMwbbMbWzBtDQogG1sxOzMybTQgG1szN21MYXRlc3QgTWVzc2FnZSAbWzM0bRtYbXNnX2FyZWFfbXNnbmV3ZXN0X2RhdGU7MzEbXBtbMzdtIBtbMTszMG2zG1swbSAgICAgICAgICAbWzMybTkbWzBtIE5ldyBTY2FuOiAgIBtbMTszMm0bWG1zZ19hcmVhX25ld3NjYW47LTMbXBtbMG0NChtbNTBDG1sxOzMwbcEbWzBtDQogG1szMm01G1sxbSAbWzBtV3JpdGUgTmV3IE1lc3NhZ2UgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzQ0bdXNzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NzbgbWzBtDQogG1szMm02G1sxbSAbWzBtU2VhcmNoIGZvciBNZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzQ0bbMbWzMzbSCvIE1lc3NhZ2UgUmVhZGluZyBOYXZpZ2F0aW9uIK4gG1sxOzM3bbMbWzBtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzE7NDRtsyAbWzMybRgbWzM2bSBTY3JvbGwgVVAgG1swOzQ0bSAgG1sxbbMbWzA7NDRtIBtbMTszMm0ZG1szNm0gU2Nyb2xsIERPV04bWzA7NDRtIBtbMTszM20gG1szN22zG1swbQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgG1sxOzQ0bbMgG1szMm0xG1szNm0gUHJldiBUbyBNZSAgG1sxOzMzbbMbWzA7NDRtIBtbMTszMm0yG1szNm0gTmV4dCBUbyBNZSAgG1szM20gG1szN22zG1swbQ0KIBtbMzJtOBtbMzdtIEFyZWEgU3VtbWFyeSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTs0NG2zG1szM20gG1szMm00IBtbMzZtUHJldmlvdXMgICAgG1sxOzMzbbMbWzA7NDRtIBtbMzJtMxtbMTszNm0gG1swOzM2OzQ0bVByZXYgVGhyZWFkG1szN20gG1sxOzMzbSAbWzM3bbMbWzBtDQogG1sxOzMybTAbWzA7MzJtIBtbMTszN21BcmVhIERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAbWzE7NDRtsxtbMzNtIBtbMzJtNhtbMzZtIE5leHQbWzFtIBtbMDs0NG0gICAgICAgG1sxbbMbWzA7NDRtIBtbMzJtNxtbMzdtIBtbMzZtTmV4dCBUaHJlYWQbWzM3bSAbWzE7MzNtIBtbMzdtsxtbMG0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTs0NG2zG1swOzQ0bSAbWzMybTUbWzM3bSAbWzM2bVdyaXRlIE5ldxtbMzdtICAgG1sxbbMbWzA7NDRtIBtbMzJtOBtbMzdtIBtbMzZtUmVwbHkbWzM3bSAgICAgICAbWzE7MzNtIBtbMzdtsxtbMG0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIBtbMTs0NG2zG1swOzQ0bSAbWzMybSMbWzM3bSAbWzM2bU1zZyBBdHRycyAgG1szN20gG1sxbbMbWzA7NDRtIBtbMTszMm0wG1szN20gG1sxOzM2bVJldHVybiBoZXJlG1szN20gG1sxOzMzbSAbWzM3bbMbWzBtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzE7NDRt1M3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NvhtbMG0NCg==","isPublic":0,"isAccessible":1,"type":"m","key":[null,null,null,null,null,null,null,null,null,null],"date":"2022-04-29T00:00:00.000Z"}