114 lines
3.5 KiB
Ruby
114 lines
3.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'bbs'
|
|
require 'time'
|
|
require_relative 'lib/repository/online_users_repository'
|
|
require_relative 'lib/repository/message_board_repository'
|
|
require_relative 'lib/repository/wiki_repository'
|
|
require_relative 'lib/repository/catalog_repository'
|
|
require_relative 'lib/page/helpers'
|
|
require_relative 'lib/page/idle_page'
|
|
require_relative 'lib/page/messages_page'
|
|
require_relative 'lib/page/new_msg_page'
|
|
require_relative 'lib/page/wiki_list_page'
|
|
require_relative 'lib/page/page_view_page'
|
|
require_relative 'lib/page/games_page'
|
|
require_relative 'lib/page/online_page'
|
|
require_relative 'lib/page/sysinfo_page'
|
|
|
|
ONLINE = OnlineUsersRepository.new
|
|
MESSAGES = MessageBoardRepository.new(ENV.fetch('MESSAGES_PATH', 'data/messages.dat'))
|
|
WIKI = WikiRepository.new(token: ENV['WEBAPP_WIKIJS_TOKEN'])
|
|
CATALOG = CatalogRepository.new
|
|
|
|
MENU_ITEMS = [
|
|
'Messages', 'Post Message', 'Blog Posts',
|
|
'HowTo Guides', 'Game Catalog', 'Online Users',
|
|
'System Info', 'Exit'
|
|
].freeze
|
|
|
|
LEFT_W = 21
|
|
CONT_X = 23
|
|
CONT_Y = 2
|
|
|
|
THEME = {
|
|
bg: "\e[0;40m", # #0A0800 ≈ black
|
|
normal: "\e[0;33m", # #FFB000 amber (body text)
|
|
bright: "\e[1;33m", # #FFD880 bright amber (headings)
|
|
border: "\e[0;33m", # amber borders
|
|
selected: "\e[0;30;43m", # #0A0800 fg on #C88000 bg (inverse)
|
|
header: "\e[1;33m", # bright amber
|
|
label: "\e[2;33m", # #6B4800 dim amber (secondary)
|
|
status: "\e[0;30;43m", # #0A0800 fg on #C88000 bg
|
|
input: "\e[1;33m", # bright amber for typed text
|
|
success: "\e[1;32m", # green
|
|
error: "\e[1;31m", # red
|
|
reset: "\e[0m",
|
|
}.freeze
|
|
|
|
MAIN_TUI = BBS::TUI.define do
|
|
helpers { include TUIHelpers }
|
|
|
|
init do
|
|
@menu_sel = 0
|
|
@page_title = 'TELETYPE BBS'
|
|
@items = []
|
|
@item_sel = 0
|
|
@scroll = 0
|
|
@detail = []
|
|
@page_meta = +''
|
|
@input = +''
|
|
@status = +''
|
|
@prev_page = nil
|
|
end
|
|
|
|
chrome do
|
|
screen_fill bg: :black
|
|
|
|
panel_h = term_rows - 1
|
|
|
|
box x: 1, y: 1, w: LEFT_W, h: panel_h,
|
|
style: THEME[:border], bg: :black
|
|
box x: LEFT_W + 1, y: 1, w: term_cols - LEFT_W, h: panel_h,
|
|
title: " #{@page_title} │ #{@username} │ #{ONLINE.count} online ",
|
|
style: THEME[:border], bg: :black
|
|
|
|
list MENU_ITEMS.map { |i| i[0, LEFT_W - 4] },
|
|
x: 2, y: CONT_Y,
|
|
selected: @menu_sel,
|
|
style: THEME[:normal], highlight: THEME[:selected]
|
|
|
|
bar y: term_rows,
|
|
content: " \e[1;37;43m↑↓\e[0;30;43m Navigate \e[1;37;43mEnter\e[0;30;43m Select " \
|
|
"\e[1;37;43mQ\e[0;30;43m Back \e[1;37;43mR\e[0;30;43m Refresh",
|
|
style: THEME[:status]
|
|
end
|
|
|
|
IdlePage.configure(self)
|
|
MessagesPage.configure(self)
|
|
NewMsgPage.configure(self)
|
|
WikiListPage.configure(self, :blog, category: 'blog', title: 'BLOG')
|
|
WikiListPage.configure(self, :howto, category: 'howto', title: 'HOWTO GUIDES')
|
|
PageViewPage.configure(self)
|
|
GamesPage.configure(self)
|
|
OnlinePage.configure(self)
|
|
SysinfoPage.configure(self)
|
|
|
|
start :idle
|
|
end
|
|
|
|
BBS.configure do |c|
|
|
c.on_session_end = ->(session) { ONLINE.remove(session.session_id) }
|
|
|
|
c.flow = BBS::Flow.define do
|
|
big_banner 'TELETYPE BBS', style: :success
|
|
ask :username, prompt: 'Name (blank for Anonymous)',
|
|
transform: ->(v) { v.strip.empty? ? 'Anonymous' : v.strip[0...20] }
|
|
call { |ctx| ONLINE.add(ctx[:session_id], ctx[:username]) }
|
|
tui MAIN_TUI
|
|
say 'Goodbye!', style: :muted
|
|
end
|
|
end
|
|
|
|
BBS.start
|