diff options
| author | Kyren223 <Kyren223@proton.me> | 2025-02-12 13:08:49 +0200 |
|---|---|---|
| committer | Kyren223 <Kyren223@proton.me> | 2025-02-12 13:08:49 +0200 |
| commit | 66983fb02847dc9b1c53916da0dc7ad5a09f6644 (patch) | |
| tree | 897301226bcb87bf6a7d2b823e74abecabece680 /internal/client/ui | |
| parent | 976d3683f963b6f9282a534e1b4fec2411b738a2 (diff) | |
Added blocking/unblocking of users using b/u (user settings are now s
instead of "u")
Diffstat (limited to 'internal/client/ui')
| -rw-r--r-- | internal/client/ui/core/chat/chat.go | 224 | ||||
| -rw-r--r-- | internal/client/ui/core/core.go | 4 | ||||
| -rw-r--r-- | internal/client/ui/core/memberlist/memberlist.go | 5 | ||||
| -rw-r--r-- | internal/client/ui/core/signallist/signallist.go | 57 | ||||
| -rw-r--r-- | internal/client/ui/core/state/state.go | 29 | ||||
| -rw-r--r-- | internal/client/ui/ui.go | 2 |
6 files changed, 211 insertions, 110 deletions
diff --git a/internal/client/ui/core/chat/chat.go b/internal/client/ui/core/chat/chat.go index 4cba8e8..07fc679 100644 --- a/internal/client/ui/core/chat/chat.go +++ b/internal/client/ui/core/chat/chat.go @@ -29,10 +29,10 @@ var ( focusStyle = func() lipgloss.Style { return lipgloss.NewStyle().Background(colors.Background).Foreground(colors.Focus) } - readOnlyStyle = func() lipgloss.Style { + grayStyle = func() lipgloss.Style { return lipgloss.NewStyle().Background(colors.Background).Foreground(colors.Gray) } - mutedStyle = func() lipgloss.Style { return lipgloss.NewStyle().Background(colors.Background).Foreground(colors.Red) } + redStyle = func() lipgloss.Style { return lipgloss.NewStyle().Background(colors.Background).Foreground(colors.Red) } editStyle = func() lipgloss.Style { return lipgloss.NewStyle().Background(colors.Background).Foreground(colors.Gold) } @@ -45,8 +45,8 @@ var ( Padding(0, 1) } ViFocusedBorder = func() lipgloss.Style { return ViBlurredBorder().BorderForeground(colors.Focus) } - ViReadOnlyBorder = func() lipgloss.Style { return ViBlurredBorder().BorderForeground(colors.Gray) } - ViMutedBorder = func() lipgloss.Style { return ViBlurredBorder().BorderForeground(colors.Red) } + ViGrayBorder = func() lipgloss.Style { return ViBlurredBorder().BorderForeground(colors.Gray) } + ViRedBorder = func() lipgloss.Style { return ViBlurredBorder().BorderForeground(colors.Red) } ViEditBorder = func() lipgloss.Style { return ViBlurredBorder().BorderForeground(colors.Gold) } PaddingCount = 1 @@ -74,6 +74,8 @@ var ( ReadOnlyPlaceholder = "You do not have permission to send messages in this frequency" MutedPlaceholder = "You have been muted by a network adminstrator" SelectSignalOrFrequency = "Cannot send messages, select a signal or frequency first" + BlockedPlaceholder = "You have blocked this user" + BlockingPlaceholder = "You have been blocked by this user" EditedIndicator = func(bg lipgloss.Color) string { return lipgloss.NewStyle().Background(bg). @@ -230,14 +232,14 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { if member.IsMuted { m.vi.Placeholder = MutedPlaceholder - m.borderStyle = ViMutedBorder() - m.style = mutedStyle() + m.borderStyle = ViRedBorder() + m.style = redStyle() m.vi.SetInactive(true) m.locked = false } else if frequency.Perms != packet.PermReadWrite && !member.IsAdmin { m.vi.Placeholder = ReadOnlyPlaceholder - m.borderStyle = ViReadOnlyBorder() - m.style = readOnlyStyle() + m.borderStyle = ViGrayBorder() + m.style = grayStyle() m.vi.SetInactive(true) m.locked = false } else if m.locked { @@ -277,9 +279,23 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { } m.hasReadAccess = true - m.hasWriteAccess = true // TODO: implement blocking users + m.hasWriteAccess = true - if m.locked { + if _, ok := state.State.BlockedUsers[receiverId]; ok { + m.hasWriteAccess = false + m.vi.Placeholder = BlockedPlaceholder + m.borderStyle = ViRedBorder() + m.style = redStyle() + m.vi.SetInactive(true) + m.locked = false + } else if _, ok := state.State.BlockingUsers[receiverId]; ok { + m.hasWriteAccess = false + m.vi.Placeholder = BlockingPlaceholder + m.borderStyle = ViRedBorder() + m.style = redStyle() + m.vi.SetInactive(true) + m.locked = false + } else if m.locked { m.vi.Placeholder = SendMessagePlaceholder m.borderStyle = ViFocusedBorder() m.style = focusStyle() @@ -301,8 +317,8 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.hasWriteAccess = false // TODO: implement blocking users m.vi.Placeholder = SelectSignalOrFrequency - m.borderStyle = ViReadOnlyBorder() - m.style = readOnlyStyle() + m.borderStyle = ViGrayBorder() + m.style = grayStyle() m.vi.SetInactive(true) } @@ -441,11 +457,55 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { _, isTrusting := state.State.TrustedUsers[senderId] + _, isBlocked := state.State.BlockedUsers[senderId] + if !isTrusting && isBlocked { + return m, nil + } + return m, gateway.Send(&packet.TrustUser{ User: senderId, Trust: !isTrusting, }) + case "b": + if m.selectedMessage == nil { + return m, nil + } + + userId := m.selectedMessage.SenderID + + if userId == *state.UserID { + return m, nil + } + + if _, ok := state.State.BlockedUsers[userId]; ok { + return m, nil + } + + return m, gateway.Send(&packet.BlockUser{ + User: userId, + Block: true, + }) + case "u": + if m.selectedMessage == nil { + return m, nil + } + + userId := m.selectedMessage.SenderID + + if userId == *state.UserID { + return m, nil + } + + if _, ok := state.State.BlockedUsers[userId]; !ok { + return m, nil + } + + return m, gateway.Send(&packet.BlockUser{ + User: userId, + Block: false, + }) + // Admin case "K": if m.selectedMessage == nil || m.receiverIndex != -1 { @@ -514,105 +574,69 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { User: member.UserID, }) case "U": - if m.selectedMessage == nil { + if m.selectedMessage == nil || m.receiverIndex != -1 { return m, nil } + networkId := state.NetworkId(m.networkIndex) + network := state.State.Networks[*networkId] + senderId := m.selectedMessage.SenderID + member := state.State.Members[*networkId][senderId] - if m.receiverIndex != -1 { - userId := state.Data.Signals[m.receiverIndex] - - if userId == *state.UserID { - return m, nil - } - - if _, ok := state.State.BlockedUsers[userId]; !ok { - return m, nil - } - - return m, gateway.Send(&packet.BlockUser{ - User: userId, - Block: false, - }) - - } else { - networkId := state.NetworkId(m.networkIndex) - network := state.State.Networks[*networkId] - senderId := m.selectedMessage.SenderID - member := state.State.Members[*networkId][senderId] + if !member.IsMuted { + return m, nil + } - if !member.IsMuted { - return m, nil - } + if !state.State.Members[*networkId][*state.UserID].IsAdmin { + return m, nil + } - if !state.State.Members[*networkId][*state.UserID].IsAdmin { - return m, nil - } + if member.UserID == *state.UserID { + return m, nil + } - if member.UserID == *state.UserID { - return m, nil - } + if member.IsAdmin && network.OwnerID != *state.UserID { + return m, nil + } - if member.IsAdmin && network.OwnerID != *state.UserID { - return m, nil - } + no := false + return m, gateway.Send(&packet.SetMember{ + Member: nil, + Admin: nil, + Muted: &no, + Banned: nil, + BanReason: nil, + Network: *state.NetworkId(m.networkIndex), + User: member.UserID, + }) - no := false - return m, gateway.Send(&packet.SetMember{ - Member: nil, - Admin: nil, - Muted: &no, - Banned: nil, - BanReason: nil, - Network: *state.NetworkId(m.networkIndex), - User: member.UserID, - }) - } case "B": - if m.selectedMessage == nil { + if m.selectedMessage == nil || m.receiverIndex != -1 { return m, nil } - if m.receiverIndex != -1 { - userId := state.Data.Signals[m.receiverIndex] - - if userId == *state.UserID { - return m, nil - } - - if _, ok := state.State.BlockedUsers[userId]; ok { - return m, nil - } - - return m, gateway.Send(&packet.BlockUser{ - User: userId, - Block: true, - }) - - } else { - networkId := state.NetworkId(m.networkIndex) - network := state.State.Networks[*networkId] - senderId := m.selectedMessage.SenderID - member := state.State.Members[*networkId][senderId] + networkId := state.NetworkId(m.networkIndex) + network := state.State.Networks[*networkId] + senderId := m.selectedMessage.SenderID + member := state.State.Members[*networkId][senderId] - if !state.State.Members[*networkId][*state.UserID].IsAdmin { - return m, nil - } + if !state.State.Members[*networkId][*state.UserID].IsAdmin { + return m, nil + } - if member.UserID == *state.UserID { - return m, nil - } + if member.UserID == *state.UserID { + return m, nil + } - if member.IsAdmin && network.OwnerID != *state.UserID { - return m, nil - } + if member.IsAdmin && network.OwnerID != *state.UserID { + return m, nil + } - cmd := func() tea.Msg { - return ui.BanReasonPopupMsg{ - Network: *state.NetworkId(m.networkIndex), - User: member.UserID, - } + cmd := func() tea.Msg { + return ui.BanReasonPopupMsg{ + Network: *state.NetworkId(m.networkIndex), + User: member.UserID, } - return m, cmd } + return m, cmd // Owner case "D": @@ -1194,6 +1218,13 @@ func (m *Model) renderMessageGroup(group []data.Message, remaining *int, height } } + if _, ok := state.State.BlockedUsers[group[i].SenderID]; ok { + messageStyle = pingedMessageStyle. + BorderForeground(colors.Gray). + Background(colors.DarkGray) + backgroundStyle = backgroundStyle.Background(colors.DarkGray).Foreground(colors.DarkGray) + } + rawContent := extra + backgroundStyle.Render(group[i].Content) content := messageStyle.Render(rawContent) heights[i] = lipgloss.Height(content) @@ -1400,6 +1431,10 @@ func (m *Model) renderHeader(message data.Message, selected bool) []byte { buf = append(buf, []byte(MutedSymbol())...) } + if _, ok := state.State.BlockedUsers[user.ID]; ok { + buf = append(buf, ui.BlockedSymbol()...) + } + } else if m.receiverIndex != -1 { user := state.State.Users[message.SenderID] trustedPublicKey, isTrusted := state.State.TrustedUsers[user.ID] @@ -1420,7 +1455,6 @@ func (m *Model) renderHeader(message data.Message, selected bool) []byte { buf = append(buf, sender...) if _, ok := state.State.BlockedUsers[user.ID]; ok { - buf = append(buf, ' ') buf = append(buf, ui.BlockedSymbol()...) } } diff --git a/internal/client/ui/core/core.go b/internal/client/ui/core/core.go index 96d6394..b46a22b 100644 --- a/internal/client/ui/core/core.go +++ b/internal/client/ui/core/core.go @@ -431,8 +431,8 @@ func (m *Model) updateConnected(message tea.Msg) tea.Cmd { message = ui.EmptyMsg{} } - // user - case "u": + // user [s]ettings + case "s": isChatLocked := m.focus == FocusChat && m.chat.Locked() if !m.HasPopup() && !isChatLocked { popup := usersettings.New() diff --git a/internal/client/ui/core/memberlist/memberlist.go b/internal/client/ui/core/memberlist/memberlist.go index 1978e29..3e07446 100644 --- a/internal/client/ui/core/memberlist/memberlist.go +++ b/internal/client/ui/core/memberlist/memberlist.go @@ -212,6 +212,11 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { _, isTrusting := state.State.TrustedUsers[member.UserID] + _, isBlocked := state.State.BlockedUsers[member.UserID] + if !isTrusting && isBlocked { + return m, nil + } + return m, gateway.Send(&packet.TrustUser{ User: member.UserID, Trust: !isTrusting, diff --git a/internal/client/ui/core/signallist/signallist.go b/internal/client/ui/core/signallist/signallist.go index 075f0f8..f20724d 100644 --- a/internal/client/ui/core/signallist/signallist.go +++ b/internal/client/ui/core/signallist/signallist.go @@ -91,7 +91,6 @@ func (m Model) View() string { Foreground(colors.Red).Background(colors.BackgroundDim). Render(notif) maxUserWidth -= notifWidth - } if m.index == m.base+i { @@ -107,6 +106,12 @@ func (m Model) View() string { username = ui.UntrustedSymbol() + username } + blockSymbol := "" + if _, ok := state.State.BlockedUsers[user.ID]; ok { + maxUserWidth -= 2 // blocked symbol width + blockSymbol = ui.BlockedSymbol() + } + if lipgloss.Width(username) <= maxUserWidth { username = lipgloss.NewStyle(). MaxWidth(maxUserWidth). @@ -120,11 +125,15 @@ func (m Model) View() string { Render(username) + ellipsisStyle.Render(ellipsis) } if m.index == m.base+i { + blockSymbol = lipgloss.NewStyle(). + Background(colors.BackgroundHighlight).Render(blockSymbol) username = lipgloss.NewStyle().Width(maxUserWidth). - Background(colors.BackgroundHighlight).Render(username) + Background(colors.BackgroundHighlight).Render(username + blockSymbol) } else { + blockSymbol = lipgloss.NewStyle(). + Background(colors.BackgroundDim).Render(blockSymbol) username = lipgloss.NewStyle().Width(maxUserWidth). - Background(colors.BackgroundDim).Render(username) + Background(colors.BackgroundDim).Render(username + blockSymbol) } signal := signalStyle.Render(username + notif) @@ -193,11 +202,53 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { _, isTrusting := state.State.TrustedUsers[userId] + _, isBlocked := state.State.BlockedUsers[userId] + if !isTrusting && isBlocked { + return m, nil + } + return m, gateway.Send(&packet.TrustUser{ User: userId, Trust: !isTrusting, }) + case "b": + if m.index == -1 { + return m, nil + } + userId := state.Data.Signals[m.index] + + if userId == *state.UserID { + return m, nil + } + + if _, ok := state.State.BlockedUsers[userId]; ok { + return m, nil + } + + return m, gateway.Send(&packet.BlockUser{ + User: userId, + Block: true, + }) + case "u": + if m.index == -1 { + return m, nil + } + userId := state.Data.Signals[m.index] + + if userId == *state.UserID { + return m, nil + } + + if _, ok := state.State.BlockedUsers[userId]; !ok { + return m, nil + } + + return m, gateway.Send(&packet.BlockUser{ + User: userId, + Block: false, + }) + } } diff --git a/internal/client/ui/core/state/state.go b/internal/client/ui/core/state/state.go index 607345f..da894ed 100644 --- a/internal/client/ui/core/state/state.go +++ b/internal/client/ui/core/state/state.go @@ -26,13 +26,14 @@ type state struct { ChatState map[snowflake.ID]ChatState // key is frequency id or receiver id LastFrequency map[snowflake.ID]snowflake.ID // key is network id - Messages map[snowflake.ID]*btree.BTreeG[data.Message] // key is frequency id or receiver id - Networks map[snowflake.ID]data.Network // key is network id - Frequencies map[snowflake.ID][]data.Frequency // key is network id - Members map[snowflake.ID]map[snowflake.ID]data.Member // key is network id then user id - Users map[snowflake.ID]data.User // key is user id - TrustedUsers map[snowflake.ID]ed25519.PublicKey // key is user id - BlockedUsers map[snowflake.ID]struct{} // key is user id + Messages map[snowflake.ID]*btree.BTreeG[data.Message] // key is frequency id or receiver id + Networks map[snowflake.ID]data.Network // key is network id + Frequencies map[snowflake.ID][]data.Frequency // key is network id + Members map[snowflake.ID]map[snowflake.ID]data.Member // key is network id then user id + Users map[snowflake.ID]data.User // key is user id + TrustedUsers map[snowflake.ID]ed25519.PublicKey // key is user id + BlockedUsers map[snowflake.ID]struct{} // key is user id + BlockingUsers map[snowflake.ID]struct{} // key is user id LastReadMessages map[snowflake.ID]*snowflake.ID // key is frequency id or receiver id Notifications map[snowflake.ID]int // key is frequency id or receiver id @@ -48,6 +49,7 @@ var State state = state{ Users: map[snowflake.ID]data.User{}, TrustedUsers: map[snowflake.ID]ed25519.PublicKey{}, BlockedUsers: map[snowflake.ID]struct{}{}, + BlockingUsers: map[snowflake.ID]struct{}{}, LastReadMessages: map[snowflake.ID]*snowflake.ID{}, Notifications: map[snowflake.ID]int{}, } @@ -345,7 +347,16 @@ func UpdateBlockedUsers(info *packet.BlockInfo) { delete(State.BlockedUsers, removed) } - for _, trusted := range info.BlockedUsers { - State.BlockedUsers[trusted] = struct{}{} + for _, blocked := range info.BlockedUsers { + State.BlockedUsers[blocked] = struct{}{} + delete(State.TrustedUsers, blocked) + } + + for _, removed := range info.RemovedBlockingUsers { + delete(State.BlockingUsers, removed) + } + + for _, blocking := range info.BlockingUsers { + State.BlockingUsers[blocking] = struct{}{} } } diff --git a/internal/client/ui/ui.go b/internal/client/ui/ui.go index 69acb44..127626c 100644 --- a/internal/client/ui/ui.go +++ b/internal/client/ui/ui.go @@ -37,7 +37,7 @@ var ( TrustedAdminStyle = func() lipgloss.Style { return AdminStyle().SetString("") } TrustedOwnerStyle = func() lipgloss.Style { return OwnerStyle().SetString("") } UntrustedSymbol = func() string { return lipgloss.NewStyle().Foreground(colors.Red).Render("") } - BlockedSymbol = func() string { return lipgloss.NewStyle().Foreground(colors.Red).Render("") } + BlockedSymbol = func() string { return lipgloss.NewStyle().Foreground(colors.Red).Render(" ") } ) var NewAuth func() tea.Model |
