feat(i18n): katalog id/en — semua string UI via T()/Tf(), fallback en, TIA_LANG sementara + e2e English
CI / test (push) Successful in 24s
CI / test (push) Successful in 24s
This commit is contained in:
1 parent
76cdb0b5bb
commit
19ae0d1c29
13 files changed
+540
-76
No files matched your search
+28
-35
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"charm.land/lipgloss/v2"
|
||||
|
||||
"gitea.oxpoe.qzz.io/oxpoe/tia-love/internal/i18n"
|
||||
"gitea.oxpoe.qzz.io/oxpoe/tia-love/internal/ui/components"
|
||||
)
|
||||
|
||||
@@ -38,9 +39,9 @@ func (m Model) homeBody() string {
|
||||
k1 := int(float64(W) * 0.55)
|
||||
k2 := W - k1
|
||||
row2 := lipgloss.JoinHorizontal(lipgloss.Top,
|
||||
panel("Kontainer", fmt.Sprintf("%d total", len(m.containers)),
|
||||
panel(i18n.T("section.containers"), i18n.Tf("fmt.countTotal", len(m.containers)),
|
||||
m.miniContainerLines(row2H-2), k1, row2H, false),
|
||||
panel("Aktivitas", "Phase 2", activityLines(), k2, row2H, false),
|
||||
panel(i18n.T("section.activity"), i18n.Tf("fmt.phase", "2"), activityLines(), k2, row2H, false),
|
||||
)
|
||||
|
||||
return row1 + "\n" + row2
|
||||
@@ -52,31 +53,32 @@ func (m Model) clockPanel(w, h int) string {
|
||||
for i, r := range rows {
|
||||
rows[i] = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#cba6f7")).Render(r)
|
||||
}
|
||||
lines := append(rows, "", dim(" "+hariID(now)+", "+tanggalID(now)+" · "+now.Format("MST")))
|
||||
tanggal := fmt.Sprintf("%d %s %d", now.Day(), i18n.MonthName(now), now.Year())
|
||||
lines := append(rows, "", dim(" "+i18n.WeekdayName(now)+", "+tanggal+" · "+now.Format("MST")))
|
||||
if len(lines) > h-2 {
|
||||
lines = lines[:h-2]
|
||||
}
|
||||
return panel("Jam", "", lines, w, h, false)
|
||||
return panel(i18n.T("section.clock"), "", lines, w, h, false)
|
||||
}
|
||||
|
||||
func (m Model) dockerPanel(w, h int) string {
|
||||
var lines []string
|
||||
switch {
|
||||
case m.engineErr != nil:
|
||||
lines = append(lines, red("GAGAL"), "", dim(truncate(m.engineErr.Error(), w-6)))
|
||||
lines = append(lines, red(i18n.T("error.fail")), "", dim(truncate(m.engineErr.Error(), w-6)))
|
||||
case m.engine.ServerVersion == "":
|
||||
lines = append(lines, dim("memuat…"))
|
||||
lines = append(lines, dim(i18n.T("state.loading")))
|
||||
default:
|
||||
lines = append(lines,
|
||||
text("Engine ")+dim(m.engine.ServerVersion),
|
||||
text("API ")+dim(m.engine.APIVersion),
|
||||
text("Kontainer ")+dim(fmt.Sprintf("%d jalan / %d total", m.engine.Running, m.engine.Containers)),
|
||||
text("Image ")+dim(fmt.Sprintf("%d", m.engine.Images)),
|
||||
fieldW(i18n.T("field.engine"), 9)+dim(m.engine.ServerVersion),
|
||||
fieldW(i18n.T("field.api"), 9)+dim(m.engine.APIVersion),
|
||||
fieldW(i18n.T("section.containers"), 9)+dim(i18n.Tf("fmt.dockerContainers", m.engine.Running, m.engine.Containers)),
|
||||
fieldW(i18n.T("field.image"), 9)+dim(fmt.Sprintf("%d", m.engine.Images)),
|
||||
"",
|
||||
styled("#a6e3a1", "● terhubung"),
|
||||
styled("#a6e3a1", i18n.T("state.connected")),
|
||||
)
|
||||
}
|
||||
return panel("Docker", "lokal", lines, w, h, false)
|
||||
return panel("Docker", i18n.T("host.local"), lines, w, h, false)
|
||||
}
|
||||
|
||||
func (m Model) hostPanel(w, h int) string {
|
||||
@@ -90,21 +92,21 @@ func (m Model) hostPanel(w, h int) string {
|
||||
pct = int((s.MemTotal - s.MemAvail) * 100 / s.MemTotal)
|
||||
}
|
||||
lines := []string{
|
||||
text("Host ") + dim(m.hostname),
|
||||
text("CPU ") + dim(fmt.Sprintf("%d core · load %.2f", cpus, s.Load1)),
|
||||
text("RAM ") + dim(fmt.Sprintf("%3d%% ", pct)) + memBar(pct, 10) +
|
||||
fieldW(i18n.T("field.host"), 9) + dim(m.hostname),
|
||||
fieldW(i18n.T("field.cpu"), 9) + dim(i18n.Tf("fmt.coreLoad", cpus, s.Load1)),
|
||||
fieldW(i18n.T("field.ram"), 9) + dim(i18n.Tf("fmt.ramUsage", pct)) + memBar(pct, 10) +
|
||||
dim(fmt.Sprintf(" %s/%s", humanKBs(s.MemTotal-s.MemAvail), humanKBs(s.MemTotal))),
|
||||
text("Uptime ") + dim(humanDuration(s.Uptime)),
|
||||
fieldW(i18n.T("field.uptime"), 9) + dim(humanDuration(s.Uptime)),
|
||||
}
|
||||
return panel("Host", "", lines, w, h, false)
|
||||
return panel(i18n.T("section.host"), "", lines, w, h, false)
|
||||
}
|
||||
|
||||
func (m Model) miniContainerLines(maxLines int) []string {
|
||||
if m.loading && len(m.containers) == 0 {
|
||||
return []string{dim("memuat…")}
|
||||
return []string{dim(i18n.T("state.loading"))}
|
||||
}
|
||||
if len(m.containers) == 0 {
|
||||
return []string{dim("belum ada kontainer — tekan 1")}
|
||||
return []string{dim(i18n.T("hint.miniNoContainers"))}
|
||||
}
|
||||
max := maxLines
|
||||
if len(m.containers) > max {
|
||||
@@ -117,31 +119,22 @@ func (m Model) miniContainerLines(maxLines int) []string {
|
||||
lines = append(lines, styled(color, glyph)+" "+text(truncate(c.Name, 24))+" "+dim(truncate(c.Image, 32)))
|
||||
}
|
||||
if extra := len(m.containers) - len(lines); extra > 0 {
|
||||
lines = append(lines, dim(fmt.Sprintf("… %d lainnya (tekan 1)", extra)))
|
||||
lines = append(lines, dim(i18n.Tf("fmt.listMore", extra)))
|
||||
}
|
||||
return lines
|
||||
}
|
||||
|
||||
func activityLines() []string {
|
||||
return []string{
|
||||
dim("Listener Docker events menyusul (Phase 2)."),
|
||||
dim(i18n.T("activity.coming")),
|
||||
"",
|
||||
dim("Panel ini akan menampilkan 5 aktivitas terbaru:"),
|
||||
dim("kontainer start/stop, image di-pull, error terakhir."),
|
||||
dim(i18n.T("activity.willShow")),
|
||||
dim(i18n.T("activity.examples")),
|
||||
}
|
||||
}
|
||||
|
||||
// --- small formatting helpers ---
|
||||
|
||||
var hari = [...]string{"Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"}
|
||||
var bulan = [...]string{"Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"}
|
||||
|
||||
func hariID(t time.Time) string { return hari[int(t.Weekday())] }
|
||||
|
||||
func tanggalID(t time.Time) string {
|
||||
return fmt.Sprintf("%d %s %d", t.Day(), bulan[int(t.Month())-1], t.Year())
|
||||
}
|
||||
|
||||
func humanKB(kb uint64) string {
|
||||
f := float64(kb) * 1024
|
||||
units := []string{"B", "KB", "MB", "GB", "TB"}
|
||||
@@ -167,11 +160,11 @@ func humanDuration(sec float64) string {
|
||||
mins := int(d.Minutes()) % 60
|
||||
switch {
|
||||
case days > 0:
|
||||
return fmt.Sprintf("%d hari %d jam", days, hours)
|
||||
return i18n.Tf("duration.days", days, hours)
|
||||
case hours > 0:
|
||||
return fmt.Sprintf("%d jam %d mnt", hours, mins)
|
||||
return i18n.Tf("duration.hours", hours, mins)
|
||||
default:
|
||||
return fmt.Sprintf("%d mnt", mins)
|
||||
return i18n.Tf("duration.minutes", mins)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user