diff options
| author | Kyren223 <Kyren223@proton.me> | 2024-11-29 23:24:06 +0200 |
|---|---|---|
| committer | Kyren223 <Kyren223@proton.me> | 2024-11-29 23:24:06 +0200 |
| commit | 3fa1c902c1049f56b30092cf6de28c4d358cf434 (patch) | |
| tree | fb5de446cc6bd127cfe946d33c4812194e6f1f73 /internal | |
| parent | 371e6c169cd39d9abe5b8d9023d4e5d0025e47a1 (diff) | |
Implemented network positions per user on client and server
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/client/ui/core/networklist/networklist.go | 53 | ||||
| -rw-r--r-- | internal/packet/packet.go | 3 | ||||
| -rw-r--r-- | internal/packet/packet_test.go | 4 | ||||
| -rw-r--r-- | internal/packet/types.go | 14 | ||||
| -rw-r--r-- | internal/server/api/api.go | 17 | ||||
| -rw-r--r-- | internal/server/server.go | 19 |
6 files changed, 96 insertions, 14 deletions
diff --git a/internal/client/ui/core/networklist/networklist.go b/internal/client/ui/core/networklist/networklist.go index 8b01c1e..a3c5842 100644 --- a/internal/client/ui/core/networklist/networklist.go +++ b/internal/client/ui/core/networklist/networklist.go @@ -5,9 +5,11 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/kyren223/eko/internal/client/gateway" "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/internal/packet" ) var ( @@ -28,8 +30,9 @@ func IconStyle(icon string, fg, bg lipgloss.Color) lipgloss.Style { } type Model struct { - focus bool - index int + history []func(m *Model) + index int + focus bool } func New() Model { @@ -50,7 +53,7 @@ func (m Model) View() string { // top := strings.Repeat(border.Top, 6) // builder.WriteString(fmt.Sprintf("%s%s%s\n", border.TopLeft, top, border.TopRight)) builder.WriteString("\n") - if m.index == 0 { + if m.index == -1 { builder.WriteString(trustedUsersButtonSelected) } else { builder.WriteString(trustedUsersButton) @@ -58,7 +61,7 @@ func (m Model) View() string { builder.WriteString("\n") for i, network := range state.State.Networks { icon := IconStyle(network.Icon, lipgloss.Color(network.FgHexColor), lipgloss.Color(network.BgHexColor)) - if m.index == i+1 { + if m.index == i { builder.WriteString(lipgloss.JoinHorizontal(ui.Center, selectedIndicator, icon.Margin(0, 1, 1, 0).String())) } else { builder.WriteString(icon.Margin(0, 1, 1).String()) @@ -81,13 +84,33 @@ func (m Model) View() string { func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { switch msg := msg.(type) { + case *packet.SwapUserNetworks: + // Pop first by shifting to the left + copy(m.history, m.history[1:]) + m.history = m.history[:len(m.history)-1] + case *packet.Error: + if msg.PktType == packet.PacketSwapUserNetworks { + // Server failed, revert! + undo := m.history[len(m.history)-1] + m.history = m.history[:len(m.history)-1] + undo(&m) + } + case tea.KeyMsg: key := msg.String() switch key { + case "K": + if 0 < m.index { + return m.Swap(-1) + } + case "J": + if 0 < m.index && m.index < len(state.State.Networks)-1 { + return m.Swap(1) + } case "k": - m.index = max(0, m.index-1) + m.index = max(-1, m.index-1) case "j": - m.index = min(len(state.State.Networks), m.index+1) + m.index = min(len(state.State.Networks)-1, m.index+1) } } return m, nil @@ -100,3 +123,21 @@ func (m *Model) Focus() { func (m *Model) Blur() { m.focus = false } + +func (m Model) Swap(dir int) (Model, tea.Cmd) { + cmd := gateway.Send(&packet.SwapUserNetworks{ + Pos1: m.index, + Pos2: m.index + dir, + }) + tmp := state.State.Networks[m.index] + state.State.Networks[m.index] = state.State.Networks[m.index+dir] + state.State.Networks[m.index+dir] = tmp + m.index += dir + m.history = append(m.history, func(m *Model) { + m.index -= dir + tmp := state.State.Networks[m.index] + state.State.Networks[m.index] = state.State.Networks[m.index+dir] + state.State.Networks[m.index+dir] = tmp + }) + return m, cmd +} diff --git a/internal/packet/packet.go b/internal/packet/packet.go index 7476056..df31dd0 100644 --- a/internal/packet/packet.go +++ b/internal/packet/packet.go @@ -56,6 +56,7 @@ const ( PacketUpdateNetwork PacketTransferNetwork PacketDeleteNetwork + PacketSwapUserNetworks PacketSetNetworkUser PacketNetworksInfo @@ -194,6 +195,8 @@ func (p Packet) DecodedPayload() (Payload, error) { payload = &DeleteMessage{} case PacketDeleteNetwork: payload = &DeleteNetwork{} + case PacketSwapUserNetworks: + payload = &SwapUserNetworks{} case PacketEditMessage: payload = &EditMessage{} case PacketMessagesInfo: diff --git a/internal/packet/packet_test.go b/internal/packet/packet_test.go index 179527a..874d0bb 100644 --- a/internal/packet/packet_test.go +++ b/internal/packet/packet_test.go @@ -14,7 +14,7 @@ import ( ) func TestPacketEncodingDecoding(t *testing.T) { - testPacketEncodingDecoding(t, &Error{"Hello, World!"}) + testPacketEncodingDecoding(t, &Error{PktType: 0, Error: ""}) node := snowflake.NewNode(1) id := node.Generate() @@ -59,7 +59,7 @@ func TestPacketFramer(t *testing.T) { defer cancel() framer := NewFramer() - pkt := NewPacket(NewJsonEncoder(&Error{"Hello, World!"})) + pkt := NewPacket(NewJsonEncoder(&Error{PktType: 0, Error: ""})) length := len(pkt.data) count := 5 data := make([]byte, length*count) diff --git a/internal/packet/types.go b/internal/packet/types.go index e5dd88a..82b8397 100644 --- a/internal/packet/types.go +++ b/internal/packet/types.go @@ -6,7 +6,8 @@ import ( ) type Error struct { - Error string + Error string + PktType PacketType } func (m *Error) Type() PacketType { @@ -51,6 +52,15 @@ func (m *DeleteNetwork) Type() PacketType { return PacketDeleteNetwork } +type SwapUserNetworks struct { + Pos1 int + Pos2 int +} + +func (m *SwapUserNetworks) Type() PacketType { + return PacketSwapUserNetworks +} + type SetNetworkUser struct { Member *bool Admin *bool @@ -69,7 +79,7 @@ type FullNetwork struct { data.Network Frequencies []data.Frequency Members []data.GetNetworkMembersRow - Position int + Position int } type NetworksInfo struct { diff --git a/internal/server/api/api.go b/internal/server/api/api.go index 53ef76a..ec3adf9 100644 --- a/internal/server/api/api.go +++ b/internal/server/api/api.go @@ -220,3 +220,20 @@ func GetNetworksInfo(ctx context.Context, sess *session.Session) (packet.Payload return networksInfo, nil } + +// FIXME: Deletion of a network is not handled! it needs to be shifted like how it works with frequencies! +func SwapUserNetworks(ctx context.Context, sess *session.Session, request *packet.SwapUserNetworks) packet.Payload { + queries := data.New(db) + pos1, pos2 := int64(request.Pos1), int64(request.Pos2) + err := queries.SwapUserNetworks(ctx, data.SwapUserNetworksParams{ + Pos1: &pos1, + Pos2: &pos2, + UserID: sess.ID(), + }) + if err != nil { + log.Println("database error:", err) + return &internalError + } + + return request +} diff --git a/internal/server/server.go b/internal/server/server.go index 474be10..2ca0c2a 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -311,16 +311,27 @@ func processRequest(ctx context.Context, sess *session.Session, request packet.P // TODO: add a way to measure the time each request/response took and log it // Potentially even separate time for code vs DB operations + var response packet.Payload switch request := request.(type) { case *packet.CreateNetwork: - return timeout(20*time.Millisecond, api.CreateNetwork, ctx, sess, request) + response = timeout(20*time.Millisecond, api.CreateNetwork, ctx, sess, request) + case *packet.SwapUserNetworks: + response = timeout(5*time.Millisecond, api.SwapUserNetworks, ctx, sess, request) + case *packet.SendMessage: - return timeout(20*time.Millisecond, api.SendMessage, ctx, sess, request) + response = timeout(20*time.Millisecond, api.SendMessage, ctx, sess, request) case *packet.RequestMessages: - return timeout(50*time.Millisecond, api.RequestMessages, ctx, sess, request) + response = timeout(50*time.Millisecond, api.RequestMessages, ctx, sess, request) + default: - return &packet.Error{Error: "use of disallowed packet type for request"} + response = &packet.Error{Error: "use of disallowed packet type for request"} } + + if response, ok := response.(*packet.Error); ok { + response.PktType = request.Type() + } + + return response } func timeout[T packet.Payload]( |
