feat: add occurrence-aware appointment search

This commit is contained in:
2026-07-18 08:31:09 +01:00
parent c19098004e
commit 2774087d14
14 changed files with 485 additions and 11 deletions

View File

@@ -6,6 +6,7 @@
#include <cstddef>
#include <functional>
#include <span>
#include <string_view>
#include <vector>
namespace nocal {
@@ -40,6 +41,9 @@ void sort_occurrences(EventOccurrences& occurrences);
[[nodiscard]] bool event_less(const Event& lhs, const Event& rhs) noexcept;
void sort_events(EventRefs& events);
[[nodiscard]] bool event_matches_query(const Event& event,
std::string_view query);
// Event and query intervals are half-open. A zero-duration event is treated as
// an instant and belongs to the interval containing its start time.
[[nodiscard]] bool event_overlaps(const Event& event, TimePoint begin,

View File

@@ -5,6 +5,7 @@
#include <span>
#include <string>
#include <string_view>
#include <vector>
#include "nocal/domain/event.hpp"
#include "nocal/domain/event_query.hpp"
@@ -40,6 +41,16 @@ struct CalendarItem {
std::string source_time_zone;
};
struct SearchResultItem {
std::string focus_id;
std::string title;
std::chrono::year_month_day day;
std::optional<std::chrono::minutes> time_of_day;
bool all_day{false};
std::string location;
bool recurring{false};
};
struct ScreenState {
std::chrono::year_month visible_month{std::chrono::year{1970}, std::chrono::month{1}};
std::chrono::year_month_day selected_day{std::chrono::year{1970}, std::chrono::month{1},
@@ -53,6 +64,11 @@ struct ScreenState {
std::optional<std::string> focused_event_id;
bool show_event_details{false};
bool confirm_delete{false};
bool search_prompt{false};
bool show_search_results{false};
std::string search_query;
std::vector<SearchResultItem> search_results;
std::size_t search_result_index{0};
std::string notification;
bool notification_is_error{false};
};
@@ -92,6 +108,7 @@ enum class Action {
delete_event,
undo,
redo,
search,
quit,
};

View File

@@ -42,6 +42,9 @@ public:
[[nodiscard]] bool delete_confirmation_active() const noexcept {
return state_.confirm_delete;
}
[[nodiscard]] bool search_active() const noexcept {
return state_.search_prompt || state_.show_search_results;
}
private:
struct HistorySnapshot {
@@ -87,6 +90,10 @@ private:
void submit_editor();
void confirm_delete();
void cancel_delete();
void begin_search();
void submit_search();
void close_search();
void choose_search_result();
void set_notification(std::string message, bool error = false);
};