From bc312b1205612f5bd124bd6bf9f173a9b6d98792 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Wed, 30 Jul 2025 19:24:53 +0300 Subject: [PATCH] implement special counter display when viewing by published, similar to marked --- classes/Counters.php | 19 ++++++++++++--- classes/Feeds.php | 25 ++++++++++++++++++++ js/FeedTree.js | 7 +++++- js/Feeds.js | 1 + themes/compact.css | 37 +++++++++++++++++++++-------- themes/compact_night.css | 43 +++++++++++++++++++++++++--------- themes/light-high-contrast.css | 37 +++++++++++++++++++++-------- themes/light.css | 37 +++++++++++++++++++++-------- themes/light/defines.less | 1 + themes/light/tt-rss.less | 33 ++++++++++++++++++++++---- themes/night.css | 43 +++++++++++++++++++++++++--------- themes/night_base.less | 24 +++++++++++++------ themes/night_blue.css | 43 +++++++++++++++++++++++++--------- utils/phpstan-watcher.sh | 6 ++--- 14 files changed, 274 insertions(+), 82 deletions(-) diff --git a/classes/Counters.php b/classes/Counters.php index 613210ecc..ec6e49b70 100644 --- a/classes/Counters.php +++ b/classes/Counters.php @@ -35,6 +35,7 @@ class Counters { static private function get_cat_children(int $cat_id, int $owner_uid): array { $unread = 0; $marked = 0; + $published = 0; $cats = ORM::for_table('ttrss_feed_categories') ->where('owner_uid', $owner_uid) @@ -42,13 +43,14 @@ class Counters { ->find_many(); foreach ($cats as $cat) { - list ($tmp_unread, $tmp_marked) = self::get_cat_children($cat->id, $owner_uid); + list ($tmp_unread, $tmp_marked, $tmp_published) = self::get_cat_children($cat->id, $owner_uid); $unread += $tmp_unread + Feeds::_get_cat_unread($cat->id, $owner_uid); $marked += $tmp_marked + Feeds::_get_cat_marked($cat->id, $owner_uid); + $published += $tmp_published + Feeds::_get_cat_published($cat->id, $owner_uid); } - return [$unread, $marked]; + return [$unread, $marked, $published]; } /** @@ -99,6 +101,7 @@ class Counters { $sth = $pdo->prepare("SELECT fc.id, SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count, SUM(CASE WHEN marked THEN 1 ELSE 0 END) AS count_marked, + SUM(CASE WHEN published THEN 1 ELSE 0 END) AS count_published, (SELECT COUNT(id) FROM ttrss_feed_categories fcc WHERE fcc.parent_cat = fc.id) AS num_children FROM ttrss_feed_categories fc @@ -110,6 +113,7 @@ class Counters { SELECT 0, SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count, SUM(CASE WHEN marked THEN 1 ELSE 0 END) AS count_marked, + SUM(CASE WHEN published THEN 1 ELSE 0 END) AS count_published, 0 FROM ttrss_feeds f, ttrss_user_entries ue WHERE f.cat_id IS NULL AND @@ -121,16 +125,18 @@ class Counters { while ($line = $sth->fetch()) { if ($line["num_children"] > 0) { - list ($child_counter, $child_marked_counter) = self::get_cat_children($line["id"], $_SESSION["uid"]); + list ($child_counter, $child_marked_counter, $child_published_counter) = self::get_cat_children($line["id"], $_SESSION["uid"]); } else { $child_counter = 0; $child_marked_counter = 0; + $child_published_counter = 0; } $cv = [ "id" => (int)$line["id"], "kind" => "cat", "markedcounter" => (int) $line["count_marked"] + $child_marked_counter, + "publishedcounter" => (int) $line["count_published"] + $child_published_counter, "counter" => (int) $line["count"] + $child_counter ]; @@ -173,6 +179,7 @@ class Counters { 'updated' => TimeHelper::make_local_datetime($feed->last_updated), 'counter' => (int) $feed->count, 'markedcounter' => (int) $feed->count_marked, + 'publishedcounter' => (int) $feed->count_published, 'ts' => Feeds::_has_icon($feed->id) ? (int) filemtime(Feeds::_get_icon_file($feed->id)) : 0, ]; } @@ -228,6 +235,9 @@ class Counters { if ($feed_id == Feeds::FEED_STARRED) $cv["markedcounter"] = $auxctr; + if ($feed_id == Feeds::FEED_PUBLISHED) + $cv["publishedcounter"] = $auxctr; + array_push($ret, $cv); } @@ -270,6 +280,7 @@ class Counters { caption, SUM(CASE WHEN u1.unread = true THEN 1 ELSE 0 END) AS count_unread, SUM(CASE WHEN u1.marked = true THEN 1 ELSE 0 END) AS count_marked, + SUM(CASE WHEN u1.published = true THEN 1 ELSE 0 END) AS count_published, COUNT(u1.unread) AS total FROM ttrss_labels2 LEFT JOIN ttrss_user_labels2 ON (ttrss_labels2.id = label_id) @@ -282,6 +293,7 @@ class Counters { caption, SUM(CASE WHEN u1.unread = true THEN 1 ELSE 0 END) AS count_unread, SUM(CASE WHEN u1.marked = true THEN 1 ELSE 0 END) AS count_marked, + SUM(CASE WHEN u1.published = true THEN 1 ELSE 0 END) AS count_published, COUNT(u1.unread) AS total FROM ttrss_labels2 LEFT JOIN ttrss_user_labels2 ON (ttrss_labels2.id = label_id) @@ -300,6 +312,7 @@ class Counters { "counter" => (int) $line["count_unread"], "auxcounter" => (int) $line["total"], "markedcounter" => (int) $line["count_marked"], + "publishedcounter" => (int) $line["count_published"], "description" => $line["caption"] ]; diff --git a/classes/Feeds.php b/classes/Feeds.php index e76044060..7781d748f 100644 --- a/classes/Feeds.php +++ b/classes/Feeds.php @@ -1248,6 +1248,31 @@ class Feeds extends Handler_Protected { return 0; } + // only real cats + static function _get_cat_published(int $cat, int $owner_uid = 0): int { + + if (!$owner_uid) $owner_uid = $_SESSION["uid"]; + + $pdo = Db::pdo(); + + if ($cat >= 0) { + + $sth = $pdo->prepare("SELECT SUM(CASE WHEN published THEN 1 ELSE 0 END) AS marked + FROM ttrss_user_entries + WHERE feed_id IN (SELECT id FROM ttrss_feeds + WHERE (cat_id = :cat OR (:cat IS NULL AND cat_id IS NULL)) + AND owner_uid = :uid) + AND owner_uid = :uid"); + + $sth->execute(["cat" => $cat ? $cat : null, "uid" => $owner_uid]); + + if ($row = $sth->fetch()) { + return (int) $row["marked"]; + } + } + return 0; + } + static function _get_cat_unread(int $cat, int $owner_uid = 0): int { if (!$owner_uid) $owner_uid = $_SESSION["uid"]; diff --git a/js/FeedTree.js b/js/FeedTree.js index df026a7bc..67d2a8035 100755 --- a/js/FeedTree.js +++ b/js/FeedTree.js @@ -173,6 +173,9 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co tnode.markedCounterNode = dojo.create('span', { className: 'counterNode marked', innerHTML: args.item.markedcounter }); domConstruct.place(tnode.markedCounterNode, tnode.rowNode, 'first'); + tnode.publishedCounterNode = dojo.create('span', { className: 'counterNode published', innerHTML: args.item.publishedcounter }); + domConstruct.place(tnode.publishedCounterNode, tnode.rowNode, 'first'); + tnode.auxCounterNode = dojo.create('span', { className: 'counterNode aux', innerHTML: args.item.auxcounter }); domConstruct.place(tnode.auxCounterNode, tnode.rowNode, 'first'); @@ -188,7 +191,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co updateCounter: function (item) { const tree = this; - //console.log("updateCounter: " + item.id[0] + " " + item.unread + " " + tree); + // console.log("updateCounter: " + item.id[0] + " U: " + item.unread + " P: " + item.publishedcounter + " M: " + item.markedcounter); let treeNode = tree._itemNodesMap[item.id]; @@ -198,6 +201,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co treeNode.unreadCounterNode.innerHTML = item.unread; treeNode.auxCounterNode.innerHTML = item.auxcounter; treeNode.markedCounterNode.innerHTML = item.markedcounter; + treeNode.publishedCounterNode.innerHTML = item.publishedcounter; } }, getTooltip: function (item) { @@ -224,6 +228,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co if (item.unread > 0) rc += " Unread"; if (item.auxcounter > 0) rc += " Has_Aux"; if (item.markedcounter > 0) rc += " Has_Marked"; + if (item.publishedcounter > 0) rc += " Has_Published"; if (item.updates_disabled > 0) rc += " UpdatesDisabled"; if (item.bare_id >= App.LABEL_BASE_INDEX && item.bare_id < 0 && !is_cat || item.bare_id == Feeds.FEED_ARCHIVED && !is_cat) rc += " Special"; if (item.bare_id == Feeds.CATEGORY_SPECIAL && is_cat) rc += " AlwaysVisible"; diff --git a/js/Feeds.js b/js/Feeds.js index 7a58a10a4..03836b594 100644 --- a/js/Feeds.js +++ b/js/Feeds.js @@ -105,6 +105,7 @@ const Feeds = { this.setUnread(id, (kind == "cat"), ctr); this.setValue(id, (kind == "cat"), 'auxcounter', parseInt(elems[l].auxcounter)); this.setValue(id, (kind == "cat"), 'markedcounter', parseInt(elems[l].markedcounter)); + this.setValue(id, (kind == "cat"), 'publishedcounter', parseInt(elems[l].publishedcounter)); if (kind != "cat") { this.setValue(id, false, 'error', error); diff --git a/themes/compact.css b/themes/compact.css index af8ab6004..df5c000ef 100644 --- a/themes/compact.css +++ b/themes/compact.css @@ -561,14 +561,19 @@ body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNod flex-shrink: 0; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.aux, -body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked, +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { background: #f5f5f5; color: #6f6f6f; border-color: #dcdcdc; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { border-color: #257aa7; - background: #ffffff; + background: white; +} +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { + border-color: #b13000; + background: white; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow[data-feed-id="-3"][data-is-cat="false"] .counterNode.unread { background-color: #3ea447; @@ -958,22 +963,34 @@ body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Ma body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Marked .counterNode.marked { display: inline-block; } +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .dijitTreeLabel { + color: #b13000; +} +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .counterNode.published { + display: inline-block; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Marked) { display: none; } +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Published) { + display: none; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Marked) { display: none; } -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Published) { display: none; } -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { + display: none; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { display: none; } body.ttrss_main { diff --git a/themes/compact_night.css b/themes/compact_night.css index 1cc3191ce..8d141beba 100644 --- a/themes/compact_night.css +++ b/themes/compact_night.css @@ -561,14 +561,19 @@ body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNod flex-shrink: 0; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.aux, -body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked, +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { background: #222; color: #e6e6e6; border-color: #080808; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { border-color: #b87d2c; - background: #ffffff; + background: #333; +} +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { + border-color: #db8c6f; + background: #333; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow[data-feed-id="-3"][data-is-cat="false"] .counterNode.unread { background-color: #3ea447; @@ -958,22 +963,34 @@ body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Ma body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Marked .counterNode.marked { display: inline-block; } +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .dijitTreeLabel { + color: #db8c6f; +} +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .counterNode.published { + display: inline-block; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Marked) { display: none; } +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Published) { + display: none; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Marked) { display: none; } -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Published) { display: none; } -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { + display: none; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { display: none; } body.ttrss_main { @@ -2169,7 +2186,8 @@ body.flat.ttrss_main #feeds-holder { box-shadow: inset -1px 0px 2px -1px #666; } body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.aux, -body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked, +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.published { background: #222; color: #ccc; border-color: #333; @@ -2177,6 +2195,9 @@ body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { border-color: #b87d2c; } +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.published { + border-color: #db8c6f; +} body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .dijitTreeRowSelected { background: #333; border-color: #333 transparent; diff --git a/themes/light-high-contrast.css b/themes/light-high-contrast.css index 96da6aa41..6fac41435 100644 --- a/themes/light-high-contrast.css +++ b/themes/light-high-contrast.css @@ -561,14 +561,19 @@ body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNod flex-shrink: 0; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.aux, -body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked, +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { background: #f5f5f5; color: #1a1a1a; border-color: #dcdcdc; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { border-color: #257aa7; - background: #ffffff; + background: white; +} +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { + border-color: #b13000; + background: white; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow[data-feed-id="-3"][data-is-cat="false"] .counterNode.unread { background-color: #3ea447; @@ -958,22 +963,34 @@ body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Ma body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Marked .counterNode.marked { display: inline-block; } +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .dijitTreeLabel { + color: #b13000; +} +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .counterNode.published { + display: inline-block; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Marked) { display: none; } +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Published) { + display: none; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Marked) { display: none; } -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Published) { display: none; } -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { + display: none; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { display: none; } body.ttrss_main { diff --git a/themes/light.css b/themes/light.css index e1a334104..f1971e227 100644 --- a/themes/light.css +++ b/themes/light.css @@ -561,14 +561,19 @@ body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNod flex-shrink: 0; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.aux, -body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked, +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { background: #f5f5f5; color: #6f6f6f; border-color: #dcdcdc; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { border-color: #257aa7; - background: #ffffff; + background: white; +} +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { + border-color: #b13000; + background: white; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow[data-feed-id="-3"][data-is-cat="false"] .counterNode.unread { background-color: #3ea447; @@ -958,22 +963,34 @@ body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Ma body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Marked .counterNode.marked { display: inline-block; } +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .dijitTreeLabel { + color: #b13000; +} +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .counterNode.published { + display: inline-block; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Marked) { display: none; } +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Published) { + display: none; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Marked) { display: none; } -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Published) { display: none; } -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { + display: none; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { display: none; } body.ttrss_main { diff --git a/themes/light/defines.less b/themes/light/defines.less index 37d1beadf..10b8675c5 100644 --- a/themes/light/defines.less +++ b/themes/light/defines.less @@ -8,6 +8,7 @@ @color-published: lighten(#ff5718, 10%); @color-marked: #ffc069; @color-accent-marked : @color-accent; +@color-accent-published : darken(@color-published, 30%); @color-panel-bg: #f5f5f5; @color-checked: #69C671; @border-default : #ddd; diff --git a/themes/light/tt-rss.less b/themes/light/tt-rss.less index 12d3cea34..a39f6677b 100644 --- a/themes/light/tt-rss.less +++ b/themes/light/tt-rss.less @@ -646,7 +646,7 @@ body.ttrss_main { height : 14px; flex-shrink : 0; - &.aux, &.marked { + &.aux, &.marked, &.published { background : @color-panel-bg; color : lighten(@default-text, 10%); border-color : darken(@color-panel-bg, 10%); @@ -654,7 +654,12 @@ body.ttrss_main { &.marked { border-color : @color-accent-marked; - background : lighten(@color-accent-marked, 60%); + background : @default-bg; + } + + &.published { + border-color : @color-accent-published; + background : @default-bg; } } @@ -1141,18 +1146,36 @@ body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree { } } +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree { + .dijitTreeRow.Has_Published .dijitTreeLabel { + color : @color-accent-published; + } + .dijitTreeRow.Has_Published .counterNode.published { + display : inline-block; + } +} + body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Marked) { display : none; } +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree + .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Published) { + display : none; +} + body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Marked) { display : none; } +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree + .dijitTreeRow:not(.AlwaysVisible):not(.Has_Published) { + display : none; +} -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree { +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree { .dijitTreeRow.Unread .counterNode.unread { display : inline-block; } @@ -1161,12 +1184,12 @@ body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree { } } -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { display : none; } -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { display : none; } diff --git a/themes/night.css b/themes/night.css index b7c329921..7d3727c7a 100644 --- a/themes/night.css +++ b/themes/night.css @@ -562,14 +562,19 @@ body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNod flex-shrink: 0; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.aux, -body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked, +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { background: #222; color: #e6e6e6; border-color: #080808; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { border-color: #b87d2c; - background: #ffffff; + background: #333; +} +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { + border-color: #db8c6f; + background: #333; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow[data-feed-id="-3"][data-is-cat="false"] .counterNode.unread { background-color: #3ea447; @@ -959,22 +964,34 @@ body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Ma body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Marked .counterNode.marked { display: inline-block; } +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .dijitTreeLabel { + color: #db8c6f; +} +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .counterNode.published { + display: inline-block; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Marked) { display: none; } +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Published) { + display: none; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Marked) { display: none; } -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Published) { display: none; } -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { + display: none; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { display: none; } body.ttrss_main { @@ -2170,7 +2187,8 @@ body.flat.ttrss_main #feeds-holder { box-shadow: inset -1px 0px 2px -1px #666; } body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.aux, -body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked, +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.published { background: #222; color: #ccc; border-color: #333; @@ -2178,6 +2196,9 @@ body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { border-color: #b87d2c; } +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.published { + border-color: #db8c6f; +} body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .dijitTreeRowSelected { background: #333; border-color: #333 transparent; diff --git a/themes/night_base.less b/themes/night_base.less index a3945c856..a2670a997 100644 --- a/themes/night_base.less +++ b/themes/night_base.less @@ -4,6 +4,9 @@ @import "../lib/flat-ttrss/flat_combined_dark.css"; @color-accent: #b87d2c; +@color-accent-marked: @color-accent; +@color-accent-published: desaturate(@color-published, 40%); + @color-panel-bg : #222; @default-text: #ccc; @default-fg: @default-text; @@ -64,14 +67,21 @@ body.flat.ttrss_main { #feedTree { .dijitTreeRow { - .counterNode.aux, .counterNode.marked { - background: @color-panel-bg; - color: @default-text; - border-color: @default-bg; - } - .counterNode.marked { - border-color : @color-accent-marked; + .counterNode { + &.aux, &.marked, &.published { + background: @color-panel-bg; + color: @default-text; + border-color: @default-bg; + } + + &.marked { + border-color : @color-accent-marked; + } + + &.published { + border-color : @color-accent-published; + } } .dijitTreeRowSelected { diff --git a/themes/night_blue.css b/themes/night_blue.css index 50e285db7..a3c76ebb4 100644 --- a/themes/night_blue.css +++ b/themes/night_blue.css @@ -562,14 +562,19 @@ body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNod flex-shrink: 0; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.aux, -body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked, +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { background: #222; color: #e6e6e6; border-color: #080808; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.marked { border-color: #257aa7; - background: #ffffff; + background: #333; +} +body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow .counterNode.published { + border-color: #db8c6f; + background: #333; } body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .dijitTreeRow[data-feed-id="-3"][data-is-cat="false"] .counterNode.unread { background-color: #3ea447; @@ -959,22 +964,34 @@ body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Ma body.ttrss_main[view-mode="marked"] #feeds-holder #feedTree .dijitTreeRow.Has_Marked .counterNode.marked { display: inline-block; } +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .dijitTreeLabel { + color: #db8c6f; +} +body.ttrss_main[view-mode="published"] #feeds-holder #feedTree .dijitTreeRow.Has_Published .counterNode.published { + display: inline-block; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Marked) { display: none; } +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Special):not(.Has_Published) { + display: none; +} body.ttrss_main[view-mode="marked"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Marked) { display: none; } -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { - display: inline-block; -} -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { +body.ttrss_main[view-mode="published"][hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.AlwaysVisible):not(.Has_Published) { display: none; } -body.ttrss_main:not([view-mode="marked"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Unread .counterNode.unread { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"]) #feeds-holder #feedTree .dijitTreeRow.Has_Aux:not(.Unread) .counterNode.aux { + display: inline-block; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="true"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible):not(.Special) { + display: none; +} +body.ttrss_main:not([view-mode="marked"]):not([view-mode="published"])[hide-read-feeds="true"][hide-read-shows-special="false"] #feeds-holder #feedTree .dijitTreeRow:not(.Unread):not(.AlwaysVisible) { display: none; } body.ttrss_main { @@ -2170,7 +2187,8 @@ body.flat.ttrss_main #feeds-holder { box-shadow: inset -1px 0px 2px -1px #666; } body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.aux, -body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked, +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.published { background: #222; color: #ccc; border-color: #333; @@ -2178,6 +2196,9 @@ body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.marked { border-color: #257aa7; } +body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .counterNode.published { + border-color: #db8c6f; +} body.flat.ttrss_main #feeds-holder #feedTree .dijitTreeRow .dijitTreeRowSelected { background: #333; border-color: #333 transparent; diff --git a/utils/phpstan-watcher.sh b/utils/phpstan-watcher.sh index 5501588be..84554e68d 100755 --- a/utils/phpstan-watcher.sh +++ b/utils/phpstan-watcher.sh @@ -1,10 +1,10 @@ #!/bin/sh -export PHP_IMAGE=registry.fakecake.org/infra/php8.3-alpine3.20 +export PHP_IMAGE=registry.fakecake.org/infra/php8.4-alpine3.22 docker run --rm -v $(pwd):/app -v /tmp/phpstan:/tmp/phpstan \ --workdir /app ${PHP_IMAGE} \ - php83 -d memory_limit=-1 ./vendor/bin/phpstan --memory-limit=2G --error-format=raw analyze . + php84 -d memory_limit=-1 ./vendor/bin/phpstan --memory-limit=2G --error-format=raw analyze . echo All done, RC=$?. @@ -15,7 +15,7 @@ while true; do docker run --rm -v $(pwd):/app -v /tmp/phpstan:/tmp/phpstan \ --workdir /app ${PHP_IMAGE} \ - php83 -d memory_limit=-1 ./vendor/bin/phpstan --memory-limit=2G --error-format=raw analyze . + php84 -d memory_limit=-1 ./vendor/bin/phpstan --memory-limit=2G --error-format=raw analyze . echo All done, RC=$?. )