Skip to content

Commit

Permalink
feat: Chat colors
Browse files Browse the repository at this point in the history
* chore: optimization + bug fix

* docs: added

* chore: general utils file

* feat: chat colors
  • Loading branch information
Topvennie authored Aug 6, 2024
1 parent 3eddef2 commit cd709b3
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 26 deletions.
10 changes: 6 additions & 4 deletions api/cammie.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,21 @@ import (
gin "github.com/gin-gonic/gin"
)

// message struct
type message struct {
Message string `form:"message" json:"message" xml:"message" binding:"required"`
}

// header struct
type header struct {
Name string `header:"X-Username"`
Ip string `header:"X-Real-IP"`
}

var messages uint64 = 0
var blockedNames = []string{"Paul-Henri Spaak"}
var blockedIps = []string{}
var maxMessageLength = 200
var blockedNames = []string{"Paul-Henri Spaak"} // Blocekd names
var blockedIps = []string{} // Blocked IPs
var maxMessageLength = 200 // Maximum message length

func getMessage(app *screen.ScreenApp, c *gin.Context) {
c.JSON(200, gin.H{"messages": messages})
Expand Down Expand Up @@ -57,7 +59,7 @@ func postMessage(app *screen.ScreenApp, c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Message received"})
return
}
newMessage = fmt.Sprintf("[%s] %s", header.Name, message.Message)
newMessage = fmt.Sprintf("[%s[] %s", header.Name, message.Message)
} else if header.Ip != "" {
if slices.Contains(blockedIps, header.Ip) {
c.JSON(http.StatusOK, gin.H{"message": "Message received"})
Expand Down
6 changes: 6 additions & 0 deletions api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,27 @@ import (
"github.com/gin-gonic/gin"
)

// Wrapper for the handler functions to pass the screen application
func handlerWrapper(app *screen.ScreenApp, callback func(*screen.ScreenApp, *gin.Context)) func(*gin.Context) {
return func(ctx *gin.Context) {
callback(app, ctx)
}
}

// Start the API
func Start(screenApp *screen.ScreenApp) {
gin.SetMode(gin.ReleaseMode)
gin.DefaultWriter = io.Discard

r := gin.Default()

// Routes

// Cammie chat routes
r.GET("/message", handlerWrapper(screenApp, getMessage))
r.POST("/message", handlerWrapper(screenApp, postMessage))

// Spotify routes
r.POST("/spotify", spotifyHandlerWrapper(screenApp))

r.Run()
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module scc
go 1.22.0

require (
github.com/gdamore/tcell/v2 v2.7.1
github.com/gin-gonic/gin v1.9.1
github.com/rivo/tview v0.0.0-20240225120200-5605142ca62e
)
Expand All @@ -12,7 +13,6 @@ require (
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell/v2 v2.7.1 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
Expand Down
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import (
)

func main() {
// Data holder for the screen
screenApp := screen.NewScreenApp()

// Start the API
go api.Start(screenApp)

// Start the screen
screen.Start(screenApp)
}
47 changes: 30 additions & 17 deletions screen/cammie.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package screen

import (
"scc/utils"
"fmt"
"time"

"github.com/gdamore/tcell/v2"
Expand All @@ -11,49 +11,62 @@ import (
// Initial value, gets adjusted once it's known how much space is available
var maxMessages = 20

// Available colors
var COLORS = [...]tcell.Color{
tcell.ColorViolet,
tcell.ColorRed,
tcell.ColorIndigo,
tcell.ColorYellow,
tcell.ColorBlue,
tcell.ColorGreen,
tcell.ColorOrange,
tcell.ColorLime,
tcell.ColorAqua,
tcell.ColorDarkSalmon,
tcell.ColorLightBlue,
tcell.ColorNavajoWhite,
}
var lastColorIndex = 0

// Component that displays messages received from the website aka cammie chat
type Cammie struct {
screenApp *ScreenApp
view *tview.TextView

queue *utils.Queue[string]
text string
buffer string
}

// Create a new cammie struct
func NewCammie(screenApp *ScreenApp) *Cammie {
cammie := Cammie{
screenApp: screenApp,
view: tview.NewTextView().SetWrap(true).SetWordWrap(true).SetText("pls"),

queue: utils.NewQueue[string](maxMessages),
view: tview.NewTextView().SetWordWrap(true).SetScrollable(true).SetDynamicColors(true),
}

cammie.view.SetTitle(" Cammie ")
cammie.view.SetBorder(true)
cammie.view.SetTextColor(tcell.ColorOrange)
cammie.view.SetBorderColor(tcell.ColorOrange)
cammie.view.SetTitleColor(tcell.ColorOrange)

return &cammie
}

// One-time setup
func (cammie *Cammie) Run() {
// Wait for the view to be properly set up
time.Sleep(5 * time.Second)

_, _, _, h := cammie.view.GetInnerRect()
cammie.queue.SetMaxSize(h)
}

// Updates the cammie chat
// Gets called when a new message is received from the website
func (cammie *Cammie) Update(message string) {
cammie.queue.Enqueue(message)
color := COLORS[lastColorIndex].String()
lastColorIndex = (lastColorIndex + 1) % len(COLORS)

fmt.Fprintf(cammie.view, "\n[%s]%s", color, message)

cammie.screenApp.execute(func() {
cammie.screenApp.app.QueueUpdateDraw(func() {
cammie.view.Clear()
cammie.view.ScrollToEnd()

for _, message := range cammie.queue.Get() {
cammie.view.Write([]byte(message + "\n"))
}
})
})
}
11 changes: 7 additions & 4 deletions screen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/rivo/tview"
)

// Main struct for the screen application
type ScreenApp struct {
mu sync.Mutex
app *tview.Application
Expand All @@ -16,16 +17,14 @@ type ScreenApp struct {
Graph2 *Graph2
}

type s_cammie struct {
cammie *tview.TextView
}

// Execute a function with a lock
func (screenApp *ScreenApp) execute(f func()) {
screenApp.mu.Lock()
defer screenApp.mu.Unlock()
f()
}

// Create a new screen application
func NewScreenApp() *ScreenApp {
screen := ScreenApp{
app: tview.NewApplication(),
Expand All @@ -36,6 +35,7 @@ func NewScreenApp() *ScreenApp {
screen.Graph1 = NewGraph1(&screen)
screen.Graph2 = NewGraph2(&screen)

// Build the screen layout
screen.app.SetRoot(tview.NewFlex().SetDirection(tview.FlexRow).
AddItem(screen.Spotify.view, 3, 2, false).
AddItem(tview.NewFlex().
Expand All @@ -48,13 +48,16 @@ func NewScreenApp() *ScreenApp {
return &screen
}

// Start the screen application
func Start(screen *ScreenApp) {

// Start each screen component
go screen.Spotify.Run()
go screen.Cammie.Run()
go screen.Graph1.Run()
go screen.Graph2.Run()

// Start the screen application
if err := screen.app.Run(); err != nil {
panic(err)
}
Expand Down
13 changes: 13 additions & 0 deletions utils/queue.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
package utils

// Simple Queue implementation
type Queue[T any] struct {
maxSize int
Items []T
}

// Create a new Queue with a maximum size
func NewQueue[T any](maxSize int) *Queue[T] {
return &Queue[T]{
maxSize: maxSize,
Items: make([]T, 0, maxSize),
}
}

// Add an item to the Queue
func (q *Queue[T]) Enqueue(item T) {
if len(q.Items) >= q.maxSize {
q.Items = q.Items[1:]
}
q.Items = append(q.Items, item)
}

// Remove an item from the Queue
func (q *Queue[T]) Dequeue() (T, bool) {
if len(q.Items) == 0 {
var zero T
Expand All @@ -30,6 +34,7 @@ func (q *Queue[T]) Dequeue() (T, bool) {
return item, true
}

// Get the first item in the Queue wtihout removing it
func (q *Queue[T]) Peek() (T, bool) {
if len(q.Items) == 0 {
var zero T
Expand All @@ -39,10 +44,18 @@ func (q *Queue[T]) Peek() (T, bool) {
return q.Items[0], true
}

// Get all items in the Queue
func (q *Queue[T]) Get() []T {
return q.Items
}

// Get the size of the Queue
func (q *Queue[T]) Size() int {
return len(q.Items)
}

// Set the maximum size of the Queue
// If the new maximum size is smaller than the current size, the Queue will be truncated and items will potentially be lost
func (q *Queue[T]) SetMaxSize(maxSize int) {
q.maxSize = maxSize

Expand Down
16 changes: 16 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package utils

import (
"math/rand/v2"
"time"
)

func RandRange(min, max int) int {
return rand.IntN(max-min) + min
}

func TimeAndDateFormat() string {
currentTime := time.Now()
formattedTime := currentTime.Format("15:04 02/01")
return formattedTime
}

0 comments on commit cd709b3

Please sign in to comment.