Clean up code
This commit is contained in:
parent
09703c6b9c
commit
cce79ab7d8
@ -254,6 +254,47 @@ func (c *Container) HandleMessage(source EventSource, evt *gomatrix.Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleMembership is the event handler for the m.room.member state event.
|
||||||
|
func (c *Container) HandleMembership(source EventSource, evt *gomatrix.Event) {
|
||||||
|
isLeave := source&EventSourceLeave != 0
|
||||||
|
isTimeline := source&EventSourceTimeline != 0
|
||||||
|
isNonTimelineLeave := isLeave && !isTimeline
|
||||||
|
if !c.config.AuthCache.InitialSyncDone && isNonTimelineLeave {
|
||||||
|
return
|
||||||
|
} else if evt.StateKey != nil && *evt.StateKey == c.config.UserID {
|
||||||
|
c.processOwnMembershipChange(evt)
|
||||||
|
} else if !isTimeline && (!c.config.AuthCache.InitialSyncDone || isLeave) {
|
||||||
|
// We don't care about other users' membership events in the initial sync or chats we've left.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HandleMessage(source, evt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
|
||||||
|
membership, _ := evt.Content["membership"].(string)
|
||||||
|
prevMembership := "leave"
|
||||||
|
if evt.Unsigned.PrevContent != nil {
|
||||||
|
prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string)
|
||||||
|
}
|
||||||
|
debug.Printf("Processing own membership change: %s->%s in %s", prevMembership, membership, evt.RoomID)
|
||||||
|
if membership == prevMembership {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
room := c.GetRoom(evt.RoomID)
|
||||||
|
switch membership {
|
||||||
|
case "join":
|
||||||
|
c.ui.MainView().AddRoom(room)
|
||||||
|
room.HasLeft = false
|
||||||
|
case "leave":
|
||||||
|
c.ui.MainView().RemoveRoom(room)
|
||||||
|
room.HasLeft = true
|
||||||
|
case "invite":
|
||||||
|
// TODO handle
|
||||||
|
debug.Printf("%s invited the user to %s", evt.Sender, evt.RoomID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Container) parseReadReceipt(evt *gomatrix.Event) (largestTimestampEvent string) {
|
func (c *Container) parseReadReceipt(evt *gomatrix.Event) (largestTimestampEvent string) {
|
||||||
var largestTimestamp int64
|
var largestTimestamp int64
|
||||||
for eventID, rawContent := range evt.Content {
|
for eventID, rawContent := range evt.Content {
|
||||||
@ -368,63 +409,6 @@ func (c *Container) HandleTag(source EventSource, evt *gomatrix.Event) {
|
|||||||
mainView.UpdateTags(room)
|
mainView.UpdateTags(room)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
|
|
||||||
membership, _ := evt.Content["membership"].(string)
|
|
||||||
prevMembership := "leave"
|
|
||||||
if evt.Unsigned.PrevContent != nil {
|
|
||||||
prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string)
|
|
||||||
}
|
|
||||||
debug.Printf("Processing own membership change: %s->%s in %s", prevMembership, membership, evt.RoomID)
|
|
||||||
if membership == prevMembership {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
room := c.GetRoom(evt.RoomID)
|
|
||||||
switch membership {
|
|
||||||
case "join":
|
|
||||||
c.ui.MainView().AddRoom(room)
|
|
||||||
room.HasLeft = false
|
|
||||||
case "leave":
|
|
||||||
c.ui.MainView().RemoveRoom(room)
|
|
||||||
room.HasLeft = true
|
|
||||||
case "invite":
|
|
||||||
// TODO handle
|
|
||||||
debug.Printf("%s invited the user to %s", evt.Sender, evt.RoomID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleMembership is the event handler for the m.room.member state event.
|
|
||||||
func (c *Container) HandleMembership(source EventSource, evt *gomatrix.Event) {
|
|
||||||
isLeave := source&EventSourceLeave != 0
|
|
||||||
isTimeline := source&EventSourceTimeline != 0
|
|
||||||
isNonTimelineLeave := isLeave && !isTimeline
|
|
||||||
if !c.config.AuthCache.InitialSyncDone && isNonTimelineLeave {
|
|
||||||
return
|
|
||||||
} else if evt.StateKey != nil && *evt.StateKey == c.config.UserID {
|
|
||||||
c.processOwnMembershipChange(evt)
|
|
||||||
} else if !isTimeline && (!c.config.AuthCache.InitialSyncDone || isLeave) {
|
|
||||||
// We don't care about other users' membership events in the initial sync or chats we've left.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
mainView := c.ui.MainView()
|
|
||||||
roomView := mainView.GetRoom(evt.RoomID)
|
|
||||||
if roomView == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
message := mainView.ParseEvent(roomView, evt)
|
|
||||||
if message != nil {
|
|
||||||
roomView.AddMessage(message, ifc.AppendMessage)
|
|
||||||
roomView.MxRoom().LastReceivedMessage = message.Timestamp()
|
|
||||||
// We don't want notifications at startup.
|
|
||||||
if c.syncer.FirstSyncDone {
|
|
||||||
pushRules := c.PushRules().GetActions(roomView.MxRoom(), evt).Should()
|
|
||||||
mainView.NotifyMessage(roomView.MxRoom(), message, pushRules)
|
|
||||||
c.ui.Render()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleTyping is the event handler for the m.typing event.
|
// HandleTyping is the event handler for the m.typing event.
|
||||||
func (c *Container) HandleTyping(source EventSource, evt *gomatrix.Event) {
|
func (c *Container) HandleTyping(source EventSource, evt *gomatrix.Event) {
|
||||||
users := evt.Content["user_ids"].([]interface{})
|
users := evt.Content["user_ids"].([]interface{})
|
||||||
|
136
ui/fuzzy-search-modal.go
Normal file
136
ui/fuzzy-search-modal.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// gomuks - A terminal Matrix client written in Go.
|
||||||
|
// Copyright (C) 2018 Tulir Asokan
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/evidlo/fuzzysearch/fuzzy"
|
||||||
|
"maunium.net/go/gomuks/matrix/rooms"
|
||||||
|
"maunium.net/go/gomuks/ui/widget"
|
||||||
|
"maunium.net/go/tview"
|
||||||
|
"maunium.net/go/tcell"
|
||||||
|
"maunium.net/go/gomuks/debug"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FuzzySearchModal struct {
|
||||||
|
tview.Primitive
|
||||||
|
|
||||||
|
search *tview.InputField
|
||||||
|
results *tview.TextView
|
||||||
|
|
||||||
|
matches fuzzy.Ranks
|
||||||
|
selected int
|
||||||
|
|
||||||
|
roomList []*rooms.Room
|
||||||
|
roomTitles []string
|
||||||
|
|
||||||
|
parent *GomuksUI
|
||||||
|
mainView *MainView
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFuzzySearchModal(mainView *MainView, width int, height int) *FuzzySearchModal {
|
||||||
|
fs := &FuzzySearchModal{
|
||||||
|
parent: mainView.parent,
|
||||||
|
mainView: mainView,
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.InitList(mainView.rooms)
|
||||||
|
|
||||||
|
fs.search = tview.NewInputField().
|
||||||
|
SetLabel("Room: ")
|
||||||
|
fs.search.
|
||||||
|
SetChangedFunc(fs.changeHandler).
|
||||||
|
SetInputCapture(fs.keyHandler)
|
||||||
|
|
||||||
|
fs.results = tview.NewTextView().
|
||||||
|
SetDynamicColors(true).
|
||||||
|
SetRegions(true)
|
||||||
|
fs.results.SetBorderPadding(1, 0, 0, 0)
|
||||||
|
|
||||||
|
// Flex widget containing input box and results
|
||||||
|
container := tview.NewFlex().
|
||||||
|
SetDirection(tview.FlexRow).
|
||||||
|
AddItem(fs.search, 1, 0, true).
|
||||||
|
AddItem(fs.results, 0, 1, false)
|
||||||
|
container.
|
||||||
|
SetBorder(true).
|
||||||
|
SetBorderPadding(1, 1, 1, 1).
|
||||||
|
SetTitle("Quick Room Switcher")
|
||||||
|
|
||||||
|
fs.Primitive = widget.TransparentCenter(width, height, container)
|
||||||
|
|
||||||
|
return fs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FuzzySearchModal) InitList(rooms map[string]*RoomView) {
|
||||||
|
for _, room := range rooms {
|
||||||
|
fs.roomList = append(fs.roomList, room.Room)
|
||||||
|
fs.roomTitles = append(fs.roomTitles, room.Room.GetTitle())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FuzzySearchModal) changeHandler(str string) {
|
||||||
|
// Get matches and display in result box
|
||||||
|
fs.matches = fuzzy.RankFindFold(str, fs.roomTitles)
|
||||||
|
if len(str) > 0 && len(fs.matches) > 0 {
|
||||||
|
sort.Sort(fs.matches)
|
||||||
|
fs.results.Clear()
|
||||||
|
for _, match := range fs.matches {
|
||||||
|
fmt.Fprintf(fs.results, `["%d"]%s[""]\n`, match.Index, match.Target)
|
||||||
|
}
|
||||||
|
fs.parent.Render()
|
||||||
|
fs.results.Highlight(strconv.Itoa(fs.matches[0].Index))
|
||||||
|
fs.results.ScrollToBeginning()
|
||||||
|
} else {
|
||||||
|
fs.results.Clear()
|
||||||
|
fs.results.Highlight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FuzzySearchModal) keyHandler(event *tcell.EventKey) *tcell.EventKey {
|
||||||
|
highlights := fs.results.GetHighlights()
|
||||||
|
switch event.Key() {
|
||||||
|
case tcell.KeyEsc:
|
||||||
|
// Close room finder
|
||||||
|
fs.parent.views.RemovePage("fuzzy-search-modal")
|
||||||
|
fs.parent.app.SetFocus(fs.parent.views)
|
||||||
|
return nil
|
||||||
|
case tcell.KeyTab:
|
||||||
|
// Cycle highlighted area to next match
|
||||||
|
if len(highlights) > 0 {
|
||||||
|
fs.selected = (fs.selected + 1) % len(fs.matches)
|
||||||
|
fs.results.Highlight(strconv.Itoa(fs.matches[fs.selected].Index))
|
||||||
|
fs.results.ScrollToHighlight()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
case tcell.KeyEnter:
|
||||||
|
// Switch room to currently selected room
|
||||||
|
if len(highlights) > 0 {
|
||||||
|
debug.Print("Fuzzy Selected Room:", fs.roomList[fs.matches[fs.selected].Index].GetTitle())
|
||||||
|
fs.mainView.SwitchRoom(fs.roomList[fs.matches[fs.selected].Index].Tags()[0].Tag, fs.roomList[fs.matches[fs.selected].Index])
|
||||||
|
}
|
||||||
|
fs.parent.views.RemovePage("fuzzy-search-modal")
|
||||||
|
fs.parent.app.SetFocus(fs.parent.views)
|
||||||
|
fs.results.Clear()
|
||||||
|
fs.search.SetText("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return event
|
||||||
|
}
|
127
ui/fuzzy-view.go
127
ui/fuzzy-view.go
@ -1,127 +0,0 @@
|
|||||||
// gomuks - A terminal Matrix client written in Go.
|
|
||||||
// Copyright (C) 2018 Tulir Asokan
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package ui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/evidlo/fuzzysearch/fuzzy"
|
|
||||||
"maunium.net/go/gomuks/debug"
|
|
||||||
"maunium.net/go/gomuks/matrix/rooms"
|
|
||||||
"maunium.net/go/gomuks/ui/widget"
|
|
||||||
"maunium.net/go/tcell"
|
|
||||||
"maunium.net/go/tview"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FuzzyView struct {
|
|
||||||
tview.Primitive
|
|
||||||
matches fuzzy.Ranks
|
|
||||||
selected int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFuzzyView(view *MainView, width int, height int) *FuzzyView {
|
|
||||||
|
|
||||||
roomList := []*rooms.Room{}
|
|
||||||
roomTitles := []string{}
|
|
||||||
for _, tag := range view.roomList.tags {
|
|
||||||
for _, room := range view.roomList.items[tag].rooms {
|
|
||||||
roomList = append(roomList, room.Room)
|
|
||||||
roomTitles = append(roomTitles, room.GetTitle())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// search box for fuzzy search
|
|
||||||
fuzzySearch := tview.NewInputField().
|
|
||||||
SetLabel("Room: ")
|
|
||||||
|
|
||||||
// list of rooms matching fuzzy search
|
|
||||||
fuzzyResults := tview.NewTextView().
|
|
||||||
SetDynamicColors(true).
|
|
||||||
SetRegions(true)
|
|
||||||
|
|
||||||
fuzzyResults.
|
|
||||||
SetBorderPadding(1, 0, 0, 0)
|
|
||||||
|
|
||||||
// flexbox containing input box and results
|
|
||||||
fuzzyFlex := tview.NewFlex().
|
|
||||||
SetDirection(tview.FlexRow).
|
|
||||||
AddItem(fuzzySearch, 1, 0, true).
|
|
||||||
AddItem(fuzzyResults, 0, 1, false)
|
|
||||||
|
|
||||||
fuzzyFlex.SetBorder(true).
|
|
||||||
SetBorderPadding(1, 1, 1, 1).
|
|
||||||
SetTitle("Fuzzy Room Finder")
|
|
||||||
|
|
||||||
var matches fuzzy.Ranks
|
|
||||||
var selected int
|
|
||||||
fuzz := &FuzzyView{
|
|
||||||
Primitive: widget.TransparentCenter(width, height, fuzzyFlex),
|
|
||||||
matches: matches,
|
|
||||||
selected: selected,
|
|
||||||
}
|
|
||||||
|
|
||||||
// callback to update search box
|
|
||||||
fuzzySearch.SetChangedFunc(func(str string) {
|
|
||||||
// get matches and display in fuzzyResults
|
|
||||||
fuzz.matches = fuzzy.RankFindFold(str, roomTitles)
|
|
||||||
if len(str) > 0 && len(fuzz.matches) > 0 {
|
|
||||||
sort.Sort(fuzz.matches)
|
|
||||||
fuzzyResults.Clear()
|
|
||||||
for _, match := range fuzz.matches {
|
|
||||||
fmt.Fprintf(fuzzyResults, "[\"%d\"]%s[\"\"]\n", match.Index, match.Target)
|
|
||||||
}
|
|
||||||
view.parent.app.Draw()
|
|
||||||
fuzzyResults.Highlight(strconv.Itoa(fuzz.matches[0].Index))
|
|
||||||
fuzzyResults.ScrollToBeginning()
|
|
||||||
} else {
|
|
||||||
fuzzyResults.Clear()
|
|
||||||
fuzzyResults.Highlight()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// callback to handle key events on fuzzy search
|
|
||||||
fuzzySearch.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
|
||||||
highlights := fuzzyResults.GetHighlights()
|
|
||||||
if event.Key() == tcell.KeyEsc {
|
|
||||||
view.parent.views.RemovePage("fuzzy")
|
|
||||||
view.parent.app.SetFocus(view.parent.views)
|
|
||||||
return nil
|
|
||||||
} else if event.Key() == tcell.KeyTab {
|
|
||||||
// cycle highlighted area to next fuzzy match
|
|
||||||
if len(highlights) > 0 {
|
|
||||||
fuzz.selected = (fuzz.selected + 1) % len(fuzz.matches)
|
|
||||||
fuzzyResults.Highlight(strconv.Itoa(fuzz.matches[fuzz.selected].Index))
|
|
||||||
fuzzyResults.ScrollToHighlight()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
} else if event.Key() == tcell.KeyEnter {
|
|
||||||
// switch room to currently selected room
|
|
||||||
if len(highlights) > 0 {
|
|
||||||
debug.Print("Fuzzy Selected Room:", roomList[fuzz.matches[fuzz.selected].Index].GetTitle())
|
|
||||||
view.SwitchRoom(roomList[fuzz.matches[fuzz.selected].Index].Tags()[0].Tag, roomList[fuzz.matches[fuzz.selected].Index])
|
|
||||||
}
|
|
||||||
view.parent.views.RemovePage("fuzzy")
|
|
||||||
fuzzyResults.Clear()
|
|
||||||
fuzzySearch.SetText("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return event
|
|
||||||
})
|
|
||||||
|
|
||||||
return fuzz
|
|
||||||
}
|
|
@ -44,6 +44,18 @@ var (
|
|||||||
spacePattern = regexp.MustCompile(`\s+`)
|
spacePattern = regexp.MustCompile(`\s+`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func matchBoundaryPattern(extract tstring.TString) tstring.TString {
|
||||||
|
matches := boundaryPattern.FindAllStringIndex(extract.String(), -1)
|
||||||
|
if len(matches) > 0 {
|
||||||
|
if match := matches[len(matches)-1]; len(match) >= 2 {
|
||||||
|
if until := match[1]; until < len(extract) {
|
||||||
|
extract = extract[:until]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return extract
|
||||||
|
}
|
||||||
|
|
||||||
// CalculateBuffer generates the internal buffer for this message that consists
|
// CalculateBuffer generates the internal buffer for this message that consists
|
||||||
// of the text of this message split into lines at most as wide as the width
|
// of the text of this message split into lines at most as wide as the width
|
||||||
// parameter.
|
// parameter.
|
||||||
@ -63,24 +75,14 @@ func (msg *BaseTextMessage) calculateBufferWithText(text tstring.TString, width
|
|||||||
} else {
|
} else {
|
||||||
newlines = 0
|
newlines = 0
|
||||||
}
|
}
|
||||||
// Mostly from tview/textview.go#reindexBuffer()
|
// Adapted from tview/textview.go#reindexBuffer()
|
||||||
for len(str) > 0 {
|
for len(str) > 0 {
|
||||||
extract := str.Truncate(width)
|
extract := str.Truncate(width)
|
||||||
if len(extract) < len(str) {
|
if len(extract) < len(str) {
|
||||||
if spaces := spacePattern.FindStringIndex(str[len(extract):].String()); spaces != nil && spaces[0] == 0 {
|
if spaces := spacePattern.FindStringIndex(str[len(extract):].String()); spaces != nil && spaces[0] == 0 {
|
||||||
extract = str[:len(extract)+spaces[1]]
|
extract = str[:len(extract)+spaces[1]]
|
||||||
}
|
}
|
||||||
|
extract = matchBoundaryPattern(extract)
|
||||||
matches := boundaryPattern.FindAllStringIndex(extract.String(), -1)
|
|
||||||
if len(matches) > 0 {
|
|
||||||
match := matches[len(matches)-1]
|
|
||||||
if len(match) >= 2 {
|
|
||||||
until := match[1]
|
|
||||||
if until < len(extract) {
|
|
||||||
extract = extract[:until]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
msg.buffer = append(msg.buffer, extract)
|
msg.buffer = append(msg.buffer, extract)
|
||||||
str = str[len(extract):]
|
str = str[len(extract):]
|
||||||
|
@ -67,19 +67,22 @@ func (str TString) Append(data string) TString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (str TString) AppendColor(data string, color tcell.Color) TString {
|
func (str TString) AppendColor(data string, color tcell.Color) TString {
|
||||||
newStr := make(TString, len(str)+len(data))
|
return str.AppendCustom(data, func(r rune) Cell {
|
||||||
copy(newStr, str)
|
return NewColorCell(r, color)
|
||||||
for i, char := range data {
|
})
|
||||||
newStr[i+len(str)] = NewColorCell(char, color)
|
|
||||||
}
|
|
||||||
return newStr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (str TString) AppendStyle(data string, style tcell.Style) TString {
|
func (str TString) AppendStyle(data string, style tcell.Style) TString {
|
||||||
|
return str.AppendCustom(data, func(r rune) Cell {
|
||||||
|
return NewStyleCell(r, style)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (str TString) AppendCustom(data string, cellCreator func(rune) Cell) TString {
|
||||||
newStr := make(TString, len(str)+len(data))
|
newStr := make(TString, len(str)+len(data))
|
||||||
copy(newStr, str)
|
copy(newStr, str)
|
||||||
for i, char := range data {
|
for i, char := range data {
|
||||||
newStr[i+len(str)] = NewStyleCell(char, style)
|
newStr[i+len(str)] = cellCreator(char)
|
||||||
}
|
}
|
||||||
return newStr
|
return newStr
|
||||||
}
|
}
|
||||||
|
@ -202,9 +202,9 @@ func (view *MainView) KeyEventHandler(roomView *RoomView, key *tcell.EventKey) *
|
|||||||
case tcell.KeyUp:
|
case tcell.KeyUp:
|
||||||
view.SwitchRoom(view.roomList.Previous())
|
view.SwitchRoom(view.roomList.Previous())
|
||||||
case tcell.KeyEnter:
|
case tcell.KeyEnter:
|
||||||
fuzz := NewFuzzyView(view, 42, 12)
|
searchModal := NewFuzzySearchModal(view, 42, 12)
|
||||||
view.parent.views.AddPage("fuzzy", fuzz, true, true)
|
view.parent.views.AddPage("fuzzy-search-modal", searchModal, true, true)
|
||||||
view.parent.app.SetFocus(fuzz)
|
view.parent.app.SetFocus(searchModal)
|
||||||
default:
|
default:
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user