diff --git a/xtrn/bullshit/bullshit.ini b/xtrn/bullshit/bullshit.ini new file mode 100644 index 0000000000000000000000000000000000000000..e020d38ef2cbe928e5e857391ad990534613121a --- /dev/null +++ b/xtrn/bullshit/bullshit.ini @@ -0,0 +1,13 @@ +; Internal code of the message area containing your bulletins +messageBase = BULLSHIT + +; See sbbsdefs.js for valid colors to specify here +titleColor = WHITE +headingColor = DARKGRAY +textColor = LIGHTGRAY +footerColor = WHITE +lightbarForeground = LIGHTCYAN +lightbarBackground = BG_CYAN +listForeground = LIGHTGRAY +; borderColor may be a comma-separated list if you want a gradient +borderColor = LIGHTBLUE,CYAN,LIGHTCYAN,LIGHTGRAY,WHITE diff --git a/xtrn/bullshit/bullshit.js b/xtrn/bullshit/bullshit.js new file mode 100644 index 0000000000000000000000000000000000000000..122297710047fe15ba0c9cfcf61142ee326db920 --- /dev/null +++ b/xtrn/bullshit/bullshit.js @@ -0,0 +1,186 @@ +load("sbbsdefs.js"); +load("frame.js"); +load("tree.js"); +load("scrollbar.js"); +load("funclib.js"); + +js.branch_limit = 0; + +var frame, + titleFrame, + listFrame, + footerFrame, + tree, + ini, + msgBase, + treeScroll; + +/* drawFrameBorder(frame, color, gradient) + Draws a border of color 'color' around Frame object 'frame' + If 'gradient' is true, 'color' must be an array of colors to draw in order + See sbbsdefs.js for valid colors */ +var drawFrameBorder = function(frame, color) { + var theColor = color; + if(color instanceof Array) + var sectionLength = Math.round(frame.width / color.length); + for(var y = 1; y <= frame.height; y++) { + for(var x = 1; x <= frame.width; x++) { + if(x > 1 && x < frame.width && y > 1 && y < frame.height) + continue; + var msg = false; + frame.gotoxy(x, y); + if(y == 1 && x == 1) + msg = ascii(218); + else if(y == 1 && x == frame.width) + msg = ascii(191); + else if(y == frame.height && x == 1) + msg = ascii(192); + else if(y == frame.height && x == frame.width) + msg = ascii(217); + else if(x == 1 || x == frame.width) + msg = ascii(179); + else + msg = ascii(196); + if(color instanceof Array) { + if(x == 1) + theColor = color[0]; + else if(x % sectionLength == 0 && x < frame.width) + theColor = color[x / sectionLength]; + else if(x == frame.width) + theColor = color[color.length - 1]; + } + frame.putmsg(msg, theColor); + } + } +} + +var showMsg = function(msg) { + try { + var readerFrame = new Frame(2, 5, console.screen_columns - 2, console.screen_rows - 8, BG_BLACK|WHITE, frame); + readerFrame.open(); + msgBase.open(); + var h = msgBase.get_msg_header(msg); + var b = msgBase.get_msg_body(msg); + msgBase.close(); + readerFrame.putmsg( + format( + "%-52s%s\r\n\r\n", + h.subject.substr(0, console.screen_columns - 30), + system.timestr(h.when_written_time) + ), + getColor(ini.titleColor) + ); + readerFrame.putmsg(word_wrap(b, console.screen_columns - 2), getColor(ini.textColor)); + readerFrame.scrollTo(0, 0); + var scroller = new ScrollBar(readerFrame, { autohide : true }); + scroller.open(); + scroller.cycle(); + } catch(err) { + log(LOG_ERR, err); + return false; + } + while(!js.terminated) { + if(frame.cycle()) { + scroller.cycle(); + console.gotoxy(console.screen_columns, console.screen_rows); + } + var userInput = console.inkey(K_NONE, 5); + if(userInput.toUpperCase() == "Q" || ascii(userInput) == 27) + break; + else if(userInput == KEY_UP && readerFrame.data_height > readerFrame.height) + readerFrame.scroll(0, -1); + else if(userInput == KEY_DOWN && readerFrame.data_height > readerFrame.height) + readerFrame.scroll(0, 1); + } + readerFrame.close(); + readerFrame.delete(); + return true; +} + +var init = function() { + try { + var f = new File(js.exec_dir + "bullshit.ini"); + f.open("r"); + ini = f.iniGetObject(); + f.close(); + ini.borderColor = ini.borderColor.toUpperCase().split(","); + if(ini.borderColor.length > 1) { + for(var b = 0; b < ini.borderColor.length; b++) + ini.borderColor[b] = getColor(ini.borderColor[b]); + } else { + ini.borderColor = getColor(ini.borderColor[0]); + } + ini.lightbarForeground = getColor(ini.lightbarForeground); + ini.lightbarBackground = getColor(ini.lightbarBackground); + + frame = new Frame(1, 1, console.screen_columns, console.screen_rows, BG_BLACK|WHITE); + titleFrame = new Frame(1, 1, console.screen_columns, 3, BG_BLACK|WHITE, frame); + listFrame = new Frame(1, 4, console.screen_columns, console.screen_rows - 6, BG_BLACK|WHITE, frame); + listTreeFrame = new Frame(2, 6, console.screen_columns - 2, console.screen_rows - 9, BG_BLACK|WHITE, listFrame); + footerFrame = new Frame(1, console.screen_rows - 2, console.screen_columns, 3, BG_BLACK|WHITE, frame); + drawFrameBorder(titleFrame, ini.borderColor); + drawFrameBorder(listFrame, ini.borderColor); + drawFrameBorder(footerFrame, ini.borderColor); + tree = new Tree(listTreeFrame); + tree.colors.lfg = ini.lightbarForeground; + tree.colors.lbg = ini.lightbarBackground; + + var titleLen = console.screen_columns - 29; + msgBase = new MsgBase(ini.messageBase); + msgBase.open(); + for(var m = msgBase.last_msg; m >= msgBase.first_msg; m = m - 1) { + try { + var h = msgBase.get_msg_header(m); + if(h === null) + throw "Header is null"; + tree.addItem( + format( + "%-" + titleLen + "s%s", + h.subject.substr(0, console.screen_columns - 29), + system.timestr(h.when_written_time) + ), + showMsg, + m + ); + } catch(err) { + continue; + } + } + msgBase.close(); + + titleFrame.gotoxy(3, 2); + titleFrame.putmsg("Bulletins", getColor(ini.titleColor)); + titleFrame.gotoxy(console.screen_columns - 25, 2); + titleFrame.putmsg("bullshit v2 by echicken", DARKGRAY); + listFrame.gotoxy(3, 2); + listFrame.putmsg(format("%-" + titleLen + "s%s", "Title", "Date"), getColor(ini.headingColor)); + footerFrame.gotoxy(3, 2); + footerFrame.putmsg("[ESC] or Q to quit, Up/Down arrows to scroll", getColor(ini.footerColor)); + treeScroll = new ScrollBar(tree); + frame.open(); + tree.open(); + } catch(err) { + log(LOG_ERR, err); + return false; + } + return true; +} + +var main = function() { + while(!js.terminated) { + var userInput = console.inkey(K_NONE, 5); + if(userInput.toUpperCase() == "Q" || ascii(userInput) == 27) + break; + tree.getcmd(userInput); + if(frame.cycle()) { + treeScroll.cycle(); + console.gotoxy(console.screen_columns, console.screen_rows); + } + } +} + +if(init()) { + main(); + frame.close(); +} +exit(); diff --git a/xtrn/bullshit/readme.txt b/xtrn/bullshit/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..1ccc060653b0140039a33a9966b30dc584f8382e --- /dev/null +++ b/xtrn/bullshit/readme.txt @@ -0,0 +1,53 @@ +Bullshit 2.0 +-=-=-=-=-=-= +by echicken -at- bbs.electronicchicken.com + +Bullshit is a bulletin listing/reading module for Synchronet BBS 3.16+. It +uses a sysops-only message base on your BBS as a storage back-end. Adding +new bulletins to your system becomes as easy as posting a message. + + +Installation: +-=-=-=-=-=-=- + +Launch SCFG (BBS->Configure in the Synchronet Control Panel on Windows.) + +In 'Message Areas', select your local message group, and create a new sub with +the following details: + +Long Name Bulletins +Short Name Bulletins +QWK Name BULLSHIT +Internal Code BULLSHIT +Access Requirements LEVEL 90 +Reading Requirements LEVEL 90 +Posting Requirements LEVEL 90 + +In the "Toggle Options" for the sub, ensure that "Default on for new scan", +"Forced on for new scan", and "Default on for your scan" are set to 'No'. + +(You can set the Access, Reading, and Posting requirements to any ARS value +that you want. Ideally, only the Sysop should be able to see or post to this +sub, and Bullshit will be the interface by which users view messages here.) + +Return to the main menu of SCFG, go to 'External Programs', then to +'Online Programs (Doors)'. Select whatever externals section you want to +place Bullshit in ('Main' might be a good choice) and then add a new item +with the following details: + +Name Bullshit +Internal Code BULLSHIT +Start-up Directory /sbbs/xtrn/bullshit +Command Line ?bullshit.js +Multiple Concurrent Users Yes + +If you want Bullshit to run during your logon process, set the following: + +Execute on Event logon + +Next you can edit 'bullshit.ini' to your liking. It contains some options for +colors and such. + +Now go ahead and start posting messages in the Bulletins sub-board that you +created. The subject line of each message will appear as the bulletin title, +and the message body will be the text of the bulletin. \ No newline at end of file