module FeedsController def show_feeds(feeds=[]) @all_feeds ||= feeds # So we can redisplay them after exiting a search subset begin @command_window = CommandWindow.new(@scr) @items = @all_feeds @scr.refresh # or else the initial screen is blank, I don't know why yet @content_area = MenuWindow.new("Your Feeds", @scr, @all_feeds, @current_feed_index || 0) @command_window.help_prompt loop do parse_feeds_list_command end end end def parse_feeds_list_command c = @scr.getch # store number in buffer, vim style c, buffer = key_buffer(c) multiplier = buffer.empty? ? 1 : buffer.join.to_i LOGGER.debug("Char: #{c}") LOGGER.debug("Multiplier: #{multiplier}") case c when ?\? # help show_help(CursesController::FEEDS_MENU_COMMANDS) # Any key restores the menu redraw when ?\u # UPDATE FEEDS @current_feed = @items[@content_area.current_index] num = @command_window.feed_update_progress(@current_feed) if num > 0 @scr.getch redraw end when ?\U # UPDATE FEEDS, forcing update even if soon after last update @current_feed = @items[@content_area.current_index] num = @command_window.feed_update_progress(@current_feed, true) if num > 0 @scr.getch redraw end when control_key('U') # UPDATE ALL FEEDS num = 0 @all_feeds.each do |feed| num += (@command_window.feed_update_progress(feed) || 0) end @command_window.message("#{num} new items.") when ?\d # delete feed @current_feed = @items[@content_area.current_index] if @current_feed.is_a?(VirtualFeed) @command_window.command_line = "You can't delete a virtual feed!" @command_window.draw return end if @command_window.confirm_delete_feed(@current_feed) == ?\y title = @current_feed.title @current_feed.destroy @command_window.command_line = "The #{title} feed has been deleted" @current_index = @content_area.current_index - 1 feeds = Feed.feeds_list redraw(feeds) else @command_window.command_line = "Canceled." end @command_window.draw when 97 # ?\a # add feed if (new_feed = @command_window.add_feed) # redraw feeds list feed_list = Feed.feeds_list @current_index = feed_list.index(new_feed) redraw(feed_list) end @command_window.draw when ?\q # cancel search # TODO change if @command_window && @command_window.command_line == 'Press q to cancel search.' cancel_search else exit end # SEARCH. This is a global search that generates a virtual feed when ?\/ @command_window ||= CommandWindow.new( @scr ) @global_search_string = @command_window.get_search_string if @global_search_string == '' || @global_search_string =~ /^\W*$/ @command_window.command_line = "Found no matches" end matches = search_feeds(@global_search_string.strip) if matches.nil? || matches.empty? @command_window.command_line = "Found no matches" end if matches # create a virtual feed @items = @current_entries = matches @entries_list_matches = nil @current_entry_index = 0 @content_area.close @content_area = nil show_entries else @command_window.draw end when Key::LEFT, Key::UP, ?k, ?p @content_area.prev_item(multiplier) when Key::DOWN, ?j, ?\s, ?n @content_area.next_item(multiplier) when Key::RESIZE redraw(false) when Key::RIGHT, ?l, 10 # Enter key # You can type a number and press enter or right arrow to select a feed by # number. unless buffer && buffer.empty? selection = buffer.join.to_i # set feed @current_feed = @items[selection - 1] @current_feed_index = selection - 1 @content_area.current_index = selection - 1 else @current_feed = @items[@content_area.current_index] @current_feed_index = @content_area.current_index end # set current entry index to 0 @current_entry_index = 0 LOGGER.debug("Selected feed #{@current_feed.title}") # Regular Feeds and Virtual Feeds have same interface @items = @current_entries = @current_feed.is_a?(VirtualFeed) ? @current_feed.entries : @current_feed.entries.find(:all, :include => :feed) # Show the entry content @entries_list_matches = nil @current_entry_index = 0 @content_area.close @content_area = nil show_entries when 'M'[0] # middle of screen @content_area.middle when 'L'[0] # bottom of screen @content_area.bottom when 'H'[0] # top of screen @content_area.top when 'G'[0] # beginning or end of list if buffer.last == 1 @content_area.end else @content_area.beginning end when control_key('F') @content_area.next_page when control_key('B') @content_area.prev_page else # don't do anything end end # This reloads the feeds (if items are provided) and redraws the content window def redraw(new_items =nil) @items = new_items ? (@all_feeds = new_items) : @content_area.items unless new_items @current_index = @content_area.current_index end @content_area.close @content_area = MenuWindow.new("Your Feeds", @scr, @items, @current_index) end # This is a global search of all feed entries def search_feeds(global_search_string) if global_search_string == '' @command_window.clear return end # maybe change this to ferret or something later # TODO LOGGER.debug("search query: title LIKE '%#{global_search_string}%' or content LIKE '%#{global_search_string}%'") matches = Entry.find(:all, :include => :feed, :conditions => "title LIKE '%#{global_search_string}%'", :order => "id desc") # We give priority to title matches matches.concat Entry.find(:all, :include => :feed, :conditions => "content LIKE '%#{global_search_string}%'", :order => "id desc") # There might very well be duplicates, so compress matches.uniq! if matches.empty? @command_window.command_line = "Found no matches for search string '#{global_search_string}'" @command_window.draw nil else @command_window.command_line = "Found #{matches.size} entries for search string '#{global_search_string}'. Displaying..." @command_window.draw sleep 1 matches end end end