Skip to content

Commit 858c9d6

Browse files
authored
Merge branch 'main' into lag_fix
2 parents 3cb6569 + 1437282 commit 858c9d6

File tree

4 files changed

+109
-34
lines changed

4 files changed

+109
-34
lines changed

app/controllers/api/v1/stats_controller.rb

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,39 @@ def user_stats
6161
service_params[:scope] = scope if scope.present?
6262

6363
if params[:total_seconds] == "true"
64-
service_params[:boundary_aware] = params[:boundary_aware] == "true"
64+
query = @user.heartbeats
65+
.coding_only
66+
.with_valid_timestamps
67+
.where(time: start_date..end_date)
68+
69+
if params[:filter_by_project].present?
70+
filter_by_project = params[:filter_by_project].split(",")
71+
query = query.where(project: filter_by_project)
72+
end
73+
74+
# do the boundary thingie if requested
75+
use_boundary_aware = params[:boundary_aware] == "true"
76+
total_seconds = if use_boundary_aware
77+
Heartbeat.duration_seconds_boundary_aware(query, start_date.to_f, end_date.to_f) || 0
78+
else
79+
query.duration_seconds || 0
80+
end
6581

66-
summary = WakatimeService.new(**service_params).generate_summary
67-
return render json: { total_seconds: summary[:total_seconds] }
82+
return render json: { total_seconds: total_seconds }
6883
end
6984

7085
summary = WakatimeService.new(**service_params).generate_summary
7186

87+
if params[:features]&.include?("projects") && params[:filter_by_project].present?
88+
filter_by_project = params[:filter_by_project].split(",")
89+
heartbeats = @user.heartbeats
90+
.coding_only
91+
.with_valid_timestamps
92+
.where(time: start_date..end_date, project: filter_by_project)
93+
unique_seconds = unique_heartbeat_seconds(heartbeats)
94+
summary[:unique_total_seconds] = unique_seconds
95+
end
96+
7297
trust_level = @user.trust_level
7398
trust_level = "blue" if trust_level == "yellow"
7499
trust_value = User.trust_levels[trust_level]
@@ -275,4 +300,19 @@ def get_project(names)
275300

276301
data.sort_by { |project| -project[:total_seconds] }
277302
end
303+
304+
def unique_heartbeat_seconds(heartbeats)
305+
timestamps = heartbeats.order(:time).pluck(:time)
306+
return 0 if timestamps.empty?
307+
308+
total_seconds = 0
309+
timestamps.each_cons(2) do |prev_time, curr_time|
310+
gap = curr_time - prev_time
311+
if gap > 0 && gap <= 2.minutes
312+
total_seconds += gap
313+
end
314+
end
315+
316+
total_seconds.to_i
317+
end
278318
end

docs/editors/roblox-studio.md

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,77 @@
1-
# Roblox Studio Setup Guide
1+
# Set Up Hackatime with Roblox Studio
22

33
![Roblox Studio](/images/editor-icons/roblox-studio-128.png)
44

5-
Follow these steps to start tracking your game development in Roblox Studio with Hackatime.
5+
This guide will walk you through setting up **Hackatime** to automatically track your game development time in **Roblox Studio**.
66

7-
## Step 1: Log into Hackatime
7+
---
88

