diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-10 08:56:14 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-10 08:56:14 +0200 |
commit | 1baf5cc13f08cffc3cfafa73369fd2b77ae31205 (patch) | |
tree | 603efa3dd87f8d6e4f09d5c13f0bf6cdd2140363 | |
parent | cb26d891e372cfc02e5da68af50543ed2e04e1fc (diff) |
Feeds: Show entries in lookup results
-rw-r--r-- | src/app.h | 4 | ||||
-rw-r--r-- | src/gmutil.c | 22 | ||||
-rw-r--r-- | src/gmutil.h | 2 | ||||
-rw-r--r-- | src/lookup.h | 1 | ||||
-rw-r--r-- | src/ui/lookupwidget.c | 57 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 21 |
6 files changed, 86 insertions, 21 deletions
@@ -86,7 +86,9 @@ void postCommand_App (const char *command); | |||
86 | void postCommandf_App (const char *command, ...); | 86 | void postCommandf_App (const char *command, ...); |
87 | 87 | ||
88 | iLocalDef void postCommandString_App(const iString *command) { | 88 | iLocalDef void postCommandString_App(const iString *command) { |
89 | postCommand_App(cstr_String(command)); | 89 | if (command) { |
90 | postCommand_App(cstr_String(command)); | ||
91 | } | ||
90 | } | 92 | } |
91 | 93 | ||
92 | void openInDefaultBrowser_App (const iString *url); | 94 | 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) { | |||
213 | } | 213 | } |
214 | } | 214 | } |
215 | 215 | ||
216 | const iString *feedEntryOpenCommand_String(const iString *url) { | ||
217 | if (!isEmpty_String(url)) { | ||
218 | iString *cmd = collectNew_String(); | ||
219 | const size_t fragPos = indexOf_String(url, '#'); | ||
220 | if (fragPos != iInvalidPos) { | ||
221 | iString *head = newRange_String( | ||
222 | (iRangecc){ constBegin_String(url) + fragPos + 1, constEnd_String(url) }); | ||
223 | format_String(cmd, | ||
224 | "open gotourlheading:%s url:%s", | ||
225 | cstr_String(head), | ||
226 | cstr_Rangecc((iRangecc){ constBegin_String(url), | ||
227 | constBegin_String(url) + fragPos })); | ||
228 | delete_String(head); | ||
229 | } | ||
230 | else { | ||
231 | format_String(cmd, "open url:%s", cstr_String(url)); | ||
232 | } | ||
233 | return cmd; | ||
234 | } | ||
235 | return NULL; | ||
236 | } | ||
237 | |||
216 | static const struct { | 238 | static const struct { |
217 | enum iGmStatusCode code; | 239 | enum iGmStatusCode code; |
218 | iGmError err; | 240 | 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 | |||
106 | iString * makeFileUrl_String (const iString *localFilePath); | 106 | iString * makeFileUrl_String (const iString *localFilePath); |
107 | const char * makeFileUrl_CStr (const char *localFilePath); | 107 | const char * makeFileUrl_CStr (const char *localFilePath); |
108 | void urlEncodeSpaces_String (iString *); | 108 | void urlEncodeSpaces_String (iString *); |
109 | |||
110 | 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) | |||
30 | enum iLookupResultType { | 30 | enum iLookupResultType { |
31 | none_LookupResultType, | 31 | none_LookupResultType, |
32 | bookmark_LookupResultType, | 32 | bookmark_LookupResultType, |
33 | feedEntry_LookupResultType, | ||
33 | history_LookupResultType, /* visited URLs */ | 34 | history_LookupResultType, /* visited URLs */ |
34 | content_LookupResultType, /* one of the pages in history, including current page */ | 35 | content_LookupResultType, /* one of the pages in history, including current page */ |
35 | identity_LookupResultType, | 36 | 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. */ | |||
26 | #include "bookmarks.h" | 26 | #include "bookmarks.h" |
27 | #include "command.h" | 27 | #include "command.h" |
28 | #include "documentwidget.h" | 28 | #include "documentwidget.h" |
29 | #include "feeds.h" | ||
29 | #include "gmcerts.h" | 30 | #include "gmcerts.h" |
30 | #include "gmutil.h" | 31 | #include "gmutil.h" |
31 | #include "history.h" | 32 | #include "history.h" |
@@ -158,6 +159,16 @@ static float bookmarkRelevance_LookupJob_(const iLookupJob *d, const iBookmark * | |||
158 | return h + iMax(p, t) + 2 * g; /* extra weight for tags */ | 159 | return h + iMax(p, t) + 2 * g; /* extra weight for tags */ |
159 | } | 160 | } |
160 | 161 | ||
162 | static float feedEntryRelevance_LookupJob_(const iLookupJob *d, const iFeedEntry *entry) { | ||
163 | iUrl parts; | ||
164 | init_Url(&parts, &entry->url); | ||
165 | const float t = scoreMatch_(d->term, range_String(&entry->title)); | ||
166 | const float h = scoreMatch_(d->term, parts.host); | ||
167 | const float p = scoreMatch_(d->term, parts.path); | ||
168 | const double age = secondsSince_Time(&d->now, &entry->posted) / 3600.0 / 24.0; /* days */ | ||
169 | return (t * 3 + h + p) / (age + 1); /* extra weight for title, recency */ | ||
170 | } | ||
171 | |||
161 | static float identityRelevance_LookupJob_(const iLookupJob *d, const iGmIdentity *identity) { | 172 | static float identityRelevance_LookupJob_(const iLookupJob *d, const iGmIdentity *identity) { |
162 | iString *cn = subject_TlsCertificate(identity->cert); | 173 | iString *cn = subject_TlsCertificate(identity->cert); |
163 | const float c = scoreMatch_(d->term, range_String(cn)); | 174 | const float c = scoreMatch_(d->term, range_String(cn)); |
@@ -190,18 +201,41 @@ static void searchBookmarks_LookupJob_(iLookupJob *d) { | |||
190 | const iBookmark *bm = i.ptr; | 201 | const iBookmark *bm = i.ptr; |
191 | iLookupResult * res = new_LookupResult(); | 202 | iLookupResult * res = new_LookupResult(); |
192 | res->type = bookmark_LookupResultType; | 203 | res->type = bookmark_LookupResultType; |
204 | res->when = bm->when; | ||
193 | res->relevance = bookmarkRelevance_LookupJob_(d, bm); | 205 | res->relevance = bookmarkRelevance_LookupJob_(d, bm); |
194 | appendChar_String(&res->label, bm->icon); | 206 | appendChar_String(&res->label, bm->icon); |
195 | appendChar_String(&res->label, ' '); | 207 | appendChar_String(&res->label, ' '); |
196 | append_String(&res->label, &bm->title); | 208 | append_String(&res->label, &bm->title); |
197 | // set_String(&res->label, &bm->title); | ||
198 | // appendFormat_String(&res->label, " (%f)", res->relevance); | ||
199 | set_String(&res->url, &bm->url); | 209 | set_String(&res->url, &bm->url); |
200 | res->when = bm->when; | ||
201 | pushBack_PtrArray(&d->results, res); | 210 | pushBack_PtrArray(&d->results, res); |
202 | } | 211 | } |
203 | } | 212 | } |
204 | 213 | ||
214 | static void searchFeeds_LookupJob_(iLookupJob *d) { | ||
215 | iConstForEach(PtrArray, i, listEntries_Feeds()) { | ||
216 | const iFeedEntry *entry = i.ptr; | ||
217 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), entry->bookmarkId); | ||
218 | if (!bm) { | ||
219 | continue; | ||
220 | } | ||
221 | const float relevance = feedEntryRelevance_LookupJob_(d, entry); | ||
222 | if (relevance > 0) { | ||
223 | iLookupResult *res = new_LookupResult(); | ||
224 | res->type = feedEntry_LookupResultType; | ||
225 | res->when = entry->posted; | ||
226 | res->relevance = relevance; | ||
227 | set_String(&res->url, &entry->url); | ||
228 | set_String(&res->meta, &bm->title); | ||
229 | if (bm->icon) { | ||
230 | appendChar_String(&res->label, bm->icon); | ||
231 | appendChar_String(&res->label, ' '); | ||
232 | } | ||
233 | append_String(&res->label, &entry->title); | ||
234 | pushBack_PtrArray(&d->results, res); | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | |||
205 | static void searchVisited_LookupJob_(iLookupJob *d) { | 239 | static void searchVisited_LookupJob_(iLookupJob *d) { |
206 | /* Note: Called in a background thread. */ | 240 | /* Note: Called in a background thread. */ |
207 | /* TODO: Thread safety! Visited URLs may be deleted while being accessed here. */ | 241 | /* TODO: Thread safety! Visited URLs may be deleted while being accessed here. */ |
@@ -300,6 +334,7 @@ static iThreadResult worker_LookupWidget_(iThread *thread) { | |||
300 | unlock_Mutex(d->mtx); | 334 | unlock_Mutex(d->mtx); |
301 | /* Do the lookup. */ { | 335 | /* Do the lookup. */ { |
302 | searchBookmarks_LookupJob_(job); | 336 | searchBookmarks_LookupJob_(job); |
337 | searchFeeds_LookupJob_(job); | ||
303 | searchVisited_LookupJob_(job); | 338 | searchVisited_LookupJob_(job); |
304 | if (termLen >= 3) { | 339 | if (termLen >= 3) { |
305 | searchHistory_LookupJob_(job); | 340 | searchHistory_LookupJob_(job); |
@@ -401,6 +436,8 @@ static const char *cstr_LookupResultType(enum iLookupResultType d) { | |||
401 | switch (d) { | 436 | switch (d) { |
402 | case bookmark_LookupResultType: | 437 | case bookmark_LookupResultType: |
403 | return "BOOKMARKS"; | 438 | return "BOOKMARKS"; |
439 | case feedEntry_LookupResultType: | ||
440 | return "FEEDS"; | ||
404 | case history_LookupResultType: | 441 | case history_LookupResultType: |
405 | return "HISTORY"; | 442 | return "HISTORY"; |
406 | case content_LookupResultType: | 443 | case content_LookupResultType: |
@@ -490,6 +527,20 @@ static void presentResults_LookupWidget_(iLookupWidget *d) { | |||
490 | format_String(&item->command, "open url:%s", cstr_String(&res->url)); | 527 | format_String(&item->command, "open url:%s", cstr_String(&res->url)); |
491 | break; | 528 | break; |
492 | } | 529 | } |
530 | case feedEntry_LookupResultType: { | ||
531 | item->fg = uiTextStrong_ColorId; | ||
532 | item->font = uiLabel_FontId; | ||
533 | format_String(&item->text, | ||
534 | "%s %s\u2014 %s", | ||
535 | cstr_String(&res->label), | ||
536 | uiText_ColorEscape, | ||
537 | cstr_String(&res->meta)); | ||
538 | const iString *cmd = feedEntryOpenCommand_String(&res->url); | ||
539 | if (cmd) { | ||
540 | set_String(&item->command, cmd); | ||
541 | } | ||
542 | break; | ||
543 | } | ||
493 | case history_LookupResultType: { | 544 | case history_LookupResultType: { |
494 | item->fg = uiText_ColorId; | 545 | item->fg = uiText_ColorId; |
495 | item->font = uiContent_FontId; | 546 | 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. */ | |||
28 | #include "documentwidget.h" | 28 | #include "documentwidget.h" |
29 | #include "feeds.h" | 29 | #include "feeds.h" |
30 | #include "gmcerts.h" | 30 | #include "gmcerts.h" |
31 | #include "gmutil.h" | ||
31 | #include "gmdocument.h" | 32 | #include "gmdocument.h" |
32 | #include "inputwidget.h" | 33 | #include "inputwidget.h" |
33 | #include "labelwidget.h" | 34 | #include "labelwidget.h" |
@@ -503,24 +504,10 @@ static void itemClicked_SidebarWidget_(iSidebarWidget *d, const iSidebarItem *it | |||
503 | postCommandf_App("document.goto loc:%p", head->text.start); | 504 | postCommandf_App("document.goto loc:%p", head->text.start); |
504 | break; | 505 | break; |
505 | } | 506 | } |
506 | case feeds_SidebarMode: | 507 | case feeds_SidebarMode: { |
507 | if (!isEmpty_String(&item->url)) { | 508 | postCommandString_App(feedEntryOpenCommand_String(&item->url)); |
508 | const size_t fragPos = indexOf_String(&item->url, '#'); | ||
509 | if (fragPos != iInvalidPos) { | ||
510 | iString *head = collect_String( | ||
511 | newRange_String((iRangecc){ constBegin_String(&item->url) + fragPos + 1, | ||
512 | constEnd_String(&item->url) })); | ||
513 | postCommandf_App( | ||
514 | "open gotourlheading:%s url:%s", | ||
515 | cstr_String(head), | ||
516 | cstr_Rangecc((iRangecc){ constBegin_String(&item->url), | ||
517 | constBegin_String(&item->url) + fragPos })); | ||
518 | } | ||
519 | else { | ||
520 | postCommandf_App("open url:%s", cstr_String(&item->url)); | ||
521 | } | ||
522 | } | ||
523 | break; | 509 | break; |
510 | } | ||
524 | case bookmarks_SidebarMode: | 511 | case bookmarks_SidebarMode: |
525 | case history_SidebarMode: { | 512 | case history_SidebarMode: { |
526 | if (!isEmpty_String(&item->url)) { | 513 | if (!isEmpty_String(&item->url)) { |