From 10c3746a6df45dd154955a9e91e662260f36363f Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Tue, 14 Apr 2026 14:38:42 +0800 Subject: refactor: adjust code structure --- src/core/local_data.cc | 171 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/core/local_data.cc (limited to 'src/core/local_data.cc') diff --git a/src/core/local_data.cc b/src/core/local_data.cc new file mode 100644 index 0000000..9115844 --- /dev/null +++ b/src/core/local_data.cc @@ -0,0 +1,171 @@ +/* + * Ricochet - A minimalist CLI web browser for fast, distraction-free navigation. + * Copyright (C) 2026 Richard Qin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ricochet/core/local_data.hh" +#include +#include +#include +#include + +namespace ricochet::core { + +std::string get_config_path( const std::string& filename ) +{ + const char* home = std::getenv( "HOME" ); // NOLINT(concurrency-mt-unsafe) + const std::string dir = ( home != nullptr ) ? std::string( home ) + "/.ricochet" : ".ricochet"; + static_cast( mkdir( dir.c_str(), 0755 ) ); + return dir + "/" + filename; +} + +void save_bookmark( const std::string& title, // NOLINT(bugprone-easily-swappable-parameters) + const std::string& url ) +{ + if ( url == "ricochet://bookmarks" ) { + return; + } + std::ofstream file( get_config_path( "bookmarks.txt" ), std::ios::app ); + if ( !file.is_open() ) { + return; + } + + std::string safe_title = title; + if ( safe_title.empty() ) { + safe_title = url; + } + for ( char& c : safe_title ) { + if ( c == '\n' || c == '\r' || c == '\t' ) { + c = ' '; + } + } + file << url << '\t' << safe_title << '\n'; +} + +std::string generate_bookmarks_html() +{ + std::ifstream file( get_config_path( "bookmarks.txt" ) ); + std::string html = "My Bookmarks

Saved Bookmarks

    "; + if ( !file.is_open() ) { + html += "
  • No bookmarks found. Press 'b' on any page to add one!
  • "; + } else { + std::string line; + while ( std::getline( file, line ) ) { + const std::size_t tab_pos = line.find( '\t' ); + if ( tab_pos != std::string::npos ) { + const std::string url = line.substr( 0, tab_pos ); + const std::string title = line.substr( tab_pos + 1 ); + html += "
  • [Link] "; + html += title; + html += "
  • "; + } + } + } + html += "
"; + return html; +} + +void append_to_history( const std::string& url, // NOLINT(bugprone-easily-swappable-parameters) + const std::string& title ) +{ + if ( url.starts_with( "ricochet://" ) ) { + return; + } + std::ofstream file( get_config_path( "history.txt" ), std::ios::app ); + if ( !file.is_open() ) { + return; + } + + std::string safe_title = title; + if ( safe_title.empty() ) { + safe_title = url; + } + for ( char& c : safe_title ) { + if ( c == '\n' || c == '\r' || c == '\t' ) { + c = ' '; + } + } + file << url << '\t' << safe_title << '\n'; +} + +std::string generate_history_html() +{ + std::ifstream file( get_config_path( "history.txt" ) ); + std::string html = "History

Browsing History

    "; + if ( !file.is_open() ) { + html += "
  • No history found. Start browsing!
  • "; + } else { + std::vector lines; + std::string line; + while ( std::getline( file, line ) ) { + lines.push_back( std::move( line ) ); + } + + std::size_t count = 0; + for ( auto it = lines.rbegin(); it != lines.rend() && count < 100; ++it, ++count ) { + const std::size_t tab_pos = it->find( '\t' ); + if ( tab_pos != std::string::npos ) { + const std::string url = it->substr( 0, tab_pos ); + const std::string title = it->substr( tab_pos + 1 ); + html += "
  • [Link] "; + html += title; + html += "
  • "; + } + } + } + html += "
"; + return html; +} + +std::string generate_help_html() +{ + return R"( + Ricochet Help Manual + +

Ricochet User Manual

+

1. Navigation & Browsing

+
    +
  • j / k : Scroll down / up
  • +
  • H / L : History backward / forward
  • +
  • / : Open prompt to enter a new URL
  • +
+

2. Page Interaction

+
    +
  • f : Toggle Link Hints (type the two letters to follow a link instantly)
  • +
  • n : Find in page (search for text)
  • +
  • N : Jump to the next search match
  • +
  • i : Enter form input mode (fill textboxes, click buttons, toggle checkboxes)
  • +
+

3. Bookmarks & History

+
    +
  • b : Bookmark the current page
  • +
  • B : View all saved bookmarks
  • +
  • h : View browsing history
  • +
+

4. System

+
    +
  • ? : Show this help manual
  • +
  • q : Quit Ricochet
  • +
+ + )"; +} + +} // namespace ricochet::core -- cgit v1.2.3