mirror of
https://github.com/System-End/hackatime.git
synced 2026-04-19 21:05:15 +00:00
218 lines
6.3 KiB
Ruby
218 lines
6.3 KiB
Ruby
module ApplicationHelper
|
|
def cache_stats
|
|
hits = Thread.current[:cache_hits] || 0
|
|
misses = Thread.current[:cache_misses] || 0
|
|
{ hits: hits, misses: misses }
|
|
end
|
|
|
|
def requests_per_second
|
|
rps = RequestCounter.per_second
|
|
rps == :high_load ? "lots of req/sec" : "#{rps} req/sec"
|
|
end
|
|
|
|
def global_requests_per_second
|
|
rps = RequestCounter.global_per_second
|
|
rps == :high_load ? "lots of req/sec" : "#{rps} req/sec (global)"
|
|
end
|
|
|
|
def current_theme
|
|
theme_name = current_user&.theme
|
|
return User::DEFAULT_THEME if theme_name.blank?
|
|
return theme_name if User.themes.key?(theme_name)
|
|
|
|
User::DEFAULT_THEME
|
|
end
|
|
|
|
def current_theme_color_scheme
|
|
User.theme_metadata(current_theme).fetch(:color_scheme, "dark")
|
|
end
|
|
|
|
def current_theme_color
|
|
User.theme_metadata(current_theme).fetch(:theme_color, "#c8394f")
|
|
end
|
|
|
|
def superadmin_tool(class_name = "", element = "div", **options, &block)
|
|
return unless current_user && (current_user.admin_level == "superadmin")
|
|
concat content_tag(element, class: "superadmin-tool #{class_name}", **options, &block)
|
|
end
|
|
|
|
def admin_tool(class_name = "", element = "div", **options, &block)
|
|
return unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin")
|
|
concat content_tag(element, class: "admin-tool #{class_name}", **options, &block)
|
|
end
|
|
|
|
def viewer_tool(class_name = "", element = "div", **options, &block)
|
|
return unless current_user && (current_user.admin_level == "viewer")
|
|
concat content_tag(element, class: "viewer-tool #{class_name}", **options, &block)
|
|
end
|
|
|
|
def dev_tool(class_name = "", element = "div", **options, &block)
|
|
return unless Rails.env.development?
|
|
concat content_tag(element, class: "dev-tool #{class_name}", **options, &block)
|
|
end
|
|
|
|
def country_to_emoji(country_code)
|
|
return "" unless country_code.present?
|
|
c = country_code.upcase.chars.map { |c| (0x1F1E6 + c.ord - "A".ord).to_s(16) }
|
|
t = c.join("-")
|
|
|
|
image_tag(
|
|
"https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/#{t}.svg",
|
|
alt: "#{country_code} flag",
|
|
class: "inline-block w-5 h-5 align-middle",
|
|
loading: "lazy"
|
|
)
|
|
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
|
|
|
|
tz1 = ActiveSupport::TimeZone[timezone1]
|
|
tz2 = ActiveSupport::TimeZone[timezone2]
|
|
|
|
tz1.utc_offset - tz2.utc_offset
|
|
end
|
|
|
|
def timezone_difference_in_words(timezone1, timezone2)
|
|
diff = timezone_difference_in_seconds(timezone1, timezone2)
|
|
msg = distance_of_time_in_words(0, diff)
|
|
|
|
if diff.zero?
|
|
"same timezone"
|
|
elsif diff.positive?
|
|
"It's currently #{Time.zone.now.in_time_zone(timezone1).strftime("%H:%M")} in #{timezone1} (#{msg} ahead of you)"
|
|
else
|
|
"It's currently #{Time.zone.now.in_time_zone(timezone1).strftime("%H:%M")} in #{timezone1} (#{msg} behind you)"
|
|
end
|
|
end
|
|
|
|
def visualize_git_url(url)
|
|
url.gsub("https://github.com/", "https://tkww0gcc0gkwwo4gc8kgs0sw.a.selfhosted.hackclub.com/")
|
|
end
|
|
|
|
def digital_time(time)
|
|
hours = time.to_i / 3600
|
|
minutes = (time.to_i % 3600) / 60
|
|
seconds = time.to_i % 60
|
|
|
|
[ hours, minutes, seconds ].map { |part| part.to_s.rjust(2, "0") }.join(":")
|
|
end
|
|
|
|
def short_time_simple(time)
|
|
hours = time.to_i / 3600
|
|
minutes = (time.to_i % 3600) / 60
|
|
|
|
return "0m" if hours.zero? && minutes.zero?
|
|
|
|
time_parts = []
|
|
time_parts << "#{hours}h" if hours.positive?
|
|
time_parts << "#{minutes}m" if minutes.positive?
|
|
time_parts.join(" ")
|
|
end
|
|
|
|
def short_time_detailed(time)
|
|
# ie. 5h 10m 10s
|
|
# ie. 10m 10s
|
|
# ie. 10m
|
|
hours = time.to_i / 3600
|
|
minutes = (time.to_i % 3600) / 60
|
|
seconds = time.to_i % 60
|
|
|
|
time_parts = []
|
|
time_parts << "#{hours}h" if hours.positive?
|
|
time_parts << "#{minutes}m" if minutes.positive?
|
|
time_parts << "#{seconds}s" if seconds.positive?
|
|
time_parts.join(" ")
|
|
end
|
|
|
|
def time_in_emoji(duration)
|
|
# ie. 15.hours => "🕒"
|
|
half_hours = duration.to_i / 1800
|
|
clocks = [
|
|
"🕛", "🕧",
|
|
"🕐", "🕜",
|
|
"🕑", "🕝",
|
|
"🕒", "🕞",
|
|
"🕓", "🕟",
|
|
"🕔", "🕠",
|
|
"🕕", "🕡",
|
|
"🕖", "🕢",
|
|
"🕗", "🕣",
|
|
"🕘", "🕤",
|
|
"🕙", "🕥",
|
|
"🕚", "🕦"
|
|
]
|
|
clocks[half_hours % clocks.length]
|
|
end
|
|
|
|
def human_interval_name(key, from: nil, to: nil)
|
|
if key.present? && Heartbeat.respond_to?(:humanize_range) && Heartbeat::RANGES.key?(key.to_sym)
|
|
Heartbeat.humanize_range(Heartbeat::RANGES[key.to_sym][:calculate].call)
|
|
elsif from.present? && to.present?
|
|
"#{from} to #{to}"
|
|
else
|
|
"All Time"
|
|
end
|
|
end
|
|
|
|
def display_editor_name(editor)
|
|
return "Unknown" if editor.blank?
|
|
|
|
case editor.downcase
|
|
when "vscode", "vs code" then "VS Code"
|
|
when "pycharm" then "PyCharm"
|
|
when "intellij", "intellijidea" then "IntelliJ IDEA"
|
|
when "webstorm" then "WebStorm"
|
|
when "phpstorm" then "PhpStorm"
|
|
when "datagrip" then "DataGrip"
|
|
when "ktexteditor" then "Kate"
|
|
when "android studio" then "Android Studio"
|
|
when "visual studio" then "Visual Studio"
|
|
when "sublime text" then "Sublime Text"
|
|
when "iterm2" then "iTerm2"
|
|
when "rubymine" then "RubyMine"
|
|
else editor.capitalize
|
|
end
|
|
end
|
|
|
|
def display_os_name(os)
|
|
return "Unknown" if os.blank?
|
|
|
|
case os.downcase
|
|
when "darwin" then "macOS"
|
|
when "macos" then "macOS"
|
|
when "wsl" then "WSL"
|
|
when "mozilla" then "Firefox"
|
|
else os.capitalize
|
|
end
|
|
end
|
|
|
|
def display_language_name(language)
|
|
LanguageUtils.display_name(language)
|
|
end
|
|
|
|
def language_color(language)
|
|
LanguageUtils.color(language)
|
|
end
|
|
|
|
def modal_open_button(modal_id, text, **options)
|
|
button_tag text, {
|
|
type: "button",
|
|
onclick: "document.getElementById('#{modal_id}')?.dispatchEvent(new CustomEvent('modal:open'))"
|
|
}.merge(options)
|
|
end
|
|
|
|
def safe_asset_path(asset_name, fallback: nil)
|
|
asset_path(asset_name)
|
|
rescue StandardError
|
|
fallback.present? ? asset_path(fallback) : asset_name
|
|
end
|
|
end
|