9-
Make sure you have a [Hackatime account](https://hackatime.hackclub.com) and are logged in.
9+
## Step 1: Log In to Your Hackatime Account
1010

11-
## Step 2: Run the Setup Script
11+
First, make sure you have a **Hackatime account** and are logged in. If you don't have an account, you can create one at [hackatime.hackclub.com](https://hackatime.hackclub.com).
1212

13-
Visit the [setup page](https://hackatime.hackclub.com/my/wakatime_setup) to automatically configure your API key and endpoint. This ensures everything works perfectly with Hackatime.
13+
---
1414

15-
## Step 3: Install Roblox Studio Plugin
15+
## Step 2: Install the Hackatime Roblox Studio Plugin
1616

17-
Follow the detailed plugin installation instructions on the [WakaTime Roblox Studio page](https://wakatime.com/roblox-studio).
17+
Next, you'll need to install the Hackatime plugin directly within Roblox Studio:
1818

19-
The WakaTime plugin will automatically use your Hackatime configuration after running the setup script.
19+
1. Open **Roblox Studio**.
20+
2. Navigate to the **Toolbox**.
21+
3. In the Toolbox search bar, select **"Plugins"** from the dropdown filter.
22+
4. Search for **"HackaTime Roblox"**.
23+
5. Install the plugin published by **"ThisWhity"**.
24+
25+
![Toolbox filter showing Plugins selected](https://github.com/user-attachments/assets/65931fad-fa16-4df6-9a07-eadf1e2aaf07)
26+
*Filter the Toolbox by "Plugins"*
27+
28+
![Toolbox search results showing HackaTime Roblox plugin](https://github.com/user-attachments/assets/13233bf7-b876-4c29-b690-9ebbcb796488)
29+
*Install the "HackaTime Roblox" plugin by ThisWhity*
30+
31+
---
32+
33+
## Step 3: Configure the Plugin with Your API Key
34+
35+
Now, you'll connect the plugin to your Hackatime account using your unique API key:
36+
37+
1. Get your API key by visiting [hackatime.hackclub.com/my/wakatime_setup](https://hackatime.hackclub.com/my/wakatime_setup). It will look something like this: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`.
38+
39+
![Screenshot showing API Key on Hackatime website](https://github.com/user-attachments/assets/635cab06-36cb-4351-819b-62403b6c6885)
40+
*Your API key from the Hackatime website*
41+
42+
2. In Roblox Studio, open the **Hackatime plugin**. You'll usually find it under the "Plugins" tab in the Ribbon bar.
43+
44+
![Screenshot showing the Hackatime plugin tab with API key input](https://github.com/user-attachments/assets/c241dbe2-6f9a-44bf-adb9-f0b4780227db)
45+
*Open the Plugin*
46+
47+
4. Paste your API key into the API key box. And hit "Save API Key"
48+
49+
---
2050

2151
## Troubleshooting
2252

23-
- **Not seeing your time?** Make sure you completed the [setup page](https://hackatime.hackclub.com/my/wakatime_setup) first
24-
- **Plugin not working?** Try restarting Roblox Studio after installation
25-
- **Still stuck?** Ask for help in [Hack Club Slack](https://hackclub.slack.com) (#hackatime-v2 channel)
53+
### ERR\_NETWORK: Plugin Cannot Connect to Hackatime
54+
55+
If you see an **ERR\_NETWORK** message, it means the plugin can't connect to Hackatime. This is likely due to you not allowing HTTP request from the plugin:
56+
57+
1. Open the "Manage Plugins".
58+
2. Hit the edit icon.
59+
3. Ensure that **"hackatime.hackclub.com"** is enabled.
60+
61+
![Screenshot showing Game Settings with Security tab open and Allow HTTP Requests highlighted](https://github.com/user-attachments/assets/c3533d87-2b06-4ba8-a1c5-7416332578e9)
62+
*Open Plugin Managment*
63+
64+
![Screenshot showing Allow HTTP Requests enabled](https://github.com/user-attachments/assets/86bea3e2-dbbe-496f-acd4-f5963c208767)
65+
*Allow HTTP requests*
66+
67+
### Still Stuck?
68+
69+
If you're still experiencing issues, don't hesitate to ask for help in the **#hackatime-v2 channel** on the [Hack Club Slack](https://hackclub.slack.com).
70+
71+
---
72+
73+
## What's Next?
2674

27-
## Next Steps
75+
Once the plugin is successfully configured, your Roblox Studio activity time will automatically start appearing on your [Hackatime dashboard](https://hackatime.hackclub.com).
2876

29-
Once configured, your activity time will automatically appear on your [Hackatime dashboard](https://hackatime.hackclub.com). Happy game developing!
77+
Happy game developing!

lib/flavor_text.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ def self.motto
220220
"#{%w[est created inited].sample} <span id='init-time-ago'>#{Time.now.to_i - Time.parse("Sun Feb 16 03:21:30 2025 -0500").to_i}</span> seconds ago!<script>setInterval(()=>{document.getElementById('init-time-ago').innerHTML=parseInt(document.getElementById('init-time-ago').innerHTML)+1},1000)</script>".html_safe,
221221
"uptime: <span id='uptime'>#{Time.now.to_i - Rails.application.config.server_start_time.to_i}</span> seconds!<script>setInterval(()=>{document.getElementById('uptime').innerHTML=parseInt(document.getElementById('uptime').innerHTML)+1},1000)</script>".html_safe,
222222
"It takes a long time to build something good: <a href='https://github.com/hackclub/hackatime#readme' target='_blank'><img src='https://hackatime-badge.hackclub.com/U0C7B14Q3/harbor'></a>".html_safe,
223-
"If you're seeing this, the page is currently <a href='https://status.hackatime.hackclub.com/status/hackatime' target='_blank'><img src='https://status.hackatime.hackclub.com/api/badge/1/status'></a>.".html_safe,
223+
"If you're seeing this, the page is currently <a href='https://status.hackatime.hackclub.com/status/hackatime' target='_blank'><img src='https://status.hackatime.hackclub.com/api/badge/1/status'></a>".html_safe,
224224
"time is money!",
225225
"in soviet russia, time tracks you!",
226226
"tick tock!",

lib/wakatime_service.rb

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
include ApplicationHelper
22

33
class WakatimeService
4-
def initialize(user: nil, specific_filters: [], allow_cache: true, limit: 10, start_date: nil, end_date: nil, scope: nil, boundary_aware: false)
4+
def initialize(user: nil, specific_filters: [], allow_cache: true, limit: 10, start_date: nil, end_date: nil, scope: nil)
55
@scope = scope || Heartbeat.all
66
@user = user
7-
@boundary_aware = boundary_aware
87

98
@start_date = convert_to_unix_timestamp(start_date)
109
@end_date = convert_to_unix_timestamp(end_date)
1110

12-
# apply with_valid_timestamps filter if no custom scope provided-- this is copied from query in stats_controller
13-
if scope.nil?
14-
@scope = @scope.with_valid_timestamps
15-
end
16-
1711
# Default to 1 year ago if no start_date provided or if no data exists
1812
@start_date = @start_date || @scope.minimum(:time) || 1.year.ago.to_i
1913
@end_date = @end_date || @scope.maximum(:time) || Time.current.to_i
2014

21-
@scope = @scope.where(time: @start_date..@end_date)
15+
@scope = @scope.where("time >= ? AND time < ?", @start_date, @end_date)
2216

2317
@limit = limit
2418
@limit = nil if @limit&.zero?
@@ -47,14 +41,7 @@ def generate_summary
4741
summary[:range] = "all_time"
4842
summary[:human_readable_range] = "All Time"
4943

50-
@total_seconds = if @boundary_aware
51-
result = Heartbeat.duration_seconds_boundary_aware(@scope, @start_date, @end_date) || 0
52-
result
53-
else
54-
result = @scope.duration_seconds || 0
55-
result
56-
end
57-
44+
@total_seconds = @scope.duration_seconds || 0
5845
summary[:total_seconds] = @total_seconds
5946

6047
@total_days = (@end_time - @start_time) / 86400

0 commit comments

Comments
 (0)