From 62baacc3f832d2844dac09386e8a98f5cf16fd32 Mon Sep 17 00:00:00 2001 From: Kai Wagner Date: Fri, 6 Feb 2026 13:52:28 +0100 Subject: [PATCH] changed read-row contrast and color, so it's easier to see what was read vs unread Signed-off-by: Kai Wagner --- app/assets/stylesheets/colors.css | 8 ++ app/assets/stylesheets/components/topics.css | 59 +++++++++++++- app/views/topics/_status_cell.html.slim | 82 ++++++++++---------- 3 files changed, 107 insertions(+), 42 deletions(-) diff --git a/app/assets/stylesheets/colors.css b/app/assets/stylesheets/colors.css index f6360a2..eae566c 100644 --- a/app/assets/stylesheets/colors.css +++ b/app/assets/stylesheets/colors.css @@ -53,6 +53,10 @@ --color-bg-card: var(--color-bg-container); --color-bg-card-hover: var(--color-gray-200); --color-bg-hover: var(--color-primary-2); + --color-bg-read-hover: var(--color-primary-3); + --color-bg-read: var(--color-primary-1); + --color-bg-unread: var(--color-primary-2); + --color-bg-unread-hover: var(--color-primary-3); --color-bg-sidebar: #f3f4ff; --color-bg-sidebar-header: var(--color-primary-2); --color-bg-table-header: var(--color-primary-2); @@ -144,6 +148,10 @@ --color-bg-card: var(--color-gray-100); --color-bg-card-hover: var(--color-gray-300); --color-bg-hover: var(--color-gray-300); + --color-bg-read-hover: var(--color-primary-5); + --color-bg-read: var(--color-primary-4); + --color-bg-unread: var(--color-primary-2); + --color-bg-unread-hover: var(--color-primary-3); --color-bg-sidebar: var(--color-primary-2); --color-bg-sidebar-header: var(--color-gray-100); --color-bg-table-header: var(--color-gray-100); diff --git a/app/assets/stylesheets/components/topics.css b/app/assets/stylesheets/components/topics.css index 0d61a4b..76cc91b 100644 --- a/app/assets/stylesheets/components/topics.css +++ b/app/assets/stylesheets/components/topics.css @@ -142,6 +142,13 @@ a.topic-icon { .status-border { border-left: 8px solid transparent; + position: relative; +} + +.topic-title-main, +.topic-title-mobile { + position: relative; + z-index: 1; } .status-border.status-new { @@ -279,10 +286,55 @@ a.topic-icon { } } +.topic-row.topic-new, +.topic-row.topic-reading { + background: var(--color-bg-unread); + + &:hover { + background: var(--color-bg-unread-hover); + } +} + +.topic-row.topic-reading { + background: var(--color-bg-read); + + &:hover { + background: var(--color-bg-read-hover); + } +} + .topic-row.topic-read { color: var(--color-text-muted); + background: var(--color-bg-read); + + &:hover { + background: var(--color-bg-read-hover); + } +} + +.topic-title-icons { + display: inline-flex; + align-items: center; + gap: var(--spacing-2); + position: relative; + padding: var(--spacing-2) var(--spacing-4) var(--spacing-2) var(--spacing-2); + align-self: stretch; + height: 100%; } +.status-border.has-new-replies::before { + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: var(--topic-new-replies-strip-width, 260px); + background: var(--color-bg-unread); + clip-path: polygon(0 0, 100% 0, calc(100% - 18px) 100%, 0 100%); + z-index: 0; +} + + .topic-icon-hover { display: none; position: absolute; @@ -376,9 +428,12 @@ a.topic-icon { .topic-title-main { - display: inline-flex; - align-items: center; + display: grid; + grid-auto-flow: column; + grid-auto-columns: max-content; + align-items: stretch; gap: var(--spacing-2); + height: 100%; } .topic-title-mobile { diff --git a/app/views/topics/_status_cell.html.slim b/app/views/topics/_status_cell.html.slim index 27d28de..9872064 100644 --- a/app/views/topics/_status_cell.html.slim +++ b/app/views/topics/_status_cell.html.slim @@ -1,30 +1,34 @@ - status = state[:status] || "new" +- reading_unread_count = nil +- if status.to_s == "reading" + - read_count = state[:read_count].to_i + - total_count = topic.message_count + - reading_unread_count = [total_count - read_count, 0].max - status_class = "status-#{status}" +- status_class = "#{status_class} has-new-replies" if status.to_s == "reading" && reading_unread_count.to_i.positive? - star_data = star_data || {} td.topic-title.status-border class=status_class id=dom_id(topic, "status_cell") data-label="Topic" - creator = topic.creator_display_alias - last_sender = topic.last_sender_person&.default_alias .topic-title-main - - if status.to_s == "reading" - - read_count = state[:read_count].to_i - - total_count = topic.message_count - - unread_count = [total_count - read_count, 0].max - - if unread_count.positive? - = link_to topic_path(topic, anchor: "first-unread"), class: "topic-icon topic-icon-reading", title: "Jump to first unread message (#{unread_count} unread)" do - i.fa-solid.fa-envelope - span.topic-icon-badge.topic-icon-badge-sup = unread_count - - else - .topic-icon.topic-icon-reading title="All messages read" - i.fa-solid.fa-envelope - = render partial: "topics/star_icon", locals: { topic: topic, star_data: star_data } - = render partial: "topics/note_icon", locals: { topic: topic, count: note_count.to_i } - = render partial: "topics/team_readers_icon", locals: { topic: topic, readers: team_readers } - - commitfest_summary = @commitfest_summaries&.dig(topic.id) - - if commitfest_summary - = render partial: "topics/commitfest_icon", locals: { summary: commitfest_summary } - - elsif topic.has_attachments? - .topic-icon title="Attachments" - i.fa-solid.fa-paperclip + .topic-title-icons + - if status.to_s == "reading" + - if reading_unread_count.to_i.positive? + = link_to topic_path(topic, anchor: "first-unread"), class: "topic-icon topic-icon-reading", title: "Jump to first unread message (#{reading_unread_count} unread)" do + i.fa-solid.fa-envelope + span.topic-icon-badge.topic-icon-badge-sup = reading_unread_count + - else + .topic-icon.topic-icon-reading title="All messages read" + i.fa-solid.fa-envelope + = render partial: "topics/star_icon", locals: { topic: topic, star_data: star_data } + = render partial: "topics/note_icon", locals: { topic: topic, count: note_count.to_i } + = render partial: "topics/team_readers_icon", locals: { topic: topic, readers: team_readers } + - commitfest_summary = @commitfest_summaries&.dig(topic.id) + - if commitfest_summary + = render partial: "topics/commitfest_icon", locals: { summary: commitfest_summary } + - elsif topic.has_attachments? + .topic-icon title="Attachments" + i.fa-solid.fa-paperclip = link_to topic.title, topic_path(topic), class: "topic-link" .topic-title-mobile = link_to topic.title, topic_path(topic), class: "topic-link" @@ -41,26 +45,24 @@ td.topic-title.status-border class=status_class id=dom_id(topic, "status_cell") .topic-row-footer .topic-footer-icons .topic-icons - - if status.to_s == "reading" - - read_count = state[:read_count].to_i - - total_count = topic.message_count - - unread_count = [total_count - read_count, 0].max - - if unread_count.positive? - = link_to topic_path(topic, anchor: "first-unread"), class: "topic-icon topic-icon-reading", title: "Jump to first unread message (#{unread_count} unread)" do - i.fa-solid.fa-envelope - span.topic-icon-badge.topic-icon-badge-sup = unread_count - - else - .topic-icon.topic-icon-reading title="All messages read" - i.fa-solid.fa-envelope - = render partial: "topics/star_icon", locals: { topic: topic, star_data: star_data } - = render partial: "topics/note_icon", locals: { topic: topic, count: note_count.to_i } - = render partial: "topics/team_readers_icon", locals: { topic: topic, readers: team_readers } - - commitfest_summary = @commitfest_summaries&.dig(topic.id) - - if commitfest_summary - = render partial: "topics/commitfest_icon", locals: { summary: commitfest_summary } - - elsif topic.has_attachments? - .topic-icon title="Attachments" - i.fa-solid.fa-paperclip + .topic-title-icons + - if status.to_s == "reading" + - if reading_unread_count.to_i.positive? + = link_to topic_path(topic, anchor: "first-unread"), class: "topic-icon topic-icon-reading", title: "Jump to first unread message (#{reading_unread_count} unread)" do + i.fa-solid.fa-envelope + span.topic-icon-badge.topic-icon-badge-sup = reading_unread_count + - else + .topic-icon.topic-icon-reading title="All messages read" + i.fa-solid.fa-envelope + = render partial: "topics/star_icon", locals: { topic: topic, star_data: star_data } + = render partial: "topics/note_icon", locals: { topic: topic, count: note_count.to_i } + = render partial: "topics/team_readers_icon", locals: { topic: topic, readers: team_readers } + - commitfest_summary = @commitfest_summaries&.dig(topic.id) + - if commitfest_summary + = render partial: "topics/commitfest_icon", locals: { summary: commitfest_summary } + - elsif topic.has_attachments? + .topic-icon title="Attachments" + i.fa-solid.fa-paperclip - replies_count = [topic.message_count - 1, 0].max .topic-footer-replies = pluralize(replies_count, "reply") .topic-footer-time title=absolute_time_display(topic.last_message_at) = smart_time_display(topic.last_message_at)