Example #1
0
func (e *StatusCmd) Exec(args []string) error {

	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
		if s.Client != nil && s.Client.Connected() {
			client.StatusMessage(v, "Status: Connected.")
		} else {
			client.StatusMessage(v, "Status: Disconnected.")
		}

		return nil
	})

	return nil
}
Example #2
0
func (e *WindowCmd) Exec(args []string) error {
	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		if !s.Client.Connected() {
			client.StatusMessage(v, "Not connected")
			return nil
		}

		if len(args) == 2 {
			i := common.StringTo(args[1]).MustInt()

			Server.CurrentChannel = Server.Channels[i].Name
			Server.Gui.SetViewOnTop(Server.CurrentChannel)

			c := Server.GetCurrentChannel()

			if _, err := g.SetCurrentView(c.Name); err != nil {
				return err
			}

			c.Unread = false

			if _, err := g.SetCurrentView("input"); err != nil {
				return err
			}

			ui.UpdateMenuView(g)
		}

		return nil
	})

	return nil
}
Example #3
0
func (e *QueryCmd) Exec(args []string) error {
	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		if !s.Client.Connected() {
			client.StatusMessage(v, "Not connected")
			return nil
		}

		if len(args) >= 2 && len(args[1]) > 0 {
			CurrentChannel = args[1]
			s.CurrentChannel = args[1]

			s.NewChannel(args[1], true)

			if len(args[2]) > 0 {
				go Server.Client.Privmsg(args[1],
					strings.Replace(args[2], "\x00", "", -1))
			}

		}

		return nil
	})

	return nil
}
Example #4
0
func (e *VersionCmd) Exec(args []string) error {

	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
		client.StatusMessage(v, ui.VersionLine)
		return nil
	})

	return nil
}
Example #5
0
func (e *EmptyCmd) Exec(args []string) error {

	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
		client.StatusMessage(v, fmt.Sprintf("Unknow Command: %s", args[0]))
		return nil
	})

	return nil
}
Example #6
0
func (e *HelpCmd) Exec(args []string) error {

	Server.Exec(Server.CurrentChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		client.StatusMessage(v, "==================== HELP COMMANDS ====================")

		for _, command := range Commands {
			metadata := command.Metadata()
			client.StatusMessage(v, fmt.Sprintf("/%s %s - %s",
				metadata.Name(), metadata.Args(), metadata.Description()))
		}

		client.StatusMessage(v, "==================== HELP COMMANDS ====================\n")

		return nil
	})

	return nil
}
Example #7
0
func (e *ConnectCmd) Exec(args []string) error {

	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		if s.Client.Connected() {
			client.StatusMessage(v, "Already Connecting and/or Connected...")
			return nil
		}

		client.StatusMessage(v, "Connecting... please wait.")

		if err := s.Client.Connect(); err != nil {
			log.Fatal(err)
		}

		go func() {
			ticker := time.NewTicker(8000 * time.Microsecond)

			for {
				select {
				case <-ticker.C:
					fmt.Fprint(v, ".")
				case msg := <-ui.LoadingChannel.Recv:
					if msg == "done" {

						fmt.Fprint(v, "\n")
						ticker.Stop()
						break
					}
				}
			}
		}()

		return nil
	})

	return nil
}
Example #8
0
func (e *PartCmd) Exec(args []string) error {
	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		if !s.Client.Connected() {
			client.StatusMessage(v, "Not connected")
			return nil
		}

		if len(args) >= 2 {

			if args[1] == client.StatusChannel {
				return nil
			}

			s.Client.Part(args[1])

			index, err := s.RemoveChannel(args[1])

			if len(s.Channels) <= 1 {
				CurrentChannel = client.StatusChannel
				Server.CurrentChannel = client.StatusChannel
				Server.Gui.SetViewOnTop(client.StatusChannel)
			} else {
				Server.CurrentChannel = Server.Channels[index-1].Name
				Server.Gui.SetViewOnTop(Server.CurrentChannel)

				c := Server.GetCurrentChannel()

				if _, err := g.SetCurrentView(c.Name); err != nil {
					return err
				}

				c.Unread = false
			}

			if _, err := g.SetCurrentView("input"); err != nil {
				return err
			}

			ui.UpdateMenuView(g)

			return err
		}

		return nil
	})

	return nil
}
Example #9
0
func (e *RawCmd) Exec(args []string) error {

	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
		if !s.Client.Connected() {
			client.StatusMessage(v, "Not connected")
			return nil
		}

		cmd := strings.Join(args[1:], " ")
		logger.Logger.Printf("RAW COMMAND %s\n", cmd)
		s.Client.Raw(cmd)
		return nil
	})

	return nil
}
Example #10
0
func (e *TopicCmd) Exec(args []string) error {
	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		if !s.Client.Connected() {
			client.StatusMessage(v, "Not connected")
			return nil
		}

		if len(args) == 3 && strings.HasPrefix(args[1], "#") {
			s.Client.Topic(args[1], args[2])
		} else if len(args) == 2 {
			s.Client.Topic(Server.CurrentChannel, args[1])
		}

		return nil
	})

	return nil
}
Example #11
0
func (e *PassCmd) Exec(args []string) error {
	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		if !s.Client.Connected() {
			client.StatusMessage(v, "Not connected")
			return nil
		}

		logger.Logger.Printf("pass %s \n", args)

		if len(args) == 2 && len(args[1]) > 0 {
			s.Client.Pass(args[1])
		}

		return nil
	})

	return nil
}
Example #12
0
func (e *NamesCmd) Exec(args []string) error {

	Server.Exec(Server.CurrentChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		if !s.Client.Connected() {
			client.StatusMessage(v, "Not connected")
			return nil
		}

		channel := Server.GetCurrentChannel()

		if channel != nil {
			channel.NickListString(v)
		}

		return nil
	})

	return nil
}
Example #13
0
func (e *JoinCmd) Exec(args []string) error {
	Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

		if !s.Client.Connected() {
			client.StatusMessage(v, "Not connected")
			return nil
		}

		if len(args) >= 2 && len(args[1]) > 0 {
			s.Client.Join(args[1])
			CurrentChannel = args[1]
			s.CurrentChannel = args[1]

			return s.NewChannel(args[1], false)
		}

		return nil
	})

	return nil
}
Example #14
0
func GetLine(g *gocui.Gui, v *gocui.View) error {
	// _, cy := v.Cursor()
	// if line, err = v.Line(0); err != nil {
	// line = ""
	// }

	line := v.Buffer()

	// logger.Logger.Printf("LINE %s\n", line)

	if len(line) <= 0 {
		// return errors.New("input line empty")
		v.Clear()
		v.SetCursor(0, 0)
		return nil
	}

	line = strings.Replace(line, "\x00", "", -1)
	line = strings.Replace(line, "\n", "", -1)

	InputHistory.Add(line)

	if strings.HasPrefix(line, "//") || !strings.HasPrefix(line, "/") {
		if len(Server.CurrentChannel) > 0 {

			Server.Exec(Server.CurrentChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
				if Server.Client.Connected() {
					// logger.Logger.Println("SEND:::", spew.Sdump(line))

					go Server.Client.Privmsg(Server.CurrentChannel, line)
				}
				return nil
			})

			if mainView, err := g.View(Server.CurrentChannel); err != nil {
				return err
			} else {
				if mainView.Name() != client.StatusChannel {

					c := Server.FindChannel(Server.CurrentChannel)

					timestamp := time.Now().Format("03:04")
					fmt.Fprintf(mainView, "[%s] -> %s: %s\n",
						ui.ColorString(ui.TimestampColor, timestamp),
						myNickColor(c.FindUser(Server.Client.Me().Nick).String(false)),
						myTextColor(line))
				}
			}
		}
		// send text
	} else {
		split := strings.Split(strings.Replace(line[1:], "\x00", "", -1), " ")

		// logger.Logger.Println("IN COMMAND!!!", line, spew.Sdump(split))

		// mainView, _ := g.View(client.StatusChannel)
		// fmt.Fprintln(mainView, "$ COMMAND = ", split[0], len(split))

		// TODO: what was this?
		if len(split) <= 1 {
			if split[0] == "p" || split[0] == "part" {
				command.Run(split[0], []string{"", Server.CurrentChannel})
				v.Clear()
				v.SetCursor(0, 0)
				return nil
			}
		}

		if err := command.Run(split[0], split); err != nil {
			client.StatusMessage(v, err.Error())
		}
	}

	// idleInputText := fmt.Sprintf("[%s] ", client.StatusChannel)

	// if len(command.CurrentChannel) > 0 {
	// idleInputText = fmt.Sprintf("[%s] ", command.CurrentChannel)
	// }

	// fmt.Fprint(v, idleInputText)
	// v.SetCursor(len(idleInputText), 0)

	v.Clear()
	v.SetCursor(0, 0)

	inCacheTab = false
	cacheTabSearch = ""
	cacheTabResults = []string{}

	FocusAndResetAll(g, v)

	return nil
}
Example #15
0
func BindHandlers() {

	for _, code := range client.IrcCodes {
		Server.Client.HandleFunc(code, func(conn *irc.Conn, line *irc.Line) {

			Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
				// client.StatusMessage(v, fmt.Sprintf("%s (CODE: %s)", line.Text(), line.Cmd))
				client.StatusMessage(v, fmt.Sprintf("%s", line.Text()))
				return nil
			})
		})
	}

	Server.Client.HandleFunc("WHOIS", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("WHOIS -----------------------------", spew.Sdump(line))
	})

	Server.Client.HandleFunc("WHO", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("WHO -----------------------------", spew.Sdump(line))
	})

	Server.Client.HandleFunc("NOTICE", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("NOTICE -----------------------------", spew.Sdump(line))
	})

	Server.Client.HandleFunc("NICK", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("NICK -----------------------------", spew.Sdump(line))

		for _, c := range Server.Channels {
			u := c.FindUser(line.Nick)

			if u != nil {
				u.Nick = line.Args[0]

				Server.Exec(c.Name, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
					fmt.Fprintf(v, "[%s] %s has changed nick to %s\n", color.GreenString("+NICK"), line.Nick, line.Args[0])
					return nil
				})
			}
		}
	})

	Server.Client.HandleFunc("KICK", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("KICK -----------------------------", spew.Sdump(line))
	})

	Server.Client.HandleFunc("AWAY", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("AWAY -----------------------------", spew.Sdump(line))
	})

	Server.Client.HandleFunc("ACTION", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("ACTION -----------------------------", spew.Sdump(line))
	})

	Server.Client.HandleFunc("REGISTER", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("REGISTER -----------------------------", spew.Sdump(line))
	})

	Server.Client.HandleFunc("QUIT", func(conn *irc.Conn, line *irc.Line) {
		// logger.Logger.Println("QUIT -----------------------------", spew.Sdump(line))

		for _, c := range Server.Channels {
			u := c.FindUser(line.Nick)

			if u != nil {
				c.RemoveNick(line.Nick)

				Server.Exec(c.Name, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
					fmt.Fprintf(v, "[%s] %s [%s@%s] has quit [%s]\n", color.RedString("-EXIT"), line.Nick, line.Ident, line.Host, line.Text())
					return nil
				})
			}
		}
	})

	Server.Client.HandleFunc("USER", func(conn *irc.Conn, line *irc.Line) {
		logger.Logger.Println("USER -----------------------------", spew.Sdump(line))
	})

	Server.Client.HandleFunc("TOPIC", func(conn *irc.Conn, line *irc.Line) {
		// logger.Logger.Println("TOPIC  -----------------------------", spew.Sdump(line))

		if c, _, has := Server.HasChannel(line.Args[0]); has {
			Server.Exec(c.Name, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
				c.Topic = line.Args[1]

				fmt.Fprintf(v, "%s %s changed the topic of %s to: %s\n", color.GreenString("**"), line.Nick, line.Nick, c.Topic)

				return nil
			})
		}
	})

	Server.Client.HandleFunc("JOIN", func(conn *irc.Conn, line *irc.Line) {
		// logger.Logger.Println("JOIN -----------------------------", line.Text())
		// logger.Logger.Println("JOIN -----------------------------", spew.Sdump(line))

		if c, _, has := Server.HasChannel(line.Text()); has {
			Server.Exec(c.Name, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
				if line.Nick != Server.Client.Me().Nick {
					c.AddNick(line.Nick)
				}
				fmt.Fprintf(v, "[%s] %s [%s@%s] has joined %s\n", color.GreenString("+JOIN"), line.Nick, line.Ident, line.Host, c.Name)
				return nil
			})
		}
	})

	Server.Client.HandleFunc("PART", func(conn *irc.Conn, line *irc.Line) {
		// logger.Logger.Println("PART -----------------------------", line.Text())

		if c, _, has := Server.HasChannel(line.Text()); has {
			Server.Exec(c.Name, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
				c.RemoveNick(line.Nick)
				fmt.Fprintf(v, "[%s] %s [%s@%s] has quit [%s]\n", color.RedString("-PART"), line.Nick, line.Ident, line.Host, line.Text())
				return nil
			})
		}
	})

	// nick in use
	Server.Client.HandleFunc("433", func(conn *irc.Conn, line *irc.Line) {
		Server.Exec(Server.CurrentChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
			fmt.Fprintf(v, "%s %s\n", color.RedString("=="), fmt.Sprintf("Nick %s is already in use.", line.Nick))
			return nil
		})
	})

	// op needed
	Server.Client.HandleFunc("482", func(conn *irc.Conn, line *irc.Line) {
		if c, _, has := Server.HasChannel(line.Args[1]); has {
			Server.Exec(c.Name, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
				fmt.Fprintf(v, "%s %s\n", color.RedString("=="), line.Text())
				return nil
			})
		} else {
			Server.Exec(client.StatusChannel, func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
				fmt.Fprintf(v, "%s %s\n", color.RedString("=="), line.Text())
				return nil
			})
		}
	})

	Server.Client.HandleFunc("331", func(conn *irc.Conn, line *irc.Line) {
		if c, _, has := Server.HasChannel(line.Args[1]); has {
			c.Topic = "N/A"
		}
	})

	//
	// TOPIC
	// https://www.alien.net.au/irc/irc2numerics.html
	//
	Server.Client.HandleFunc("332", func(conn *irc.Conn, line *irc.Line) {
		// logger.Logger.Println("TOPIC........", spew.Sdump(line))

		Server.Exec(line.Args[1], func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

			if c, _, has := Server.HasChannel(line.Args[1]); has {
				c.Topic = line.Args[2]
				fmt.Fprintf(v, "%s Topic of %s: %s\n", color.GreenString("**"), line.Args[1], c.Topic)
			}

			return nil
		})

	})

	// names list done
	Server.Client.HandleFunc("366", func(conn *irc.Conn, line *irc.Line) {
		Server.Exec(line.Args[1], func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

			// v.Clear()
			// v.SetCursor(0, 0)

			// logger.Logger.Println("NICK LIST DONE")

			if c, _, has := s.HasChannel(line.Args[1]); has {

				go func(c *client.Channel) {
					for {
						select {
						case <-c.Loading.Recv:
							// logger.Logger.Println("INSIDE THE NAMES AND STUFF...")
							if !c.NickListReady {
								c.NickListReady = true

								c.NickListString(v)
								c.NickMetricsString(v)
							}
							break
						}
					}
				}(c)

				// var topic string

				// if len(c.Topic) <= 0 {
				// topic = "N/A"
				// } else {
				// topic = c.Topic
				// }

				// fmt.Fprintf(v, "⣿ CHANNEL: %s\n", c.Name)
				// fmt.Fprintf(v, "⣿   Users: %d\n", len(c.Names))
				// fmt.Fprintf(v, "⣿   TOPIC: %s\n", topic)

				// fmt.Fprint(v, "⣿   NAMES: \n")

				// w := tabwriter.NewWriter(v, 0, 8, 3, ' ', tabwriter.DiscardEmptyColumns)

				// count := 1
				// current := ""
				// for _, u := range c.Names {
				// if count < 7 {
				// current = current + fmt.Sprintf("%s\t", u)
				// count += 1
				// } else {
				// fmt.Fprintln(w, current)
				// current = ""
				// count = 1
				// }
				// }

				// if current != "" {
				// fmt.Fprintln(w, current)
				// }

				// w.Flush()

				// fmt.Fprint(v, "\n")
			}
			return nil
		})
	})

	// nick list
	Server.Client.HandleFunc("353", func(conn *irc.Conn, line *irc.Line) {
		// logger.Logger.Printf("NICK LIST %s\n", spew.Sdump(line))

		Server.Exec(line.Args[2], func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

			if c, _, has := Server.HasChannel(line.Args[2]); has {
				nicks := strings.Split(line.Args[len(line.Args)-1], " ")

				for _, nick := range nicks {
					// UnrealIRCd's coders are lazy and leave a trailing space
					if nick == "" {
						continue
					}

					// logger.Logger.Printf("ADD NICK %s\n", spew.Sdump(nick))

					user := &client.User{}

					switch c := nick[0]; c {
					case '~', '&', '@', '%', '+':
						nick = nick[1:]
						fallthrough
					default:
						switch c {
						case '~':
							// conn.st.ChannelModes(ch.Name, "+q", nick)
						case '&':
							// conn.st.ChannelModes(ch.Name, "+a", nick)
						case '@':
							user.Mode = "@"
							// conn.st.ChannelModes(ch.Name, "+o", nick)
							// fmt.Fprintf(v, "@%s ", nick)
						case '%':
							// conn.st.ChannelModes(ch.Name, "+h", nick)
							user.Mode = "%"
						case '+':
							user.Mode = "+"
							// conn.st.ChannelModes(ch.Name, "+v", nick)
							// fmt.Fprintf(v, "+%s ", nick)
						default:
							{

								// fmt.Fprintf(v, "+%s ", nick)
							}
						}

					}

					// logger.Logger.Printf("ADD NICK %s\n", spew.Sdump(nick))

					if u := c.FindUser(nick); u == nil {
						user.Nick = nick
						user.Color = client.ANSIColors[rand.Intn(len(client.ANSIColors))]
						c.Users = append(c.Users, user)
					}

				}

				c.Loading.Send <- nil
			}

			return nil
		})
	})

	// Server.Client.HandleFunc("315", func(conn *irc.Conn, line *irc.Line) {
	// Server.Exec(line.Args[1], func(v *gocui.View, s *client.Server) error {
	// return nil
	// })
	// })

	// 328
	// 331 -- no topic

	// 333 -- topic set by
	Server.Client.HandleFunc("333", func(conn *irc.Conn, line *irc.Line) {
		// logger.Logger.Printf("TOPIC SET BY %s\n", spew.Sdump(line))

		Server.Exec(line.Args[1], func(g *gocui.Gui, v *gocui.View, s *client.Server) error {

			i, err := strconv.ParseInt(line.Args[3], 10, 64)

			if err != nil {
				logger.Logger.Printf(err.Error())
			}

			tm := time.Unix(i, 0)

			if strings.Contains(line.Args[2], "!") {
				ss := strings.Split(line.Args[2], "!")

				fmt.Fprintf(v, "%s Topic set by %s [%s] [%s]\n", color.GreenString("**"),
					ss[0], ss[1], tm.Format(time.RFC822))
			} else {
				fmt.Fprintf(v, "%s Topic set by %s [%s]\n", color.GreenString("**"),
					line.Args[2], tm.Format(time.RFC822))
			}

			return nil
		})
	})

	Server.Client.HandleFunc(irc.PRIVMSG, func(conn *irc.Conn, line *irc.Line) {

		ircChan := line.Args[0]

		// logger.Logger.Printf("MSG %s %s %s %s\n", ircChan, line.Nick, line.Host, line.Args)

		if ircChan == Server.Client.Me().Nick {

			if c, _, has := Server.HasChannel(line.Nick); !has {
				Server.NewChannel(line.Nick, true)
			} else {
				if Server.CurrentChannel != line.Nick {
					c.Unread = true

				}
			}

			Server.Exec(line.Nick,
				func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
					timestamp := time.Now().Format("03:04")
					fmt.Fprintf(v, "[%s] <- %s: %s\n", timestampColor(timestamp), nickColor(line.Nick), line.Text())

					notify.Push(fmt.Sprintf("Private message from %s", line.Nick), line.Text(), "", notificator.UR_NORMAL)

					return nil
				})

		} else {

			if c, _, has := Server.HasChannel(ircChan); has {

				if Server.CurrentChannel != c.Name {
					c.Unread = true
				}

				Server.Exec(ircChan,
					func(g *gocui.Gui, v *gocui.View, s *client.Server) error {
						timestamp := time.Now().Format("03:04")

						var highlight bool

						if strings.Contains(line.Text(), Server.Client.Me().Nick) {
							highlight = true
							notify.Push(fmt.Sprintf("Highlight from %s", line.Nick), line.Text(), "", notificator.UR_NORMAL)
						}

						text := line.Text()
						style := "<-"

						if highlight {
							text = color.YellowString(text)
							style = color.YellowString("!!")
						}

						fmt.Fprintf(v, "[%s] %s %s: %s\n", timestampColor(timestamp), style, c.FindUser(line.Nick).String(true), text)

						return nil
					})
			}

		}
	})

	Server.Client.HandleFunc("464", func(conn *irc.Conn, line *irc.Line) {
		LoadingChannel.Send <- "done"
	})

	Server.Client.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) {
		// logger.Logger.Printf("LINE %s\n", spew.Sdump(line))
		LoadingChannel.Send <- "done"
	})

	Server.Client.HandleFunc(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) {
		LoadingChannel.Send <- "done"
	})

}
Example #16
0
func Layout(g *gocui.Gui) error {
	maxX, maxY := g.Size()

	notify = notificator.New(notificator.Options{
		AppName: Name,
	})

	// if _, err := g.SetView("sidebar", -1, -1, int(0.2*float32(maxX)), maxY-3); err != nil {
	// if err != gocui.ErrorUnkView {
	// return err
	// }
	// }

	if err := HeaderView(g, -1, -1, maxX, 1); err != nil {
		panic(err)
	}

	if _, _, ok := Server.HasChannel(client.StatusChannel); !ok {
		status := client.Channel{
			Status: true,
			Name:   client.StatusChannel,
			MaxX:   maxX,
			MaxY:   maxY,
			RenderHandler: func(channel *client.Channel, view *gocui.View) error {
				view.Autoscroll = true
				view.Wrap = true
				view.Frame = false

				// view.FgColor = gocui.ColorGreen
				view.BgColor = gocui.ColorDefault

				fmt.Fprintln(view, "")
				fmt.Fprintln(view, Logo)
				fmt.Fprintln(view, color.GreenString(VersionLine))

				client.StatusMessage(view, fmt.Sprintf("Welcome to the %s IRC client.", Name))
				client.StatusMessage(view, "Type /help for a list of commands.\n")

				return nil
			},
		}

		Server.AddChannel(&status)

		logger.Logger.Printf("LAYOUT %p %p\n", g, Server.Gui)

		if err := status.Render(false); err != nil {
			return err
		}

		BindHandlers()

	} else {
		for _, c := range Server.Channels {
			c.Update()
		}
	}

	if err := MenuView(g, maxX, maxY); err != nil {
		return err
	}

	// if err := InputView(g, 20, maxY-2, maxX, maxY); err != nil {
	// return err
	// }

	return nil
}