mirror of
https://git.ptzo.gdn/feditools/relay.git
synced 2024-09-21 09:27:12 +00:00
display lists as columns (#171)
Reviewed-on: https://git.ptzo.gdn/feditools/relay/pulls/171 Co-authored-by: Tyr Mactire <tyr@pettingzoo.co> Co-committed-by: Tyr Mactire <tyr@pettingzoo.co>
This commit is contained in:
parent
f3d26c147f
commit
54fa199245
@ -9,5 +9,5 @@ const BlocksName = "blocks"
|
||||
type Blocks struct {
|
||||
Common
|
||||
|
||||
Blocks []*models.Block
|
||||
Blocks [][]*models.Block
|
||||
}
|
||||
|
@ -11,5 +11,5 @@ type Home struct {
|
||||
|
||||
HomeBody string
|
||||
|
||||
FollowingInstances []*models.Instance
|
||||
FollowingInstances [][]*models.Instance
|
||||
}
|
||||
|
@ -30,7 +30,8 @@ func (m *Module) BlocksGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
return
|
||||
}
|
||||
tmplVars.Blocks = blocks
|
||||
|
||||
tmplVars.Blocks = columnizer(blocks)
|
||||
|
||||
m.executeTemplate(w, r, template.BlocksName, tmplVars)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ func (m *Module) HomeGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
return
|
||||
}
|
||||
tmplVars.FollowingInstances = followingInstance
|
||||
tmplVars.FollowingInstances = columnizer(followingInstance)
|
||||
|
||||
// get metrics
|
||||
received, err := m.logic.MetricsGetReceivedTotalWeek(r.Context(), 7)
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"git.ptzo.gdn/feditools/relay/internal/path"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/sessions"
|
||||
"math"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -44,6 +45,65 @@ func (m *Module) authRequireLoggedIn(w http.ResponseWriter, r *http.Request) (*m
|
||||
return account, false
|
||||
}
|
||||
|
||||
// columnizer
|
||||
|
||||
func columnizer[L any](list []L) [][]L {
|
||||
colLens := columnizerColumnLen(len(list))
|
||||
|
||||
colList := make([][]L, len(colLens))
|
||||
for i := 0; i < len(colLens); i++ {
|
||||
newList := make([]L, colLens[i])
|
||||
|
||||
offset := 0
|
||||
for j := 0; j < i; j++ {
|
||||
offset = offset + colLens[j]
|
||||
}
|
||||
|
||||
for j := 0; j < colLens[i]; j++ {
|
||||
newList[j] = list[offset+j]
|
||||
}
|
||||
|
||||
colList[i] = newList
|
||||
}
|
||||
|
||||
return colList
|
||||
}
|
||||
|
||||
func columnizerColumns(count int) int {
|
||||
switch {
|
||||
case count == 0:
|
||||
return 0
|
||||
case 0 < count && count <= 20:
|
||||
return 1
|
||||
case 20 < count && count <= 40:
|
||||
return 2
|
||||
default:
|
||||
return 3
|
||||
}
|
||||
}
|
||||
|
||||
func columnizerColumnLen(count int) []int {
|
||||
columns := columnizerColumns(count)
|
||||
colCountFloat := float64(count) / float64(columns)
|
||||
colCount := int(colCountFloat)
|
||||
remainder := colCountFloat - float64(colCount)
|
||||
|
||||
columnsWithExtras := int(math.Round(float64(columns) * remainder))
|
||||
|
||||
colCounts := make([]int, columns)
|
||||
for i := 0; i < columns; i++ {
|
||||
if i < columnsWithExtras {
|
||||
colCounts[i] = colCount + 1
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
colCounts[i] = colCount
|
||||
}
|
||||
|
||||
return colCounts
|
||||
}
|
||||
|
||||
// metrics
|
||||
|
||||
func (m *Module) collectAdminStatistics(ctx context.Context, days int) (map[int]map[*models.Instance]logic.MetricsDataPointsTime, error) {
|
||||
|
201
internal/http/webapp/util_test.go
Normal file
201
internal/http/webapp/util_test.go
Normal file
@ -0,0 +1,201 @@
|
||||
package webapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestColumnizerColumns(t *testing.T) {
|
||||
//t.Parallel()
|
||||
|
||||
tables := []struct {
|
||||
in int
|
||||
out int
|
||||
}{
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 1},
|
||||
{3, 1},
|
||||
{4, 1},
|
||||
{5, 1},
|
||||
{6, 1},
|
||||
{7, 1},
|
||||
{8, 1},
|
||||
{9, 1},
|
||||
{10, 1},
|
||||
{11, 1},
|
||||
{12, 1},
|
||||
{13, 1},
|
||||
{14, 1},
|
||||
{15, 1},
|
||||
{16, 1},
|
||||
{17, 1},
|
||||
{18, 1},
|
||||
{19, 1},
|
||||
{20, 1},
|
||||
{21, 2},
|
||||
{22, 2},
|
||||
{23, 2},
|
||||
{24, 2},
|
||||
{25, 2},
|
||||
{26, 2},
|
||||
{27, 2},
|
||||
{28, 2},
|
||||
{29, 2},
|
||||
{30, 2},
|
||||
{31, 2},
|
||||
{32, 2},
|
||||
{33, 2},
|
||||
{34, 2},
|
||||
{35, 2},
|
||||
{36, 2},
|
||||
{37, 2},
|
||||
{38, 2},
|
||||
{39, 2},
|
||||
{40, 2},
|
||||
{41, 3},
|
||||
{42, 3},
|
||||
{43, 3},
|
||||
{44, 3},
|
||||
{45, 3},
|
||||
{46, 3},
|
||||
{47, 3},
|
||||
{48, 3},
|
||||
{49, 3},
|
||||
{50, 3},
|
||||
}
|
||||
|
||||
for i, table := range tables {
|
||||
i := i
|
||||
table := table
|
||||
|
||||
name := fmt.Sprintf("[%d] checking domain obfuscation", i)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
//t.Parallel()
|
||||
|
||||
if result := columnizerColumns(table.in); result != table.out {
|
||||
t.Errorf("wrong number of columnts, got: '%d', want: '%d'", result, table.out)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestColumnizerColumnLen(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tables := []struct {
|
||||
in int
|
||||
out []int
|
||||
}{
|
||||
{0, []int{}},
|
||||
{1, []int{1}},
|
||||
{2, []int{2}},
|
||||
{3, []int{3}},
|
||||
{4, []int{4}},
|
||||
{5, []int{5}},
|
||||
{6, []int{6}},
|
||||
{7, []int{7}},
|
||||
{8, []int{8}},
|
||||
{9, []int{9}},
|
||||
{10, []int{10}},
|
||||
{11, []int{11}},
|
||||
{12, []int{12}},
|
||||
{13, []int{13}},
|
||||
{14, []int{14}},
|
||||
{15, []int{15}},
|
||||
{16, []int{16}},
|
||||
{17, []int{17}},
|
||||
{18, []int{18}},
|
||||
{19, []int{19}},
|
||||
{20, []int{20}},
|
||||
{21, []int{11, 10}},
|
||||
{22, []int{11, 11}},
|
||||
{23, []int{12, 11}},
|
||||
{24, []int{12, 12}},
|
||||
{25, []int{13, 12}},
|
||||
{26, []int{13, 13}},
|
||||
{27, []int{14, 13}},
|
||||
{28, []int{14, 14}},
|
||||
{29, []int{15, 14}},
|
||||
{30, []int{15, 15}},
|
||||
{31, []int{16, 15}},
|
||||
{32, []int{16, 16}},
|
||||
{33, []int{17, 16}},
|
||||
{34, []int{17, 17}},
|
||||
{35, []int{18, 17}},
|
||||
{36, []int{18, 18}},
|
||||
{37, []int{19, 18}},
|
||||
{38, []int{19, 19}},
|
||||
{39, []int{20, 19}},
|
||||
{40, []int{20, 20}},
|
||||
{41, []int{14, 14, 13}},
|
||||
{42, []int{14, 14, 14}},
|
||||
{43, []int{15, 14, 14}},
|
||||
{44, []int{15, 15, 14}},
|
||||
{45, []int{15, 15, 15}},
|
||||
{46, []int{16, 15, 15}},
|
||||
{47, []int{16, 16, 15}},
|
||||
{48, []int{16, 16, 16}},
|
||||
{49, []int{17, 16, 16}},
|
||||
{50, []int{17, 17, 16}},
|
||||
{51, []int{17, 17, 17}},
|
||||
{52, []int{18, 17, 17}},
|
||||
{53, []int{18, 18, 17}},
|
||||
{54, []int{18, 18, 18}},
|
||||
{55, []int{19, 18, 18}},
|
||||
{56, []int{19, 19, 18}},
|
||||
{57, []int{19, 19, 19}},
|
||||
{58, []int{20, 19, 19}},
|
||||
{59, []int{20, 20, 19}},
|
||||
{60, []int{20, 20, 20}},
|
||||
{61, []int{21, 20, 20}},
|
||||
{62, []int{21, 21, 20}},
|
||||
{63, []int{21, 21, 21}},
|
||||
{64, []int{22, 21, 21}},
|
||||
{65, []int{22, 22, 21}},
|
||||
{66, []int{22, 22, 22}},
|
||||
{67, []int{23, 22, 22}},
|
||||
{68, []int{23, 23, 22}},
|
||||
{69, []int{23, 23, 23}},
|
||||
{70, []int{24, 23, 23}},
|
||||
{71, []int{24, 24, 23}},
|
||||
{72, []int{24, 24, 24}},
|
||||
{73, []int{25, 24, 24}},
|
||||
{74, []int{25, 25, 24}},
|
||||
{75, []int{25, 25, 25}},
|
||||
{76, []int{26, 25, 25}},
|
||||
{77, []int{26, 26, 25}},
|
||||
{78, []int{26, 26, 26}},
|
||||
{79, []int{27, 26, 26}},
|
||||
{80, []int{27, 27, 26}},
|
||||
}
|
||||
|
||||
for i, table := range tables {
|
||||
i := i
|
||||
table := table
|
||||
|
||||
name := fmt.Sprintf("[%d] checking domain obfuscation", i)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
result := columnizerColumnLen(table.in)
|
||||
|
||||
if len(result) != len(table.out) {
|
||||
t.Fatalf("wrong number of elements in slice, got: '%d', want: '%d'", len(result), len(table.out))
|
||||
}
|
||||
|
||||
for i := 0; i < len(result); i++ {
|
||||
if result[i] != table.out[i] {
|
||||
t.Errorf("wrong number of objects in column %d, got: '%d', want: '%d'", i, result[i], table.out[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkColumnizerColumnLen(b *testing.B) {
|
||||
// run the Fib function b.N times
|
||||
for n := 0; n < b.N; n++ {
|
||||
columnizerColumnLen(1000)
|
||||
}
|
||||
}
|
@ -13,17 +13,19 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<ul>
|
||||
{{- range $block := .Blocks }}
|
||||
{{- if $block.ObfuscatedDomain }}
|
||||
<li><span data-bs-toggle="tooltip" data-bs-placement="right" data-bs-title="{{ $block.UnicodeDomain }}" data-bs-custom-class="danger-tooltip">{{ $block.ObfuscatedDomain }}</span></li>
|
||||
{{- else }}
|
||||
<li>{{ $block.UnicodeDomain }}</li>
|
||||
{{- end }}
|
||||
{{- range $column := .Blocks }}
|
||||
<div class="col">
|
||||
<ul>
|
||||
{{- range $block := $column }}
|
||||
{{- if $block.ObfuscatedDomain }}
|
||||
<li><span data-bs-toggle="tooltip" data-bs-placement="right" data-bs-title="{{ $block.UnicodeDomain }}" data-bs-custom-class="danger-tooltip">{{ $block.ObfuscatedDomain }}</span></li>
|
||||
{{- else }}
|
||||
<li>{{ $block.UnicodeDomain }}</li>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</ul>
|
||||
</div>
|
||||
{{- end }}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.container -->
|
||||
{{ template "footer" . }}
|
||||
|
@ -37,9 +37,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{{- range $column := .FollowingInstances }}
|
||||
<div class="col">
|
||||
<ul>
|
||||
{{- range $instance := .FollowingInstances }}
|
||||
{{- range $instance := $column }}
|
||||
<li>
|
||||
{{- $instance }}
|
||||
{{- if $instance.IsPaused }} <span class="badge rounded-pill text-bg-secondary" lang="{{ $textPaused.Language }}">{{ $textPaused.Lower }}</span>{{end}}
|
||||
@ -47,6 +48,7 @@
|
||||
{{- end }}
|
||||
</ul>
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col mt-4">
|
||||
|
Loading…
Reference in New Issue
Block a user