mirror of
https://github.com/System-End/hackatime.git
synced 2026-04-19 21:05:15 +00:00
trust factor updates and more (#263)
Co-authored-by: ImgBotApp <ImgBotHelp@gmail.com>
This commit is contained in:
parent
433aeac3ac
commit
f7f2be553c
8 changed files with 71 additions and 44 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 16 KiB |
|
|
@ -34,7 +34,7 @@
|
|||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--primary-color);
|
||||
background-color: #4caf50;
|
||||
display: inline-block;
|
||||
margin-right: 0.2em;
|
||||
animation: pulse 2s infinite;
|
||||
|
|
@ -100,4 +100,4 @@
|
|||
.currently-hacking-header {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,14 @@ module ApplicationHelper
|
|||
country_code.tr("A-Z", "\u{1F1E6}-\u{1F1FF}")
|
||||
end
|
||||
|
||||
# infer country from timezone
|
||||
def timezone_to_country(timezone)
|
||||
return null unless timezone.present?
|
||||
tz = ActiveSupport::TimeZone[timezone]
|
||||
return null unless tz && tz.tzinfo.respond_to?(:country_code)
|
||||
tz.tzinfo.country_code || null
|
||||
end
|
||||
|
||||
def timezone_difference_in_seconds(timezone1, timezone2)
|
||||
return 0 if timezone1 == timezone2
|
||||
|
||||
|
|
|
|||
|
|
@ -1,57 +1,62 @@
|
|||
import { Controller } from "@hotwired/stimulus"
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["select"]
|
||||
static targets = ["select"];
|
||||
|
||||
connect() {
|
||||
this.selectTarget.addEventListener('change', this.handleChange.bind(this))
|
||||
this.selectTarget.addEventListener("change", this.handleChange.bind(this));
|
||||
}
|
||||
|
||||
async handleChange(event) {
|
||||
const userId = event.target.dataset.userId
|
||||
const trustLevel = event.target.value
|
||||
const userId = event.target.dataset.userId;
|
||||
const trustLevel = event.target.value;
|
||||
|
||||
if (!userId) {
|
||||
console.error('No user ID found in dataset')
|
||||
event.target.value = event.target.dataset.currentTrustLevel
|
||||
alert('Error: No user ID found. Please try again.')
|
||||
return
|
||||
console.error("No user ID found in dataset");
|
||||
event.target.value = event.target.dataset.currentTrustLevel;
|
||||
alert("Error: No user ID found. Please try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Updating trust level for user:', userId, 'to:', trustLevel)
|
||||
const url = new URL(`/users/${userId}/update_trust_level`, window.location.origin)
|
||||
console.log("Updating trust level for user:", userId, "to:", trustLevel);
|
||||
const url = new URL(
|
||||
`/users/${userId}/update_trust_level`,
|
||||
window.location.origin
|
||||
);
|
||||
const response = await fetch(url, {
|
||||
method: 'PATCH',
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-Token": document.querySelector('meta[name="csrf-token"]')
|
||||
.content,
|
||||
},
|
||||
body: JSON.stringify({ trust_level: trustLevel })
|
||||
})
|
||||
body: JSON.stringify({ trust_level: trustLevel }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to update trust level: ${response.status} ${response.statusText}`)
|
||||
throw new Error(
|
||||
`Failed to update trust level: ${response.status} ${response.statusText}`
|
||||
);
|
||||
}
|
||||
|
||||
// Update the current trust level in the dataset
|
||||
event.target.dataset.currentTrustLevel = trustLevel
|
||||
event.target.dataset.currentTrustLevel = trustLevel;
|
||||
|
||||
// Update the leaderboard entry's omitted class
|
||||
const leaderboardEntry = event.target.closest('.leaderboard-entry')
|
||||
const leaderboardEntry = event.target.closest(".leaderboard-entry");
|
||||
if (leaderboardEntry) {
|
||||
if (trustLevel === 'untrusted') {
|
||||
leaderboardEntry.classList.add('omitted')
|
||||
if (trustLevel === "red") {
|
||||
leaderboardEntry.classList.add("omitted");
|
||||
} else {
|
||||
leaderboardEntry.classList.remove('omitted')
|
||||
leaderboardEntry.classList.remove("omitted");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error updating trust level:', error)
|
||||
console.error("Error updating trust level:", error);
|
||||
// Revert the select to its previous value
|
||||
event.target.value = event.target.dataset.currentTrustLevel
|
||||
alert('Failed to update trust level. Please try again.')
|
||||
event.target.value = event.target.dataset.currentTrustLevel;
|
||||
alert("Failed to update trust level. Please try again.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,17 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
enum :trust_level, {
|
||||
default: 0,
|
||||
untrusted: 1,
|
||||
trusted: 2
|
||||
yellow: 0,
|
||||
red: 1,
|
||||
green: 2
|
||||
}
|
||||
# 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)
|
||||
end
|
||||
# ex: .set_trust(:green) or set_trust(1) setting it to red
|
||||
|
||||
has_many :heartbeats
|
||||
has_many :email_addresses, dependent: :destroy
|
||||
|
|
|
|||
|
|
@ -22,9 +22,6 @@
|
|||
Hackatime is totally free. Anyone can see the <a href="https://github.com/hackclub/hackatime" target="_blank">code</a>. It's like <a href="https://wakatime.com" target="_blank">WakaTime</a> but free and open source.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>🎯 How to Start</h3>
|
||||
<ol>
|
||||
<li><strong>Make an account</strong> at <a href="<%= root_url %>">hackatime.hackclub.com</a></li>
|
||||
|
|
@ -33,10 +30,11 @@
|
|||
<li><strong>Start coding</strong>: It tracks your time by itself!</li>
|
||||
</ol>
|
||||
|
||||
<p style="background: #f0f8ff; padding: 1rem; border-radius: 8px; border-left: 4px solid var(--primary);">
|
||||
<p id="tip-box" class="tip-box" style="background: #f0f8ff; padding: 1rem; border-radius: 8px; border-left: 4px solid var(--primary);">
|
||||
<strong>💡 Tip:</strong> The <a href="<%= my_wakatime_setup_path %>">setup page</a> does everything for you. No hard stuff to figure out!
|
||||
</p>
|
||||
|
||||
|
||||
<h3>🔌 What Code Editors Work</h3>
|
||||
<p>
|
||||
Hackatime works with <strong>any editor</strong> that has <a href="https://wakatime.com" target="_blank">WakaTime</a>. Just add the WakaTime plugin to your editor:
|
||||
|
|
@ -55,7 +53,7 @@
|
|||
<div>
|
||||
<strong>Lots More:</strong>
|
||||
<ul style="margin-top: 0.5rem;">
|
||||
<li><%= link_to "Atom", doc_path("editors/atom") %>, <%= link_to "Brackets", doc_path("editors/brackets") %></li>
|
||||
<li><%= link_to "Brackets", doc_path("editors/brackets") %></li>
|
||||
<li>All JetBrains apps</li>
|
||||
<li><%= link_to "Command Line", doc_path("editors/terminal") %></li>
|
||||
<li><a href="#supported-editors" onclick="document.getElementById('all-editors').parentElement.open = true; document.getElementById('all-editors').scrollIntoView({behavior: 'smooth'});">70+ others</a></li>
|
||||
|
|
@ -226,6 +224,16 @@
|
|||
<% end %>
|
||||
</div>
|
||||
</details>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.tip-box, #all-editors {
|
||||
background: #1a2233 !important;
|
||||
border-left-color: #4fd1c5 !important;
|
||||
color: #e6e6e6 !important;
|
||||
}
|
||||
.tip-box a { color: #4fd1c5 !important; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<hr style="margin: 2rem 0;">
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@
|
|||
<% if @entries&.any? %>
|
||||
<div class="leaderboard-entries">
|
||||
<% @entries.each_with_index do |entry, index| %>
|
||||
<div class="leaderboard-entry <%= 'current-user' if entry.user_id == current_user&.id %> <%= 'omitted' if entry.user.untrusted? && current_user&.admin? %>">
|
||||
<div class="leaderboard-entry <%= 'current-user' if entry.user_id == current_user&.id %> <%= 'omitted' if entry.user.red? && current_user&.admin? %>">
|
||||
<!-- in the future, convicted users will be hidden from public leaderboards -->
|
||||
<span class="rank">
|
||||
<% case index %>
|
||||
<% when 0 then %>
|
||||
|
|
@ -86,9 +87,9 @@
|
|||
data-trust-level-target="select"
|
||||
data-user-id="<%= entry.user.id %>"
|
||||
data-current-trust-level="<%= entry.user.trust_level %>">
|
||||
<option value="default" <%= 'selected' if entry.user.default? %>>Default</option>
|
||||
<option value="untrusted" <%= 'selected' if entry.user.untrusted? %>>Untrusted</option>
|
||||
<option value="trusted" <%= 'selected' if entry.user.trusted? %>>Trusted</option>
|
||||
<option value="yellow" <%= 'selected' if entry.user.yellow? %>>Yellow</option>
|
||||
<option value="red" <%= 'selected' if entry.user.red? %>>Red</option>
|
||||
<option value="green" <%= 'selected' if entry.user.green? %>>Green</option>
|
||||
</select>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1 @@
|
|||
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="256" cy="256" r="256" fill="red"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512"><circle cx="256" cy="256" r="256" fill="red"/></svg>
|
||||
|
Before Width: | Height: | Size: 122 B After Width: | Height: | Size: 117 B |
Loading…
Add table
Reference in a new issue