Fixed inability to jump to mentioned channel by name
* mutex instances have been removed from components, instead the
components are mutexes themselves now
* vtxxx checks have been replaced with tview calls
* duplicated code has been removed
MODIFY
ui/chatview.go
ui/chatview.go
@@ -52,6 +52,8 @@ var (
// in a simple way. It supports highlighting specific element types and it
// also supports multiline.
type ChatView struct {
+ *sync.Mutex
+
internalTextView *tview.TextView
shortener *linkshortener.Shortener
@@ -72,8 +74,6 @@ type ChatView struct {
formattedMessages map[string]string
onMessageAction func(message *discordgo.Message, event *tcell.EventKey) *tcell.EventKey
-
- mutex *sync.Mutex
}
// NewChatView constructs a new ready to use ChatView.
@@ -93,7 +93,7 @@ func NewChatView(state *discordgo.State, ownUserID string) *ChatView {
shortenLinks: config.Current.ShortenLinks,
shortenWithExtension: config.Current.ShortenWithExtension,
formattedMessages: make(map[string]string),
- mutex: &sync.Mutex{},
+ Mutex: &sync.Mutex{},
}
if chatView.shortenLinks {
@@ -515,7 +515,7 @@ func (chatView *ChatView) formatDefaultMessageText(message *discordgo.Message) s
}
var color string
- if vtxxx {
+ if tview.IsVtxxx {
if chatView.state.User.ID == user.ID {
color = "[::r]"
} else {
@@ -530,7 +530,7 @@ func (chatView *ChatView) formatDefaultMessageText(message *discordgo.Message) s
}
var replacement string
- if vtxxx {
+ if tview.IsVtxxx {
replacement = color + "@" + userName + "[::-]"
} else {
replacement = color + "@" + userName + "[" + tviewutil.ColorToHex(config.GetTheme().PrimaryTextColor) + "]"
@@ -1045,14 +1045,3 @@ func (chatView *ChatView) SetMessages(messages []*discordgo.Message) {
chatView.internalTextView.ScrollToEnd()
}
}
-
-// Lock will lock the ChatView, allowing other callers to prevent race
-// conditions.
-func (chatView *ChatView) Lock() {
- chatView.mutex.Lock()
-}
-
-// Unlock unlocks the previously locked ChatView.
-func (chatView *ChatView) Unlock() {
- chatView.mutex.Unlock()
-}

MODIFY
ui/guildlist.go
ui/guildlist.go
@@ -65,27 +65,20 @@ func NewGuildList(guilds []*discordgo.Guild) *GuildList {
}
// UpdateNodeStateByGuild updates the state of a guilds node accordingly
-// to its readstate, unless the node is selected.
-//
-// FIXME selected should probably be removed here, but bugs will occur
-// so I'll do it someday ... :D
-func (g *GuildList) UpdateNodeStateByGuild(guild *discordgo.Guild, selected bool) {
+// to its readstate, unless the guild represented by that node is loaded.
+func (g *GuildList) UpdateNodeStateByGuild(guild *discordgo.Guild, loaded bool) {
matchedNode := tviewutil.GetNodeByReference(guild.ID, g.TreeView)
if matchedNode != nil {
- g.updateNodeState(guild, matchedNode, selected)
+ g.updateNodeState(guild, matchedNode, loaded)
}
}
-func (g *GuildList) updateNodeState(guild *discordgo.Guild, node *tview.TreeNode, selected bool) {
- if selected {
- if vtxxx {
- node.SetAttributes(tcell.AttrUnderline)
- } else {
- node.SetColor(tview.Styles.ContrastBackgroundColor)
- }
+func (g *GuildList) updateNodeState(guild *discordgo.Guild, node *tview.TreeNode, loaded bool) {
+ if loaded {
+ g.markNodeAsLoaded(node)
} else {
if !readstate.HasGuildBeenRead(guild.ID) {
- if vtxxx {
+ if tview.IsVtxxx {
node.SetAttributes(tcell.AttrBlink)
} else {
node.SetColor(config.GetTheme().AttentionColor)
@@ -96,10 +89,11 @@ func (g *GuildList) updateNodeState(guild *discordgo.Guild, node *tview.TreeNode
}
}
+ //Prefix order doesn't matter for now, as we never have more than one.
if readstate.HasGuildBeenMentioned(guild.ID) {
- node.SetText("(@) " + tviewutil.Escape(guild.Name))
+ node.AddPrefix("(@)")
} else {
- node.SetText(tviewutil.Escape(guild.Name))
+ node.RemovePrefix("@")
}
}
@@ -172,10 +166,14 @@ func (g *GuildList) MarkAsLoaded(guildID string) {
guildNode := tviewutil.GetNodeByReference(guildID, g.TreeView)
if guildNode != nil {
g.SetCurrentNode(guildNode)
- if vtxxx {
- guildNode.SetAttributes(tcell.AttrUnderline)
- } else {
- guildNode.SetColor(tview.Styles.ContrastBackgroundColor)
+ g.markNodeAsLoaded(guildNode)
}
}
+
+func (g *GuildList) markNodeAsLoaded(node *tview.TreeNode) {
+ if tview.IsVtxxx {
+ node.SetAttributes(tcell.AttrUnderline)
+ } else {
+ node.SetColor(tview.Styles.ContrastBackgroundColor)
+ }
}

MODIFY
ui/privatechats.go
ui/privatechats.go
@@ -131,7 +131,7 @@ func (privateList *PrivateChatList) addChannel(channel *discordgo.Channel) {
newNode := createPrivateChannelNode(channel)
if !readstate.HasBeenRead(channel, channel.LastMessageID) {
privateList.privateChannelStates[newNode] = unread
- if vtxxx {
+ if tview.IsVtxxx {
newNode.SetAttributes(tcell.AttrBlink)
} else {
newNode.SetColor(config.GetTheme().AttentionColor)
@@ -227,7 +227,7 @@ func (privateList *PrivateChatList) MarkAsUnread(channelID string) {
if node != nil {
privateList.privateChannelStates[node] = unread
privateList.setNotificationCount(privateList.amountOfUnreadChannels())
- if vtxxx {
+ if tview.IsVtxxx {
node.SetAttributes(tcell.AttrBlink)
} else {
node.SetColor(config.GetTheme().AttentionColor)
@@ -252,7 +252,7 @@ func (privateList *PrivateChatList) MarkAsRead(channelID string) {
if node != nil {
privateList.setNotificationCount(privateList.amountOfUnreadChannels())
privateList.privateChannelStates[node] = read
- if vtxxx {
+ if tview.IsVtxxx {
node.SetAttributes(tcell.AttrNone)
} else {
node.SetColor(config.GetTheme().PrimaryTextColor)
@@ -296,7 +296,7 @@ func (privateList *PrivateChatList) MarkAsLoaded(channelID string) {
for node, state := range privateList.privateChannelStates {
if state == loaded {
privateList.privateChannelStates[node] = read
- if vtxxx {
+ if tview.IsVtxxx {
node.SetAttributes(tcell.AttrNone)
} else {
node.SetColor(config.GetTheme().PrimaryTextColor)
@@ -309,7 +309,7 @@ func (privateList *PrivateChatList) MarkAsLoaded(channelID string) {
referenceChannelID, ok := node.GetReference().(string)
if ok && referenceChannelID == channelID {
privateList.privateChannelStates[node] = loaded
- if vtxxx {
+ if tview.IsVtxxx {
node.SetAttributes(tcell.AttrUnderline)
} else {
node.SetColor(tview.Styles.ContrastBackgroundColor)

MODIFY
ui/shortcutdialog/dialog.go
ui/shortcutdialog/dialog.go
@@ -2,8 +2,6 @@ package shortcutdialog
import (
"log"
- "os"
- "regexp"
"github.com/Bios-Marcel/cordless/shortcuts"
"github.com/Bios-Marcel/cordless/tview"
@@ -13,16 +11,6 @@ import (
"github.com/Bios-Marcel/cordless/ui/tviewutil"
)
-func checkVT() bool {
- VTxxx, err := regexp.MatchString("(vt)[0-9]+", os.Getenv("TERM"))
- if err != nil {
- panic(err)
- }
- return VTxxx
-}
-
-var vtxxx = checkVT()
-
func ShowShortcutsDialog(app *tview.Application, onClose func()) {
var table *ShortcutTable
var shortcutDescription *tview.TextView
@@ -75,7 +63,7 @@ func ShowShortcutsDialog(app *tview.Application, onClose func()) {
shortcutDescription = tview.NewTextView()
shortcutDescription.SetDynamicColors(true).SetBorderPadding(1, 0, 0, 0)
- if vtxxx {
+ if tview.IsVtxxx {
shortcutDescription.SetText("R [::r]Reset shortcut[::-]" +
"[::-] Backspace [::r]Delete shortcut" +
"[::-] Enter [::r]Change shortcut" +

MODIFY
ui/shortcutdialog/table.go
ui/shortcutdialog/table.go
@@ -36,7 +36,7 @@ func NewShortcutTable() *ShortcutTable {
table.SetSelectable(true, false)
table.SetBorder(true)
- if vtxxx {
+ if tview.IsVtxxx {
table.SetSelectedStyle(tcell.ColorBlack, tcell.ColorWhite, tcell.AttrReverse)
}

MODIFY
ui/usertree.go
ui/usertree.go
@@ -15,8 +15,9 @@ import (
// UserTree represents the visual list of users in a guild.
type UserTree struct {
+ *sync.Mutex
+
internalTreeView *tview.TreeView
- rootNode *tview.TreeNode
state *discordgo.State
@@ -24,7 +25,6 @@ type UserTree struct {
roleNodes map[string]*tview.TreeNode
roles []*discordgo.Role
- lock *sync.Mutex
loaded bool
}
@@ -32,34 +32,37 @@ type UserTree struct {
func NewUserTree(state *discordgo.State) *UserTree {
userTree := &UserTree{
state: state,
- rootNode: tview.NewTreeNode(""),
internalTreeView: tview.NewTreeView(),
loaded: false,
- lock: &sync.Mutex{},
+ Mutex: &sync.Mutex{},
}
userTree.internalTreeView.
SetVimBindingsEnabled(config.Current.OnTypeInListBehaviour == config.DoNothingOnTypeInList).
- SetRoot(userTree.rootNode).
+ SetRoot(tview.NewTreeNode("")).
SetTopLevel(1).
- SetCycleSelection(true)
- userTree.internalTreeView.SetBorder(true)
+ SetCycleSelection(true).
+ SetBorder(true)
return userTree
}
// Clear removes all nodes and data out of the view.
func (userTree *UserTree) Clear() {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
userTree.clear()
}
+func (userTree *UserTree) rootNode() *tview.TreeNode {
+ return userTree.internalTreeView.GetRoot()
+}
+
func (userTree *UserTree) clear() {
for _, roleNode := range userTree.roleNodes {
roleNode.ClearChildren()
}
- userTree.rootNode.ClearChildren()
+ userTree.rootNode().ClearChildren()
userTree.loaded = false
// After clearing, we don't reallocate anything, since we don't know
@@ -71,8 +74,8 @@ func (userTree *UserTree) clear() {
// LoadGroup loads all users for a group-channel.
func (userTree *UserTree) LoadGroup(channelID string) error {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
userTree.clear()
userTree.userNodes = make(map[string]*tview.TreeNode)
@@ -94,8 +97,8 @@ func (userTree *UserTree) LoadGroup(channelID string) error {
// LoadGuild will load all available roles of the guild and then load all
// available members. Afterwards the first available node will be selected.
func (userTree *UserTree) LoadGuild(guildID string) error {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
userTree.clear()
userTree.userNodes = make(map[string]*tview.TreeNode)
@@ -120,9 +123,9 @@ func (userTree *UserTree) LoadGuild(guildID string) error {
func (userTree *UserTree) selectFirstNode() {
if userTree.internalTreeView.GetCurrentNode() == nil {
- userNodes := userTree.rootNode.GetChildren()
+ userNodes := userTree.rootNode().GetChildren()
if len(userNodes) > 0 {
- userTree.internalTreeView.SetCurrentNode(userTree.rootNode.GetChildren()[0])
+ userTree.internalTreeView.SetCurrentNode(userTree.rootNode().GetChildren()[0])
}
}
}
@@ -156,7 +159,7 @@ func (userTree *UserTree) loadGuildRoles(guildID string) ([]*discordgo.Role, err
"]" + tviewutil.Escape(role.Name))
roleNode.SetSelectable(false)
userTree.roleNodes[role.ID] = roleNode
- userTree.rootNode.AddChild(roleNode)
+ userTree.rootNode().AddChild(roleNode)
}
}
@@ -166,8 +169,8 @@ func (userTree *UserTree) loadGuildRoles(guildID string) ([]*discordgo.Role, err
// AddOrUpdateMember adds the passed member to the tree, unless it is
// already part of the tree, in that case the nodes name is updated.
func (userTree *UserTree) AddOrUpdateMember(member *discordgo.Member) {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
if !userTree.loaded {
return
}
@@ -197,14 +200,14 @@ func (userTree *UserTree) addOrUpdateMember(member *discordgo.Member) {
}
}
- userTree.rootNode.AddChild(userNode)
+ userTree.rootNode().AddChild(userNode)
}
// AddOrUpdateUser adds a user to the tree, unless the user already exists,
// in that case the users node gets updated.
func (userTree *UserTree) AddOrUpdateUser(user *discordgo.User) {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
if !userTree.loaded {
return
}
@@ -223,14 +226,14 @@ func (userTree *UserTree) addOrUpdateUser(user *discordgo.User) {
userNode = tview.NewTreeNode(nameToUse)
userTree.userNodes[user.ID] = userNode
- userTree.rootNode.AddChild(userNode)
+ userTree.rootNode().AddChild(userNode)
}
// AddOrUpdateUsers adds users to the tree, unless they already exists, in that
// case the users nodes gets updated.
func (userTree *UserTree) AddOrUpdateUsers(users []*discordgo.User) {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
if !userTree.loaded {
return
}
@@ -246,8 +249,8 @@ func (userTree *UserTree) addOrUpdateUsers(users []*discordgo.User) {
// AddOrUpdateMembers adds the all passed members to the tree, unless a node is
// already part of the tree, in that case the nodes name is updated.
func (userTree *UserTree) AddOrUpdateMembers(members []*discordgo.Member) {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
if !userTree.loaded {
return
}
@@ -262,8 +265,8 @@ func (userTree *UserTree) addOrUpdateMembers(members []*discordgo.Member) {
// RemoveMember finds and removes a node from the tree.
func (userTree *UserTree) RemoveMember(member *discordgo.Member) {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
if !userTree.loaded {
return
}
@@ -273,7 +276,7 @@ func (userTree *UserTree) RemoveMember(member *discordgo.Member) {
func (userTree *UserTree) removeMember(member *discordgo.Member) {
userNode, contains := userTree.userNodes[member.User.ID]
if contains {
- userTree.rootNode.Walk(func(node, parent *tview.TreeNode) bool {
+ userTree.rootNode().Walk(func(node, parent *tview.TreeNode) bool {
if node == userNode {
if len(parent.GetChildren()) == 1 {
parent.SetChildren(make([]*tview.TreeNode, 0))
@@ -306,8 +309,8 @@ func (userTree *UserTree) removeMember(member *discordgo.Member) {
// RemoveMembers finds and removes all passed members from the tree.
func (userTree *UserTree) RemoveMembers(members []*discordgo.Member) {
- userTree.lock.Lock()
- defer userTree.lock.Unlock()
+ userTree.Lock()
+ defer userTree.Unlock()
if !userTree.loaded {
return
}

MODIFY
ui/window.go
ui/window.go
@@ -2391,7 +2391,7 @@ func (window *Window) startEditingMessage(message *discordgo.Message) {
window.messageInput.SetText(message.Content)
window.messageInput.SetBorderColor(tcell.ColorYellow)
window.messageInput.SetBorderFocusColor(tcell.ColorYellow)
- if vtxxx {
+ if tview.IsVtxxx {
window.messageInput.SetBorderFocusAttributes(tcell.AttrBlink | tcell.AttrBold)
}
window.editingMessageID = &message.ID
@@ -2408,7 +2408,7 @@ func (window *Window) exitMessageEditModeAndKeepText() {
window.editingMessageID = nil
window.messageInput.SetBorderColor(tview.Styles.BorderColor)
window.messageInput.SetBorderFocusColor(tview.Styles.BorderFocusColor)
- if vtxxx {
+ if tview.IsVtxxx {
window.messageInput.SetBorderFocusAttributes(tcell.AttrBold)
window.messageInput.SetBorderAttributes(tcell.AttrNone)
}

Fixed inability to jump to mentioned channel by name

* mutex instances have been removed from components, instead the
components are mutexes themselves now
* vtxxx checks have been replaced with tview calls
* duplicated code has been removed