From 1baf5cc13f08cffc3cfafa73369fd2b77ae31205 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Thu, 10 Dec 2020 08:56:14 +0200 Subject: Feeds: Show entries in lookup results --- src/app.h | 4 +++- src/gmutil.c | 22 +++++++++++++++++++ src/gmutil.h | 2 ++ src/lookup.h | 1 + src/ui/lookupwidget.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++--- src/ui/sidebarwidget.c | 21 ++++--------------- 6 files changed, 86 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/app.h b/src/app.h index 743484a5..0e8351aa 100644 --- a/src/app.h +++ b/src/app.h @@ -86,7 +86,9 @@ void postCommand_App (const char *command); void postCommandf_App (const char *command, ...); iLocalDef void postCommandString_App(const iString *command) { - postCommand_App(cstr_String(command)); + if (command) { + postCommand_App(cstr_String(command)); + } } void openInDefaultBrowser_App (const iString *url); diff --git a/src/gmutil.c b/src/gmutil.c index 94f00ce1..477d0f17 100644 --- a/src/gmutil.c +++ b/src/gmutil.c @@ -213,6 +213,28 @@ void urlEncodeSpaces_String(iString *d) { } } +const iString *feedEntryOpenCommand_String(const iString *url) { + if (!isEmpty_String(url)) { + iString *cmd = collectNew_String(); + const size_t fragPos = indexOf_String(url, '#'); + if (fragPos != iInvalidPos) { + iString *head = newRange_String( + (iRangecc){ constBegin_String(url) + fragPos + 1, constEnd_String(url) }); + format_String(cmd, + "open gotourlheading:%s url:%s", + cstr_String(head), + cstr_Rangecc((iRangecc){ constBegin_String(url), + constBegin_String(url) + fragPos })); + delete_String(head); + } + else { + format_String(cmd, "open url:%s", cstr_String(url)); + } + return cmd; + } + return NULL; +} + static const struct { enum iGmStatusCode code; iGmError err; diff --git a/src/gmutil.h b/src/gmutil.h index e7022cfa..926f5a10 100644 --- a/src/gmutil.h +++ b/src/gmutil.h @@ -106,3 +106,5 @@ const iString * absoluteUrl_String (const iString *, const iString *urlMayb iString * makeFileUrl_String (const iString *localFilePath); const char * makeFileUrl_CStr (const char *localFilePath); void urlEncodeSpaces_String (iString *); + +const iString * feedEntryOpenCommand_String (const iString *url); /* checks fragment */ diff --git a/src/lookup.h b/src/lookup.h index a20a36d0..64e2c974 100644 --- a/src/lookup.h +++ b/src/lookup.h @@ -30,6 +30,7 @@ iDeclareType(LookupResult) enum iLookupResultType { none_LookupResultType, bookmark_LookupResultType, + feedEntry_LookupResultType, history_LookupResultType, /* visited URLs */ content_LookupResultType, /* one of the pages in history, including current page */ identity_LookupResultType, diff --git a/src/ui/lookupwidget.c b/src/ui/lookupwidget.c index dcde7d79..b80170d2 100644 --- a/src/ui/lookupwidget.c +++ b/src/ui/lookupwidget.c @@ -26,6 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "bookmarks.h" #include "command.h" #include "documentwidget.h" +#include "feeds.h" #include "gmcerts.h" #include "gmutil.h" #include "history.h" @@ -158,6 +159,16 @@ static float bookmarkRelevance_LookupJob_(const iLookupJob *d, const iBookmark * return h + iMax(p, t) + 2 * g; /* extra weight for tags */ } +static float feedEntryRelevance_LookupJob_(const iLookupJob *d, const iFeedEntry *entry) { + iUrl parts; + init_Url(&parts, &entry->url); + const float t = scoreMatch_(d->term, range_String(&entry->title)); + const float h = scoreMatch_(d->term, parts.host); + const float p = scoreMatch_(d->term, parts.path); + const double age = secondsSince_Time(&d->now, &entry->posted) / 3600.0 / 24.0; /* days */ + return (t * 3 + h + p) / (age + 1); /* extra weight for title, recency */ +} + static float identityRelevance_LookupJob_(const iLookupJob *d, const iGmIdentity *identity) { iString *cn = subject_TlsCertificate(identity->cert); const float c = scoreMatch_(d->term, range_String(cn)); @@ -190,18 +201,41 @@ static void searchBookmarks_LookupJob_(iLookupJob *d) { const iBookmark *bm = i.ptr; iLookupResult * res = new_LookupResult(); res->type = bookmark_LookupResultType; + res->when = bm->when; res->relevance = bookmarkRelevance_LookupJob_(d, bm); appendChar_String(&res->label, bm->icon); appendChar_String(&res->label, ' '); append_String(&res->label, &bm->title); -// set_String(&res->label, &bm->title); -// appendFormat_String(&res->label, " (%f)", res->relevance); set_String(&res->url, &bm->url); - res->when = bm->when; pushBack_PtrArray(&d->results, res); } } +static void searchFeeds_LookupJob_(iLookupJob *d) { + iConstForEach(PtrArray, i, listEntries_Feeds()) { + const iFeedEntry *entry = i.ptr; + const iBookmark *bm = get_Bookmarks(bookmarks_App(), entry->bookmarkId); + if (!bm) { + continue; + } + const float relevance = feedEntryRelevance_LookupJob_(d, entry); + if (relevance > 0) { + iLookupResult *res = new_LookupResult(); + res->type = feedEntry_LookupResultType; + res->when = entry->posted; + res->relevance = relevance; + set_String(&res->url, &entry->url); + set_String(&res->meta, &bm->title); + if (bm->icon) { + appendChar_String(&res->label, bm->icon); + appendChar_String(&res->label, ' '); + } + append_String(&res->label, &entry->title); + pushBack_PtrArray(&d->results, res); + } + } +} + static void searchVisited_LookupJob_(iLookupJob *d) { /* Note: Called in a background thread. */ /* TODO: Thread safety! Visited URLs may be deleted while being accessed here. */ @@ -300,6 +334,7 @@ static iThreadResult worker_LookupWidget_(iThread *thread) { unlock_Mutex(d->mtx); /* Do the lookup. */ { searchBookmarks_LookupJob_(job); + searchFeeds_LookupJob_(job); searchVisited_LookupJob_(job); if (termLen >= 3) { searchHistory_LookupJob_(job); @@ -401,6 +436,8 @@ static const char *cstr_LookupResultType(enum iLookupResultType d) { switch (d) { case bookmark_LookupResultType: return "BOOKMARKS"; + case feedEntry_LookupResultType: + return "FEEDS"; case history_LookupResultType: return "HISTORY"; case content_LookupResultType: @@ -490,6 +527,20 @@ static void presentResults_LookupWidget_(iLookupWidget *d) { format_String(&item->command, "open url:%s", cstr_String(&res->url)); break; } + case feedEntry_LookupResultType: { + item->fg = uiTextStrong_ColorId; + item->font = uiLabel_FontId; + format_String(&item->text, + "%s %s\u2014 %s", + cstr_String(&res->label), + uiText_ColorEscape, + cstr_String(&res->meta)); + const iString *cmd = feedEntryOpenCommand_String(&res->url); + if (cmd) { + set_String(&item->command, cmd); + } + break; + } case history_LookupResultType: { item->fg = uiText_ColorId; item->font = uiContent_FontId; diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index a140718b..78b51a54 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c @@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "documentwidget.h" #include "feeds.h" #include "gmcerts.h" +#include "gmutil.h" #include "gmdocument.h" #include "inputwidget.h" #include "labelwidget.h" @@ -503,24 +504,10 @@ static void itemClicked_SidebarWidget_(iSidebarWidget *d, const iSidebarItem *it postCommandf_App("document.goto loc:%p", head->text.start); break; } - case feeds_SidebarMode: - if (!isEmpty_String(&item->url)) { - const size_t fragPos = indexOf_String(&item->url, '#'); - if (fragPos != iInvalidPos) { - iString *head = collect_String( - newRange_String((iRangecc){ constBegin_String(&item->url) + fragPos + 1, - constEnd_String(&item->url) })); - postCommandf_App( - "open gotourlheading:%s url:%s", - cstr_String(head), - cstr_Rangecc((iRangecc){ constBegin_String(&item->url), - constBegin_String(&item->url) + fragPos })); - } - else { - postCommandf_App("open url:%s", cstr_String(&item->url)); - } - } + case feeds_SidebarMode: { + postCommandString_App(feedEntryOpenCommand_String(&item->url)); break; + } case bookmarks_SidebarMode: case history_SidebarMode: { if (!isEmpty_String(&item->url)) { -- cgit v1.2.3