feat: show users top languages

feat: language icons
This commit is contained in:
Ferdinand Mütsch 2022-10-05 23:36:57 +02:00
parent 7a07c9d4fc
commit 1989a69926
10 changed files with 77 additions and 15 deletions

View File

@ -12,11 +12,12 @@ server:
public_url: http://localhost:3000 # required for links (e.g. password reset) in e-mail
app:
aggregation_time: '02:15' # time at which to run daily aggregation batch jobs
report_time_weekly: 'fri,18:00' # time at which to fan out weekly reports (format: '<weekday)>,<daytime>')
inactive_days: 7 # time of previous days within a user must have logged in to be considered active
import_batch_size: 50 # maximum number of heartbeats to insert into the database within one transaction
heartbeat_max_age: '4320h' # maximum acceptable age of a heartbeat (see https://pkg.go.dev/time#ParseDuration)
aggregation_time: '02:15' # time at which to run daily aggregation batch jobs
leaderboard_generation_time: '06:00;18:00' # time at which to run daily aggregation batch jobs
report_time_weekly: 'fri,18:00' # time at which to fan out weekly reports (format: '<weekday)>,<daytime>')
inactive_days: 7 # time of previous days within a user must have logged in to be considered active
import_batch_size: 50 # maximum number of heartbeats to insert into the database within one transaction
heartbeat_max_age: '4320h' # maximum acceptable age of a heartbeat (see https://pkg.go.dev/time#ParseDuration)
custom_languages:
vue: Vue
jsx: JSX

View File

@ -1,6 +1,9 @@
package view
import "github.com/muety/wakapi/models"
import (
"github.com/muety/wakapi/models"
"strings"
)
type LeaderboardViewModel struct {
User *models.User
@ -39,3 +42,30 @@ func (s *LeaderboardViewModel) ColorModifier(item *models.LeaderboardItem, princ
}
return "default"
}
func (s *LeaderboardViewModel) LangIcon(lang string) string {
// https://icon-sets.iconify.design/mdi/
langs := map[string]string{
"c": "c",
"c++": "cpp",
"cpp": "cpp",
"go": "go",
"haskell": "haskell",
"html": "html5",
"java": "java",
"javascript": "javascript",
"kotlin": "kotlin",
"lua": "lua",
"php": "php",
"python": "python",
"r": "r",
"ruby": "ruby",
"rust": "rust",
"swift": "swift",
"typescript": "typescript",
}
if match, ok := langs[strings.ToLower(lang)]; ok {
return "mdi:language-" + match
}
return ""
}

View File

