add invisable suspected flag

This commit is contained in:
Echo
2025-06-20 11:39:21 -04:00
parent 96fac4bbbb
commit 5ff01ae450
5 changed files with 154 additions and 18 deletions

View File

@@ -136,4 +136,113 @@
background-color: #1F2937; /* Match page background to make it appear to "cut through" */
padding: 0 0.2rem;
white-space: nowrap;
}
}
.user-trust-red {
background-color: rgba(239, 68, 68, 0.15) !important;
border-left: 3px solid rgb(239, 68, 68) !important;
}
.user-trust-green {
background-color: rgba(16, 185, 129, 0.15) !important;
border-left: 3px solid rgb(16, 185, 129) !important;
}
.user-trust-yellow {
background-color: rgba(245, 158, 11, 0.15) !important;
border-left: 3px solid rgb(245, 158, 11) !important;
}
.user-trust-blue {
background-color: rgba(59, 130, 246, 0.1) !important;
border-left: 3px solid rgb(59, 130, 246) !important;
}
.user-trust-indicator {
display: inline-block;
margin-left: 4px;
font-size: 0.875rem;
}
.conviction-hammer {
cursor: pointer;
margin-left: 6px;
padding: 2px 4px;
border-radius: 4px;
transition: background-color 0.2s;
}
.conviction-hammer:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.cm {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.cm-content {
background-color: #1F2937;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
width: 90%;
max-width: 500px;
}
.cm-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid #374151;
}
.cm-header h3 {
margin: 0;
color: #F3F4F6;
font-size: 1.25rem;
}
.cm-close {
background: none;
border: none;
color: #9CA3AF;
font-size: 1.5rem;
cursor: pointer;
}
.cm-body {
padding: 16px;
color: #D1D5DB;
}
.cos {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px;
margin-top: 16px;
}
.co {
background-color: #2D3748;
border: 1px solid #4B5563;
border-radius: 6px;
padding: 12px;
color: #E5E7EB;
font-size: 0.875rem;
cursor: pointer;
transition: background-color 0.2s;
text-align: center;
}
.co:hover {
background-color: #374151;
}

View File

@@ -21,12 +21,15 @@ export default class extends Controller {
<button type="button" class="co" data-value="red" data-level="1">
🔴 Convicted (1)
</button>
<button type="button" class="co" data-value="yellow" data-level="0">
🟡 Unscored (0)
<button type="button" class="co" data-value="blue" data-level="0">
🔵 Unscored (0)
</button>
<button type="button" class="co" data-value="green" data-level="2">
🟢 Trusted (2)
</button>
<button type="button" class="co" data-value="yellow" data-level="3">
🟡 Suspected (3) - Hidden
</button>
</div>
</div>
</div>
@@ -68,12 +71,14 @@ export default class extends Controller {
if (resp.ok) {
const cell = document.querySelector(`.admin-timeline-user-header-cell[data-user-id="${userId}"]`);
if (cell) {
cell.classList.remove('user-trust-red', 'user-trust-green');
cell.classList.remove('user-trust-red', 'user-trust-green', 'user-trust-yellow');
if (level === 'red') {
cell.classList.add('user-trust-red');
} else if (level === 'green') {
cell.classList.add('user-trust-green');
} else if (level === 'yellow') {
cell.classList.add('user-trust-yellow');
}
const indicator = cell.querySelector('.user-trust-indicator');
@@ -84,8 +89,13 @@ export default class extends Controller {
} else if (level === 'green') {
indicator.textContent = '🟢';
indicator.title = 'Trusted';
} else if (level === 'yellow') {
// For suspected users, show indicator only in admin UI
indicator.textContent = '🟡';
indicator.title = 'Suspected (Hidden from user)';
} else {
indicator.textContent = '';
// Blue/unscored
indicator.textContent = '🔵';
indicator.title = 'Unscored';
}
}

View File

@@ -21,12 +21,11 @@ class User < ApplicationRecord
end
enum :trust_level, {
yellow: 0,
red: 1,
green: 2
blue: 0, # unscored
red: 1, # convicted
green: 2, # trusted
yellow: 3 # suspected (invisible to user)
}
# yellow is unscored, red being convicted while green being trusted
# labels make it easier for display :okay-1:
def set_trust(level)
update!(trust_level: level)
@@ -422,10 +421,18 @@ class User < ApplicationRecord
"https://github.com/#{github_username}" if github_username.present?
end
# Returns users that are not convicted (red)
# For public APIs - includes blue, green, and yellow (suspected) users
def self.not_convicted
where.not(trust_level: User.trust_levels[:red])
end
# Returns only unscored (blue) and trusted (green) users
# Excludes suspected (yellow) and convicted (red) users
def self.not_suspect
where(trust_level: [ User.trust_levels[:blue], User.trust_levels[:green] ])
end
private
def invalidate_activity_graph_cache

View File

@@ -145,6 +145,8 @@
trust_level_class = "user-trust-red"
when "green"
trust_level_class = "user-trust-green"
when "yellow"
trust_level_class = "user-trust-yellow"
end
end
%>
@@ -170,9 +172,18 @@
style="font-size: 0.7rem; color: #9CA3AF; text-decoration: none;"
title="Set trust level">🔨</a>
<% end %>
<% if user.respond_to?(:trust_level) && user.trust_level != "yellow" %>
<% if user.respond_to?(:trust_level) %>
<span class="user-trust-indicator" data-user-conviction-target="trustIndicator" title="<%= user.trust_level.capitalize %>">
<%= user.trust_level == "red" ? "🔴" : "🟢" %>
<% case user.trust_level %>
<% when "red" %>
🔴
<% when "green" %>
🟢
<% when "yellow" %>
<20>
<% when "blue" %>
🔵
<% end %>
</span>
<% else %>
<span class="user-trust-indicator" data-user-conviction-target="trustIndicator"></span>
@@ -418,6 +429,11 @@
border-left: 3px solid #10B981;
}
.user-trust-yellow {
background-color: rgba(245, 158, 11, 0.08);
border-left: 3px solid #F59E0B;
}
.user-trust-indicator {
font-size: 0.75rem;
margin-left: 0.25rem;

View File

@@ -111,12 +111,6 @@ Get a user's trust factor.
}
```
Trust levels can be:
- `yellow` (0): unscored
- `red` (1): convicted/untrusted
- `green` (2): trusted
## Try These Examples
### See Your Recent Activity