Fix paging bug where if you go to a page and scroll down further than a previous (shorter) page can get to, the document is scrolled to bottom and looks empty. #6

Merged
peteyboy merged 1 commits from fix-paging-bug into develop 2026-06-12 17:32:55 -04:00

View File

@@ -1,9 +1,9 @@
#!/usr/bin/perl -w
# connex.pl Nightfall Express (nex://) browser
# By Pete Dussin, peteyboy@sdf.org 3/2024
# updated 6/2026
# This program uses telnet instead of nc to make nex requests, because I couldn't get the Perl nc module to work right.
#TODO: Fill out help Dialog, mention vi navigatio and search
#TODO: Fill out About Dialog
#TODO: Make status dialog actually useful
#TODO: bookmarks, maybe a quick mark-and-hold toggle to jump between two pages?
@@ -18,6 +18,7 @@ use Curses::UI;
use Net::Telnet;
use URI::Split qw(uri_split uri_join);
use URI ();
use Scalar::Util 'looks_like_number';
use Term::ReadKey; #for fatpacker?
@@ -62,7 +63,7 @@ if (defined $full_url){
die "Need a $SCHEME_NEX url, or start without supplying URL argument.\n";
}
$full_url= $uri->as_string;
$HOME_URL = $full_url; #TODO make sure you want to do this, mostly go home and other defaults will go here instead o nightfall.city
$HOME_URL = $full_url; #TODO make sure you want to do this, mostly go home and other defaults will go here instead of nightfall.city
}else{
$full_url = $HOME_URL;
}
@@ -84,19 +85,19 @@ my $connect = new Net::Telnet (Timeout => 10,
my @menu = (
{ -label => 'File',
-submenu => [
{ -label => 'Choose Link >', -value => \&goto_link_dialog },
{ -label => 'Back ^B/<', -value => \&goto_back },
{ -label => 'Go to Link ^G', -value => \&navigate_link_dialog },
{ -label => 'Go Home ^M', -value => \&goto_home },
{ -label => 'Page Links ^P', -value => \&page_links_dialog },
{ -label => 'History ^Y', -value => \&history_status_dialog },
{ -label => 'Exit ^Q', -value => \&exit_dialog }
{ -label => 'Choose Link >', -value => \&goto_link_dialog },
{ -label => 'Back ^B/<', -value => \&goto_back },
{ -label => 'Go to Link ^G', -value => \&navigate_link_dialog },
{ -label => 'Go Home ^M', -value => \&goto_home },
{ -label => 'Page Links ^P', -value => \&page_links_dialog },
{ -label => 'Browser History ^Y', -value => \&history_status_dialog },
{ -label => 'Exit ^Q', -value => \&exit_dialog }
]
},
{ -label => 'Help',
-submenu => [
{ -label => 'Help ^H', -value => \&help_dialog },
{ -label => 'About ', -value => \&about_dialog },
{ -label => 'Help ^H', -value => \&help_dialog },
{ -label => 'About ', -value => \&about_dialog },
]
},
@@ -108,7 +109,7 @@ my @menu = (
sub exit_dialog()
{
my $return = $cui->dialog(
-title => "Quit Connex?",
-title => "Quit Connex",
-message => "Are you sure?",
-buttons => ['yes', 'no'],
@@ -132,6 +133,9 @@ sub links_dialog()
sub unsupported_dialog
{
my $scheme = shift;
if (!defined $scheme){
$scheme="unknown";
}
my $return = $cui->dialog(
-message => "$scheme protocol not supported.",
-title => "Bad Navigation",
@@ -159,16 +163,19 @@ sub goto_link_dialog()
);
#if not canceled, or too big or too small, goto link
if($return){
my $linkcount = scalar @page_links;
if($return <= $linkcount && $return >0){
update_status($S_REQUESTING);
goto_link($return);
}else{
#$browser->focus();
my $return1 = $cui->status("there is no link # " . $return);
if(looks_like_number($return)){
my $linkcount = scalar @page_links;
if($return <= $linkcount && $return >0){
update_status($S_REQUESTING);
goto_link($return);
}else{
my $return1 = $cui->status("there is no link # " . $return);
}
}else{ #they are using it to navigate to a different site or for some other reason entered text
my $return2 = $cui->status("You did not enter a link #. To Go to a different site, use 'Go' menu or type ctl-g");
}
#do nothing on cancel
}
#do nothing on cancel
}
@@ -182,7 +189,7 @@ sub goto_back()
#if($fetched) {
$full_url =$fetched;
update_status($S_REQUESTING);
load($full_url,0); #don't move back to top
load($full_url,1); #move back to top
history_status_dialog();
#}
@@ -198,7 +205,7 @@ sub goto_home()
$full_url=$HOME_URL;
}
update_status($S_REQUESTING);
load($full_url,0); #don't move back to top
load($full_url,1); #move back to top
history_status_dialog();
}
@@ -211,7 +218,7 @@ sub goto_link{
#my $element=$linknum -1; #offset for array element
#if ($element <= $#page_links){ #such a perlism, this is highest INDEX of array
if ($linknum <= $linkcount){ #such a perlism, this is highest INDEX of array
if ($linknum <= $linkcount){
navigate($page_links[$linknum-1]); #offset from count to index
}else{
#my $browser = $win1->getobj("browser");
@@ -231,6 +238,15 @@ sub navigate{
}
sub browser_scroll_reset
{
my $browser = $win1->getobj("browser");
$browser->{-ypos} = 0;
#$browser->{-viewPos} =0; none of this works
$browser->draw();
$browser->focus();
}
sub update_status_bar
{
my $status = shift;
@@ -291,12 +307,16 @@ sub history_status_dialog
sub page_links_dialog
{
my $browser = $win1->getobj("browser");
$browser->focus();
#my $link_list = join("\n", @page_links);
if(@page_links){
my $browser = $win1->getobj("browser");
$browser->focus();
#my $link_list = join("\n", @page_links);
my $link_list = page_links_list();
my $return = $cui->status("links on this page:\n$link_list");
#}elsif (!is_path_index($browser->title())){ #if not an index, actually is this even important to the user?
# my $return = $cui->status("Not an index page.");
}else{ #there are no links in this index (should be rare, and index with no links?)
my $return = $cui->status("No links on this page.");
}
}
@@ -330,12 +350,27 @@ sub help_dialog
my $browser = $win1->getobj("browser");
$browser->focus();
my $message = <<'END_MESSAGE';
Navigation:
Press '>' key to select a '[>#]link by #
Browsing:
Press '>' key to select a '[>#] link by #
Press '<' key to go back to previous page
Press 'ctl-Y' to see viewed page history
Press 'ctl-P' to see list of links on current page
Program Features:
Scrolling:
Arrow keys to scroll document
Press 'PageDown' to scroll down by page
Press 'PageUp' to scroll up by page
Search:
'less' type search function supported:
Press '/' to start a forward search (type search term, hit <enter>)
search for the next occurance using the 'n' key or the previous
occurance using the 'N' key.
Press '?' to start a reverse search (type search term, hit <enter>)
More Program Features:
Press ctl-x for menu
END_MESSAGE
my $return = $cui->dialog(
@@ -397,6 +432,7 @@ $statusbar = $win1->add("status", "TextViewer",
#key bindings, should match menu items
$cui->set_binding(sub {$menu->focus()}, "\cX");
$cui->set_binding( \&help_dialog , "\cH");
$cui->set_binding( \&exit_dialog , "\cQ");
$cui->set_binding( \&navigate_link_dialog , "\cG");
$cui->set_binding( \&goto_back , "\cB");
@@ -405,7 +441,6 @@ $cui->set_binding( \&goto_link_dialog , ">");
$cui->set_binding( \&goto_home , "\cM");
$cui->set_binding( \&page_links_dialog , "\cP");
$cui->set_binding( \&history_status_dialog , "\cY");
$cui->set_binding( \&help_dialog , "\cH");
$cui->set_binding(sub {
my $cui = shift;
$cui->layout;
@@ -516,7 +551,20 @@ sub load
#TODO:handle non-existent request? Die is not pretty to do here
die unless $connect->eof();
$connect->close();
my $widget= $texteditor;
# check if we want to scroll to top
if ($top eq 1){
#For widget programmers: To control the scrollbar, the widget data -vscrolllen (the total length of the content of the widget) and -vscrollpos (the current position in the document) should be set.
# If Curses::UI::Widget::draw is called, the scrollbar will be drawn.
#browser_scroll_reset();
#my $browser = $win1->getobj("browser");
$widget->{-ypos} = 0;
#$browser->{-viewPos} =0; none of this works
#$browser->draw();
#$browser->focus();
}
#loop through nex response and load into text editor. Identify, mark and store link lines for index pages
my $page_contents =""; #this is the page contents to be dumped into the browser widget
@@ -532,11 +580,9 @@ sub load
}
$page_contents= $page_contents . $currentline;
}
$widget->text($page_contents);
$widget->text($page_contents);
$widget->draw();
if ($top){
$widget->pos(0);
}
if ($page_contents eq ''){
update_status($S_NORESPONSE);
}else{