@ -56,6 +56,9 @@ func DefaultTemplateFuncs() template.FuncMap {
"htmlSafe": func(html string) template.HTML {
return template.HTML(html)
},
"urlSafe": func(s string) template.URL {
return template.URL(s)
},
"avatarUrlTemplate": func() string {
return config.Get().App.AvatarURLTemplate
},

View File

@ -53,7 +53,23 @@ let icons = [
'ion:rocket',
'heroicons-solid:server',
'eva:checkmark-circle-2-fill',
'fluent:key-24-filled'
'fluent:key-24-filled',
'mdi:language-c',
'mdi:language-cpp',
'mdi:language-go',
'mdi:language-haskell',
'mdi:language-html5',
'mdi:language-java',
'mdi:language-javascript',
'mdi:language-kotlin',
'mdi:language-lua',
'mdi:language-php',
'mdi:language-python',
'mdi:language-r',
'mdi:language-ruby',
'mdi:language-rust',
'mdi:language-swift',
'mdi:language-typescript',
]
const output = path.normalize(path.join(__dirname, '../static/assets/js/icons.dist.js'))

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -69,6 +69,7 @@
<li><span class="iconify inline text-green-700" data-icon="eva:checkmark-circle-2-fill"></span> &nbsp; 100 % free and open-source</li>
<li><span class="iconify inline text-green-700" data-icon="eva:checkmark-circle-2-fill"></span> &nbsp; Built by developers for developers</li>
<li><span class="iconify inline text-green-700" data-icon="eva:checkmark-circle-2-fill"></span> &nbsp; Fancy statistics and plots</li>
<li><span class="iconify inline text-green-700" data-icon="eva:checkmark-circle-2-fill"></span> &nbsp; Public leaderboards</li>
<li><span class="iconify inline text-green-700" data-icon="eva:checkmark-circle-2-fill"></span> &nbsp; Cool badges for readmes</li>
<li><span class="iconify inline text-green-700" data-icon="eva:checkmark-circle-2-fill"></span> &nbsp; Weekly e-mail reports</li>
<li><span class="iconify inline text-green-700" data-icon="eva:checkmark-circle-2-fill"></span> &nbsp; Intuitive REST API</li>

View File

@ -37,7 +37,12 @@
<div class="flex space-x-2 mb-4">
{{ range $i, $key := (strslice .TopKeys 0 20) }}
<div class="inline-block">
<a href="leaderboard?by={{ $.By }}&key={{ $key }}" class="{{ if eq $.Key (lower $key) }} btn-primary {{ else }} btn-default {{ end }} btn-small cursor-pointer">{{ $key }}</a>
<a href="leaderboard?by={{ $.By }}&key={{ $key }}" class="{{ if eq $.Key (lower $key) }} btn-primary {{ else }} btn-default {{ end }} btn-small cursor-pointer">
{{ if and (eq (lower $.By) "language") ($.LangIcon $key) }}
<span class="align-middle leading-none"><span class="iconify inline text-white text-base" data-icon="{{ ($.LangIcon $key) | urlSafe }}"></span>&nbsp;</span>
{{ end }}
<span>{{ $key }}</span>
</a>
</div>
{{ end }}
</div>
@ -47,19 +52,24 @@
<ol>
{{ range $i, $item := .Items }}
<li class="px-4 py-2 my-2 rounded-md border-2 leaderboard-{{ ($.ColorModifier $item $.User) }} flex justify-between">
<div class="w-1/12"><strong># {{ $item.Rank }}</strong></div>
<div class="flex w-4/12 justify-start items-center space-x-4 text-ellipsis overflow-hidden whitespace-nowrap align-middle">
<div class="w-1/12 mr-1"><strong># {{ $item.Rank }}</strong></div>
<div class="flex w-3/12 mx-1 justify-start items-center space-x-4 align-middle">
{{ if avatarUrlTemplate }}
<img src="{{ $item.User.AvatarURL avatarUrlTemplate }}" width="24px" class="rounded-full border-green-700" alt="User Profile Avatar"/>
{{ else }}
<span class="iconify inline cursor-pointer text-gray-500 rounded-full border-green-700" style="width: 24px; height: 24px" data-icon="ic:round-person"></span>
{{ end }}
<strong>@{{ $item.UserID }}</strong>
<strong class="text-ellipsis truncate">@{{ $item.UserID }}</strong>
</div>
<span class="w-4/12 text-sm text-ellipsis overflow-hidden whitespace-nowrap leading-6 align-middle">
{{ join (index $.UserLanguages $item.UserID) ", " }}
<span class="w-5/12 mx-1 truncate leading-6 align-middle">
{{ range $i, $lang := (index $.UserLanguages $item.UserID) }}
{{ if $.LangIcon $lang }}
<span class="align-middle leading-none"><span class="iconify inline text-white text-base" data-icon="{{ ($.LangIcon $lang) | urlSafe }}"></span></span>
{{ end }}
<span class="text-sm leading-6">{{ $lang }}{{ if lt $i (add (len (index $.UserLanguages $item.UserID)) -1) }},&nbsp;{{ end }}</span>
{{ end }}
</span>
<div class="w-3/12 text-right"><span>{{ $item.Total | duration }}</span></div>
<div class="w-3/12 ml-1 text-right"><span>{{ $item.Total | duration }}</span></div>
</li>
{{ end }}
</ol>