diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-10 07:32:51 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-10 07:32:51 +0300 |
commit | 4e8977f5734663956613caac058849273c4e5ac0 (patch) | |
tree | 60401b68bac34b6e13f49ec49d2e64d1fb4b2325 /src | |
parent | 2e9be8d9ceb6b2ee5d15e63b82c4be6ceca54429 (diff) |
Feeds: All/Unread view mode selection
This is a bit too simple, but allows seeing the unread entries only. The unread counter needs some reworking: should it show all unread or unread in the "All" list (latest 100 entries)?
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/listwidget.c | 4 | ||||
-rw-r--r-- | src/ui/listwidget.h | 2 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 45 | ||||
-rw-r--r-- | src/ui/sidebarwidget.h | 5 |
4 files changed, 46 insertions, 10 deletions
diff --git a/src/ui/listwidget.c b/src/ui/listwidget.c index 1f5572bd..dbd8e540 100644 --- a/src/ui/listwidget.c +++ b/src/ui/listwidget.c | |||
@@ -165,7 +165,7 @@ void setScrollPos_ListWidget(iListWidget *d, int pos) { | |||
165 | refresh_Widget(as_Widget(d)); | 165 | refresh_Widget(as_Widget(d)); |
166 | } | 166 | } |
167 | 167 | ||
168 | void scrollOffset_ListWidget(iListWidget *d, int offset) { | 168 | iBool scrollOffset_ListWidget(iListWidget *d, int offset) { |
169 | const int oldScroll = d->scrollY; | 169 | const int oldScroll = d->scrollY; |
170 | d->scrollY += offset; | 170 | d->scrollY += offset; |
171 | if (d->scrollY < 0) { | 171 | if (d->scrollY < 0) { |
@@ -180,7 +180,9 @@ void scrollOffset_ListWidget(iListWidget *d, int offset) { | |||
180 | } | 180 | } |
181 | updateVisible_ListWidget(d); | 181 | updateVisible_ListWidget(d); |
182 | refresh_Widget(as_Widget(d)); | 182 | refresh_Widget(as_Widget(d)); |
183 | return iTrue; | ||
183 | } | 184 | } |
185 | return iFalse; | ||
184 | } | 186 | } |
185 | 187 | ||
186 | void scrollToItem_ListWidget(iListWidget *d, size_t index) { | 188 | void scrollToItem_ListWidget(iListWidget *d, size_t index) { |
diff --git a/src/ui/listwidget.h b/src/ui/listwidget.h index 16adf664..d7e2c55e 100644 --- a/src/ui/listwidget.h +++ b/src/ui/listwidget.h | |||
@@ -61,7 +61,7 @@ int scrollPos_ListWidget (const iListWidget *); | |||
61 | 61 | ||
62 | void setScrollPos_ListWidget (iListWidget *, int pos); | 62 | void setScrollPos_ListWidget (iListWidget *, int pos); |
63 | void scrollToItem_ListWidget (iListWidget *, size_t index); | 63 | void scrollToItem_ListWidget (iListWidget *, size_t index); |
64 | void scrollOffset_ListWidget (iListWidget *, int offset); | 64 | iBool scrollOffset_ListWidget (iListWidget *, int offset); /* returns true if position changed */ |
65 | void updateVisible_ListWidget (iListWidget *); | 65 | void updateVisible_ListWidget (iListWidget *); |
66 | void updateMouseHover_ListWidget (iListWidget *); | 66 | void updateMouseHover_ListWidget (iListWidget *); |
67 | 67 | ||
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index b865679e..5c71ef0d 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -91,6 +91,7 @@ struct Impl_SidebarWidget { | |||
91 | iWidget widget; | 91 | iWidget widget; |
92 | enum iSidebarSide side; | 92 | enum iSidebarSide side; |
93 | enum iSidebarMode mode; | 93 | enum iSidebarMode mode; |
94 | enum iFeedsMode feedsMode; | ||
94 | iString cmdPrefix; | 95 | iString cmdPrefix; |
95 | iWidget * blank; | 96 | iWidget * blank; |
96 | iListWidget * list; | 97 | iListWidget * list; |
@@ -139,6 +140,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
139 | d->actions->rect.size.y = 0; | 140 | d->actions->rect.size.y = 0; |
140 | destroy_Widget(d->menu); | 141 | destroy_Widget(d->menu); |
141 | d->menu = NULL; | 142 | d->menu = NULL; |
143 | iBool isEmpty = iFalse; /* show blank? */ | ||
142 | switch (d->mode) { | 144 | switch (d->mode) { |
143 | case feeds_SidebarMode: { | 145 | case feeds_SidebarMode: { |
144 | const iString *docUrl = withSpacesEncoded_String(url_DocumentWidget(document_App())); | 146 | const iString *docUrl = withSpacesEncoded_String(url_DocumentWidget(document_App())); |
@@ -150,6 +152,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
150 | const iDate today = on; | 152 | const iDate today = on; |
151 | iZap(on); | 153 | iZap(on); |
152 | size_t numItems = 0; | 154 | size_t numItems = 0; |
155 | isEmpty = iTrue; | ||
153 | iConstForEach(PtrArray, i, listEntries_Feeds()) { | 156 | iConstForEach(PtrArray, i, listEntries_Feeds()) { |
154 | const iFeedEntry *entry = i.ptr; | 157 | const iFeedEntry *entry = i.ptr; |
155 | if (isHidden_FeedEntry(entry)) { | 158 | if (isHidden_FeedEntry(entry)) { |
@@ -163,6 +166,12 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
163 | if (secondsSince_Time(&now, &entry->discovered) > maxAge_Visited) { | 166 | if (secondsSince_Time(&now, &entry->discovered) > maxAge_Visited) { |
164 | break; /* the rest are even older */ | 167 | break; /* the rest are even older */ |
165 | } | 168 | } |
169 | isEmpty = iFalse; | ||
170 | const iBool isOpen = equal_String(docUrl, &entry->url); | ||
171 | const iBool isUnread = isUnread_FeedEntry(entry); | ||
172 | if (d->feedsMode == unread_FeedsMode && !isUnread && !isOpen) { | ||
173 | continue; | ||
174 | } | ||
166 | /* Insert date separators. */ { | 175 | /* Insert date separators. */ { |
167 | iDate entryDate; | 176 | iDate entryDate; |
168 | init_Date(&entryDate, &entry->posted); | 177 | init_Date(&entryDate, &entry->posted); |
@@ -188,10 +197,8 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
188 | } | 197 | } |
189 | } | 198 | } |
190 | iSidebarItem *item = new_SidebarItem(); | 199 | iSidebarItem *item = new_SidebarItem(); |
191 | if (equal_String(docUrl, &entry->url)) { | 200 | item->listItem.isSelected = isOpen; /* currently being viewed */ |
192 | item->listItem.isSelected = iTrue; /* currently being viewed */ | 201 | item->indent = isUnread; |
193 | } | ||
194 | item->indent = isUnread_FeedEntry(entry); | ||
195 | set_String(&item->url, &entry->url); | 202 | set_String(&item->url, &entry->url); |
196 | set_String(&item->label, &entry->title); | 203 | set_String(&item->label, &entry->title); |
197 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), entry->bookmarkId); | 204 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), entry->bookmarkId); |
@@ -208,6 +215,16 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
208 | break; | 215 | break; |
209 | } | 216 | } |
210 | } | 217 | } |
218 | /* Actions. */ { | ||
219 | addChildFlags_Widget( | ||
220 | d->actions, | ||
221 | iClob(new_LabelWidget("${sidebar.action.feeds.showall}", "feeds.mode arg:0")), | ||
222 | d->feedsMode == all_FeedsMode ? selected_WidgetFlag : 0); | ||
223 | addChildFlags_Widget(d->actions, | ||
224 | iClob(new_LabelWidget("${sidebar.action.feeds.showunread}", | ||
225 | "feeds.mode arg:1")), | ||
226 | d->feedsMode == unread_FeedsMode ? selected_WidgetFlag : 0); | ||
227 | } | ||
211 | d->menu = makeMenu_Widget( | 228 | d->menu = makeMenu_Widget( |
212 | as_Widget(d), | 229 | as_Widget(d), |
213 | (iMenuItem[]){ { openTab_Icon " ${feeds.entry.newtab}", 0, 0, "feed.entry.opentab" }, | 230 | (iMenuItem[]){ { openTab_Icon " ${feeds.entry.newtab}", 0, 0, "feed.entry.opentab" }, |
@@ -343,11 +360,14 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
343 | case identities_SidebarMode: { | 360 | case identities_SidebarMode: { |
344 | /* Actions. */ { | 361 | /* Actions. */ { |
345 | checkIcon_LabelWidget(addChild_Widget( | 362 | checkIcon_LabelWidget(addChild_Widget( |
346 | d->actions, iClob(new_LabelWidget(add_Icon " New...", "ident.new")))); | 363 | d->actions, |
364 | iClob(new_LabelWidget(add_Icon " ${sidebar.action.ident.new}", "ident.new")))); | ||
347 | checkIcon_LabelWidget(addChild_Widget( | 365 | checkIcon_LabelWidget(addChild_Widget( |
348 | d->actions, iClob(new_LabelWidget("Import...", "ident.import")))); | 366 | d->actions, |
367 | iClob(new_LabelWidget("${sidebar.action.ident.import}", "ident.import")))); | ||
349 | } | 368 | } |
350 | const iString *tabUrl = url_DocumentWidget(document_App()); | 369 | const iString *tabUrl = url_DocumentWidget(document_App()); |
370 | isEmpty = iTrue; | ||
351 | iConstForEach(PtrArray, i, identities_GmCerts(certs_App())) { | 371 | iConstForEach(PtrArray, i, identities_GmCerts(certs_App())) { |
352 | const iGmIdentity *ident = i.ptr; | 372 | const iGmIdentity *ident = i.ptr; |
353 | iSidebarItem *item = new_SidebarItem(); | 373 | iSidebarItem *item = new_SidebarItem(); |
@@ -380,6 +400,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
380 | item->listItem.isSelected = isActive; | 400 | item->listItem.isSelected = isActive; |
381 | addItem_ListWidget(d->list, item); | 401 | addItem_ListWidget(d->list, item); |
382 | iRelease(item); | 402 | iRelease(item); |
403 | isEmpty = iFalse; | ||
383 | } | 404 | } |
384 | const iMenuItem menuItems[] = { | 405 | const iMenuItem menuItems[] = { |
385 | { person_Icon " ${ident.use}", 0, 0, "ident.use arg:1" }, | 406 | { person_Icon " ${ident.use}", 0, 0, "ident.use arg:1" }, |
@@ -400,10 +421,12 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
400 | default: | 421 | default: |
401 | break; | 422 | break; |
402 | } | 423 | } |
403 | updateVisible_ListWidget(d->list); | 424 | if (!scrollOffset_ListWidget(d->list, 0)) { |
425 | updateVisible_ListWidget(d->list); | ||
426 | } | ||
404 | invalidate_ListWidget(d->list); | 427 | invalidate_ListWidget(d->list); |
405 | /* Content for a blank tab. */ | 428 | /* Content for a blank tab. */ |
406 | if (isEmpty_ListWidget(d->list)) { | 429 | if (isEmpty) { |
407 | if (d->mode == feeds_SidebarMode) { | 430 | if (d->mode == feeds_SidebarMode) { |
408 | iWidget *div = makeVDiv_Widget(); | 431 | iWidget *div = makeVDiv_Widget(); |
409 | setPadding_Widget(div, 3 * gap_UI, 0, 3 * gap_UI, 2 * gap_UI); | 432 | setPadding_Widget(div, 3 * gap_UI, 0, 3 * gap_UI, 2 * gap_UI); |
@@ -536,6 +559,7 @@ void init_SidebarWidget(iSidebarWidget *d, enum iSidebarSide side) { | |||
536 | iZap(d->modeScroll); | 559 | iZap(d->modeScroll); |
537 | d->side = side; | 560 | d->side = side; |
538 | d->mode = -1; | 561 | d->mode = -1; |
562 | d->feedsMode = all_FeedsMode; | ||
539 | d->numUnreadEntries = 0; | 563 | d->numUnreadEntries = 0; |
540 | d->itemFonts[0] = uiContent_FontId; | 564 | d->itemFonts[0] = uiContent_FontId; |
541 | d->itemFonts[1] = uiContentBold_FontId; | 565 | d->itemFonts[1] = uiContentBold_FontId; |
@@ -1031,6 +1055,11 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1031 | updateItems_SidebarWidget_(d); | 1055 | updateItems_SidebarWidget_(d); |
1032 | } | 1056 | } |
1033 | } | 1057 | } |
1058 | else if (equalWidget_Command(cmd, w, "feeds.mode")) { | ||
1059 | d->feedsMode = arg_Command(cmd); | ||
1060 | updateItems_SidebarWidget_(d); | ||
1061 | return iTrue; | ||
1062 | } | ||
1034 | else if (equal_Command(cmd, "feeds.markallread") && d->mode == feeds_SidebarMode) { | 1063 | else if (equal_Command(cmd, "feeds.markallread") && d->mode == feeds_SidebarMode) { |
1035 | iConstForEach(PtrArray, i, listEntries_Feeds()) { | 1064 | iConstForEach(PtrArray, i, listEntries_Feeds()) { |
1036 | const iFeedEntry *entry = i.ptr; | 1065 | const iFeedEntry *entry = i.ptr; |
diff --git a/src/ui/sidebarwidget.h b/src/ui/sidebarwidget.h index 8027adc0..2e418aa4 100644 --- a/src/ui/sidebarwidget.h +++ b/src/ui/sidebarwidget.h | |||
@@ -40,6 +40,11 @@ enum iSidebarSide { | |||
40 | right_SideBarSide, | 40 | right_SideBarSide, |
41 | }; | 41 | }; |
42 | 42 | ||
43 | enum iFeedsMode { | ||
44 | all_FeedsMode, | ||
45 | unread_FeedsMode | ||
46 | }; | ||
47 | |||
43 | iDeclareWidgetClass(SidebarWidget) | 48 | iDeclareWidgetClass(SidebarWidget) |
44 | iDeclareObjectConstructionArgs(SidebarWidget, enum iSidebarSide side) | 49 | iDeclareObjectConstructionArgs(SidebarWidget, enum iSidebarSide side) |
45 | 50 | ||