summaryrefslogtreecommitdiff
path: root/internal/client/ui/core
diff options
context:
space:
mode:
Diffstat (limited to 'internal/client/ui/core')
-rw-r--r--internal/client/ui/core/banlist/banlist.go12
-rw-r--r--internal/client/ui/core/chat/chat.go12
-rw-r--r--internal/client/ui/core/core.go61
-rw-r--r--internal/client/ui/core/helppopup.go22
-rw-r--r--internal/client/ui/core/memberlist/memberlist.go12
-rw-r--r--internal/client/ui/core/peerlist/peerlist.go205
-rw-r--r--internal/client/ui/core/state/state.go2
7 files changed, 293 insertions, 33 deletions
diff --git a/internal/client/ui/core/banlist/banlist.go b/internal/client/ui/core/banlist/banlist.go
index c6c0a46..96f9b23 100644
--- a/internal/client/ui/core/banlist/banlist.go
+++ b/internal/client/ui/core/banlist/banlist.go
@@ -95,19 +95,19 @@ func (m Model) View() string {
var userStyle lipgloss.Style
if isTrusted && keysMatch {
if ownerId == member.UserID {
- userStyle = ui.TrustedOwnerMemberStyle
+ userStyle = ui.TrustedOwnerStyle
} else if member.IsAdmin {
- userStyle = ui.TrustedAdminMemberStyle
+ userStyle = ui.TrustedAdminStyle
} else {
- userStyle = ui.TrustedNormalMemberStyle
+ userStyle = ui.TrustedMemberStyle
}
} else {
if ownerId == member.UserID {
- userStyle = ui.OwnerMemberStyle
+ userStyle = ui.OwnerStyle
} else if member.IsAdmin {
- userStyle = ui.AdminMemberStyle
+ userStyle = ui.AdminStyle
} else {
- userStyle = ui.NormalMemberStyle
+ userStyle = ui.UserStyle
}
}
memberName := state.State.Users[member.UserID].Name
diff --git a/internal/client/ui/core/chat/chat.go b/internal/client/ui/core/chat/chat.go
index 67079f9..c045c41 100644
--- a/internal/client/ui/core/chat/chat.go
+++ b/internal/client/ui/core/chat/chat.go
@@ -988,19 +988,19 @@ func (m *Model) renderHeader(message data.Message, selected bool) []byte {
var senderStyle lipgloss.Style
if isTrusted && keysMatch {
if ownerId == member.UserID {
- senderStyle = ui.TrustedOwnerMemberStyle
+ senderStyle = ui.TrustedOwnerStyle
} else if member.IsAdmin {
- senderStyle = ui.TrustedAdminMemberStyle
+ senderStyle = ui.TrustedAdminStyle
} else {
- senderStyle = ui.TrustedNormalMemberStyle
+ senderStyle = ui.TrustedMemberStyle
}
} else {
if ownerId == member.UserID {
- senderStyle = ui.OwnerMemberStyle
+ senderStyle = ui.OwnerStyle
} else if member.IsAdmin {
- senderStyle = ui.AdminMemberStyle
+ senderStyle = ui.AdminStyle
} else {
- senderStyle = ui.NormalMemberStyle
+ senderStyle = ui.UserStyle
}
}
diff --git a/internal/client/ui/core/core.go b/internal/client/ui/core/core.go
index 5898741..b5cd8ba 100644
--- a/internal/client/ui/core/core.go
+++ b/internal/client/ui/core/core.go
@@ -25,6 +25,7 @@ import (
"github.com/kyren223/eko/internal/client/ui/core/networkjoin"
"github.com/kyren223/eko/internal/client/ui/core/networklist"
"github.com/kyren223/eko/internal/client/ui/core/networkupdate"
+ "github.com/kyren223/eko/internal/client/ui/core/peerlist"
"github.com/kyren223/eko/internal/client/ui/core/state"
"github.com/kyren223/eko/internal/client/ui/core/usersettings"
"github.com/kyren223/eko/internal/client/ui/loadscreen"
@@ -76,6 +77,7 @@ type Model struct {
banReasonPopup *banreason.Model
banViewPopup *banview.Model
networkList networklist.Model
+ peerList peerlist.Model
frequencyList frequencylist.Model
memberList memberlist.Model
chat chat.Model
@@ -100,6 +102,7 @@ func New(privKey ed25519.PrivateKey, name string) Model {
banReasonPopup: nil,
banViewPopup: nil,
networkList: networklist.New(),
+ peerList: peerlist.New(),
frequencyList: frequencylist.New(),
memberList: memberlist.New(),
chat: chat.New(),
@@ -120,7 +123,12 @@ func (m Model) View() string {
}
networkList := m.networkList.View()
- leftSidebar := m.frequencyList.View()
+ var leftSidebar string
+ if m.networkList.Index() == networklist.PeersIndex {
+ leftSidebar = m.peerList.View()
+ } else {
+ leftSidebar = m.frequencyList.View()
+ }
chat := m.chat.View()
rightSidebar := m.memberList.View()
result := lipgloss.JoinHorizontal(lipgloss.Top, networkList, leftSidebar, chat, rightSidebar)
@@ -238,6 +246,7 @@ func (m *Model) updateConnected(msg tea.Msg) tea.Cmd {
// log.Println("sidebarWidth:", sidebarWidth)
// log.Println("chatWidth:", chatWidth)
+ m.peerList.SetWidth(sidebarWidth)
m.frequencyList.SetWidth(sidebarWidth)
m.memberList.SetWidth(sidebarWidth)
m.chat.SetWidth(chatWidth)
@@ -327,17 +336,21 @@ func (m *Model) updateConnected(msg tea.Msg) tea.Cmd {
}
case FocusLeftSidebar:
if !m.HasPopup() {
- networkId := state.NetworkId(m.networkList.Index())
- if networkId == nil {
- return nil
- }
- member := state.State.Members[*networkId][*state.UserID]
- if !member.IsAdmin {
+ if m.networkList.Index() == networklist.PeersIndex {
+ // TODO: add n keybind for receiver
+ } else {
+ networkId := state.NetworkId(m.networkList.Index())
+ if networkId == nil {
+ return nil
+ }
+ member := state.State.Members[*networkId][*state.UserID]
+ if !member.IsAdmin {
+ return nil
+ }
+ popup := frequencycreation.New(*networkId)
+ m.frequencyCreationPopup = &popup
return nil
}
- popup := frequencycreation.New(*networkId)
- m.frequencyCreationPopup = &popup
- return nil
}
}
@@ -404,7 +417,11 @@ func (m *Model) updateConnected(msg tea.Msg) tea.Cmd {
case FocusNetworkList:
m.helpPopup = NewHelpPopup(HelpNetworkList)
case FocusLeftSidebar:
- m.helpPopup = NewHelpPopup(HelpFrequencyList)
+ if m.networkList.Index() == networklist.PeersIndex {
+ m.helpPopup = NewHelpPopup(HelpPeerList)
+ } else {
+ m.helpPopup = NewHelpPopup(HelpFrequencyList)
+ }
case FocusChat:
if m.chat.Locked() {
m.helpPopup = NewHelpPopup(HelpVim)
@@ -510,9 +527,14 @@ func (m *Model) updateConnected(msg tea.Msg) tea.Cmd {
m.networkList, cmd = m.networkList.Update(msg)
cmds = append(cmds, cmd)
- m.frequencyList.SetNetworkIndex(m.networkList.Index())
- m.frequencyList, cmd = m.frequencyList.Update(msg)
- cmds = append(cmds, cmd)
+ if m.networkList.Index() == networklist.PeersIndex {
+ m.peerList, cmd = m.peerList.Update(msg)
+ cmds = append(cmds, cmd)
+ } else {
+ m.frequencyList.SetNetworkIndex(m.networkList.Index())
+ m.frequencyList, cmd = m.frequencyList.Update(msg)
+ cmds = append(cmds, cmd)
+ }
m.memberList.SetNetworkAndFrequency(m.networkList.Index(), m.frequencyList.Index())
m.memberList, cmd = m.memberList.Update(msg)
@@ -541,6 +563,7 @@ func (m *Model) move(direction int) {
switch m.focus {
case FocusNetworkList:
+ m.peerList.Blur()
m.frequencyList.Blur()
m.memberList.Blur()
m.chat.Blur()
@@ -549,13 +572,21 @@ func (m *Model) move(direction int) {
m.networkList.Blur()
m.memberList.Blur()
m.chat.Blur()
- m.frequencyList.Focus()
+ if m.networkList.Index() == networklist.PeersIndex {
+ m.frequencyList.Blur()
+ m.peerList.Focus()
+ } else {
+ m.peerList.Blur()
+ m.frequencyList.Focus()
+ }
case FocusChat:
+ m.peerList.Blur()
m.networkList.Blur()
m.memberList.Blur()
m.frequencyList.Blur()
m.chat.Focus()
case FocusRightSidebar:
+ m.peerList.Blur()
m.networkList.Blur()
m.frequencyList.Blur()
m.chat.Blur()
diff --git a/internal/client/ui/core/helppopup.go b/internal/client/ui/core/helppopup.go
index 74c9ef7..0e77607 100644
--- a/internal/client/ui/core/helppopup.go
+++ b/internal/client/ui/core/helppopup.go
@@ -34,6 +34,7 @@ var (
const (
HelpNetworkList = iota
+ HelpPeerList
HelpFrequencyList
HelpChat
HelpMemberList
@@ -75,6 +76,8 @@ func (m HelpPopup) View() string {
switch m.help {
case HelpNetworkList:
keymapLists = m.HelpNetworkList()
+ case HelpPeerList:
+ keymapLists = m.HelpPeerList()
case HelpFrequencyList:
keymapLists = m.HelpFrequencyList()
case HelpChat:
@@ -129,6 +132,8 @@ func (m HelpPopup) Title() string {
switch m.help {
case HelpNetworkList:
return "Network"
+ case HelpPeerList:
+ return "Signals"
case HelpFrequencyList:
return "Frequency"
case HelpChat:
@@ -194,6 +199,23 @@ func (m HelpPopup) HelpFrequencyList() [][]Keymap {
}}
}
+func (m HelpPopup) HelpPeerList() [][]Keymap {
+ return [][]Keymap{{
+ {"k", "Move up a user"},
+ {"j", "Move down a user"},
+ {"ctrl+u", "Move half a page up"},
+ {"ctrl+d", "Move half a page down"},
+ {"g", "Move to the top"},
+ {"G", "Move to the bottom"},
+ }, {
+ {"n", "New user conversation"},
+ {"c", "Close user conversation"},
+ {"T", "Trust/untrust user"},
+ {"B", "Block user"},
+ {"U", "Unblock user"},
+ }}
+}
+
func (m HelpPopup) HelpChat() [][]Keymap {
return [][]Keymap{{
{"k", "Move up a message"},
diff --git a/internal/client/ui/core/memberlist/memberlist.go b/internal/client/ui/core/memberlist/memberlist.go
index f6b3845..ee61868 100644
--- a/internal/client/ui/core/memberlist/memberlist.go
+++ b/internal/client/ui/core/memberlist/memberlist.go
@@ -104,19 +104,19 @@ func (m Model) View() string {
var userStyle lipgloss.Style
if isTrusted && keysMatch {
if ownerId == member.UserID {
- userStyle = ui.TrustedOwnerMemberStyle
+ userStyle = ui.TrustedOwnerStyle
} else if member.IsAdmin {
- userStyle = ui.TrustedAdminMemberStyle
+ userStyle = ui.TrustedAdminStyle
} else {
- userStyle = ui.TrustedNormalMemberStyle
+ userStyle = ui.TrustedMemberStyle
}
} else {
if ownerId == member.UserID {
- userStyle = ui.OwnerMemberStyle
+ userStyle = ui.OwnerStyle
} else if member.IsAdmin {
- userStyle = ui.AdminMemberStyle
+ userStyle = ui.AdminStyle
} else {
- userStyle = ui.NormalMemberStyle
+ userStyle = ui.UserStyle
}
}
memberName := m.Users()[member.UserID].Name
diff --git a/internal/client/ui/core/peerlist/peerlist.go b/internal/client/ui/core/peerlist/peerlist.go
new file mode 100644
index 0000000..b062cb2
--- /dev/null
+++ b/internal/client/ui/core/peerlist/peerlist.go
@@ -0,0 +1,205 @@
+package peerlist
+
+import (
+ "bytes"
+ "strings"
+
+ tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/lipgloss"
+ "github.com/kyren223/eko/internal/client/ui"
+ "github.com/kyren223/eko/internal/client/ui/colors"
+ "github.com/kyren223/eko/internal/client/ui/core/state"
+ "github.com/kyren223/eko/pkg/snowflake"
+)
+
+var (
+ sepStyle = lipgloss.NewStyle().Width(0).
+ Border(lipgloss.ThickBorder(), false, true, false, false)
+
+ nameStyle = lipgloss.NewStyle().
+ Padding(1).Align(lipgloss.Center).
+ Border(lipgloss.ThickBorder(), false, false, true)
+ networkIdStyle = lipgloss.NewStyle().
+ MarginBottom(1).Padding(1, 2).Align(lipgloss.Center).
+ Border(lipgloss.ThickBorder(), false, false, true)
+
+ margin = 2
+ padding = 1
+ peerStyle = lipgloss.NewStyle().
+ Margin(0, margin).Padding(0, padding).Align(lipgloss.Left)
+
+ symbolReadWrite = "󰖩 "
+ symbolReadOnly = "󱛂 "
+ symbolReadOnlyAdmin = "󰖩 "
+ symbolNoAccess = "󱚿 "
+ symbolNoAccessAdmin = "󱛀 "
+ symbolWidth = 2
+
+ widthWithoutUser = ((margin + padding) * 2) + symbolWidth
+
+ ellipsis = "…"
+
+ BackgroundStyle = lipgloss.NewStyle().Background(colors.BackgroundDim)
+)
+
+type Model struct {
+ base int
+ index int
+ focus bool
+ width int
+ height int
+}
+
+func New() Model {
+ return Model{
+ base: 0,
+ index: -1,
+ focus: false,
+ width: -1,
+ height: 1,
+ }
+}
+
+func (m Model) Init() tea.Cmd {
+ return nil
+}
+
+func (m Model) View() string {
+ peerStyle := peerStyle.Width(m.width - (margin * 2))
+ backgroundStyle := BackgroundStyle.Width(m.width)
+ maxUserWidth := m.width - widthWithoutUser
+
+ var builder strings.Builder
+
+ builder.WriteString(m.renderHeader())
+
+ builder.WriteString("\n")
+ peers := m.Peers()
+ upper := min(m.base+m.height, len(peers))
+ peers = peers[m.base:upper]
+ for i, peer := range peers {
+ peerStyle := peerStyle
+ if m.index == m.base+i {
+ peerStyle = peerStyle.Background(colors.BackgroundHighlight)
+ }
+
+ user := state.State.Users[peer]
+ trustedPublicKey, isTrusted := state.State.Trusteds[user.ID]
+ keysMatch := bytes.Equal(trustedPublicKey, user.PublicKey)
+
+ var userStyle lipgloss.Style
+ if isTrusted && keysMatch {
+ userStyle = ui.TrustedUserStyle
+ } else {
+ userStyle = ui.UserStyle
+ }
+
+ username := user.Name
+ username = userStyle.Render(username)
+ if isTrusted && !keysMatch {
+ username = ui.UntrustedSymbol + username
+ }
+
+ if lipgloss.Width(username) <= maxUserWidth {
+ username = lipgloss.NewStyle().
+ MaxWidth(maxUserWidth).
+ Render(username)
+ } else {
+ ellipsisStyle := lipgloss.NewStyle().
+ Background(peerStyle.GetBackground()).Foreground(userStyle.GetForeground())
+ username = lipgloss.NewStyle().
+ MaxWidth(maxUserWidth-1).
+ Render(username) + ellipsisStyle.Render(ellipsis)
+ }
+
+ builder.WriteString(backgroundStyle.Render(peerStyle.Render(username)))
+ builder.WriteString("\n")
+ }
+
+ sidebar := builder.String()
+ sep := sepStyle.Height(ui.Height)
+ if m.focus {
+ sep = sep.BorderForeground(colors.Focus)
+ }
+ result := lipgloss.JoinHorizontal(lipgloss.Top, sidebar, sep.String())
+
+ return BackgroundStyle.Render(result)
+}
+
+func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
+ // Calculate height for frequencies
+ m.height = ui.Height
+ m.height -= lipgloss.Height(m.renderHeader())
+ m.height -= 1
+ m.SetIndex(m.index)
+
+ switch msg := msg.(type) {
+ case tea.KeyMsg:
+ if !m.focus {
+ return m, nil
+ }
+
+ key := msg.String()
+ switch key {
+ case "k":
+ m.SetIndex(m.index - 1)
+ case "j":
+ m.SetIndex(m.index + 1)
+ case "g":
+ m.SetIndex(0)
+ case "G":
+ m.SetIndex(m.FrequenciesLength() - 1)
+ case "ctrl+u":
+ m.SetIndex(m.index - m.height/2)
+ case "ctrl+d":
+ m.SetIndex(m.index + m.height/2)
+
+ }
+ }
+
+ return m, nil
+}
+
+func (m *Model) Focus() {
+ m.focus = true
+}
+
+func (m *Model) Blur() {
+ m.focus = false
+}
+
+func (m Model) FrequenciesLength() int {
+ // TODO:
+ return len(state.State.Frequencies[0])
+}
+
+func (m Model) Peers() []snowflake.ID {
+ return state.Data.Peers
+}
+
+func (m *Model) Index() int {
+ return m.index
+}
+
+func (m *Model) SetIndex(index int) {
+ m.index = min(max(index, 0), m.FrequenciesLength()-1)
+ if m.index < m.base {
+ m.base = max(m.index, 0)
+ } else if m.index >= m.base+m.height {
+ m.base = 1 + m.index - m.height
+ }
+}
+
+func (m Model) renderHeader() string {
+ nameStyle := nameStyle.Background(colors.DarkerCyan).Foreground(colors.Turquoise).Width(m.width)
+ if m.focus {
+ nameStyle = nameStyle.BorderForeground(colors.Focus)
+ }
+ peersName := nameStyle.Render("User Signals")
+
+ return lipgloss.JoinVertical(0, peersName)
+}
+
+func (m *Model) SetWidth(width int) {
+ m.width = width
+}
diff --git a/internal/client/ui/core/state/state.go b/internal/client/ui/core/state/state.go
index 044de2b..c67fe04 100644
--- a/internal/client/ui/core/state/state.go
+++ b/internal/client/ui/core/state/state.go
@@ -45,10 +45,12 @@ var State state = state{
type UserData struct {
Networks []snowflake.ID
+ Peers []snowflake.ID
}
var Data UserData = UserData{
Networks: []snowflake.ID{},
+ Peers: []snowflake.ID{},
}
var UserID *snowflake.ID = nil