diff --git a/src/login/login.go b/src/login/login.go index 8e8d392..35f1cfd 100644 --- a/src/login/login.go +++ b/src/login/login.go @@ -438,6 +438,9 @@ var ( infoCol = lipgloss.Color("3") // yellow greenCol = lipgloss.Color("2") // green + cardBg = lipgloss.Color("0") // black card background + cardPad = 2 + avatarStyle = lipgloss.NewStyle().Foreground(accent) fieldBox = lipgloss.NewStyle(). @@ -481,6 +484,14 @@ func (m *Model) View() string { content := m.renderLayout() if m.width > 0 && m.height > 0 { + if m.automata != nil { + bg := m.automata.Frame() + var sb strings.Builder + sb.WriteString(bg) + sb.WriteString("\x1b[H") // cursor home before overlaying + sb.WriteString(overlayCenter(m.width, m.height, content)) + return sb.String() + } return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, content, ) @@ -488,17 +499,49 @@ func (m *Model) View() string { return content } +func overlayCenter(w, h int, content string) string { + lines := strings.Split(content, "\n") + cw := 0 + for _, l := range lines { + if lw := lipgloss.Width(l); lw > cw { + cw = lw + } + } + cx := (w - cw) / 2 + cy := (h - len(lines)) / 2 + if cx < 0 { + cx = 0 + } + if cy < 0 { + cy = 0 + } + + var sb strings.Builder + for i, line := range lines { + sb.WriteString(fmt.Sprintf("\x1b[%d;%dH", cy+i+1, cx+1)) + sb.WriteString(line) + } + return sb.String() +} + func (m *Model) renderLayout() string { - // top bar: power hints - top := m.renderPowerHints() + clock := m.renderClock() + + // top bar: power hints on left, clock on right + var topParts []string + topParts = append(topParts, m.renderPowerHints()) + if clock != "" { + topParts = append(topParts, clock) + } + top := strings.Join(topParts, " ") // avatar + form side by side avatar := m.renderAvatar() form := m.renderForm() mid := lipgloss.JoinHorizontal(lipgloss.Top, avatar, " ", form) - // DE switcher below - sw := m.renderSwitcherDots() + // DE switcher with specifier label + sw := m.renderSwitcher() // caps lock caps := m.renderCapsLock() @@ -536,7 +579,10 @@ func (m *Model) renderLayout() string { joined = pad + joined } } - return joined + return lipgloss.NewStyle(). + Background(cardBg). + Padding(cardPad, cardPad+2). + Render(joined) } func (m *Model) renderPowerHints() string { @@ -594,7 +640,12 @@ func (m *Model) renderForm() string { return lipgloss.JoinVertical(lipgloss.Left, userField, "", passField) } -func (m *Model) renderSwitcherDots() string { +func (m *Model) renderClock() string { + now := time.Now() + return powerHint.Render(now.Format("Mon Jan 02 15:04:05")) +} + +func (m *Model) renderSwitcher() string { if len(m.envs) == 0 { return swNeighbour.Align(lipgloss.Center).Render("no desktop environments found") } @@ -604,6 +655,9 @@ func (m *Model) renderSwitcherDots() string { var parts []string + // session specifier (like "x11", "wayland") + spec := swDot.Render(m.envs[m.selIdx].Kind + " ") + if cfg.ShowMovers && m.selIdx > 0 { parts = append(parts, swMover.Render(cfg.LeftMover+" ")) } @@ -636,7 +690,7 @@ func (m *Model) renderSwitcherDots() string { } dotLine := strings.Join(dots, " ") - return lipgloss.JoinVertical(lipgloss.Center, swLine, dotLine) + return lipgloss.JoinVertical(lipgloss.Center, spec, swLine, dotLine) } func (m *Model) renderCapsLock() string {