From 7b04f9ca9e084348d9e8a93686c94f8caf201a15 Mon Sep 17 00:00:00 2001 From: VetheonGames Date: Wed, 6 Sep 2023 13:12:35 -0600 Subject: [PATCH] Put up our skeletons --- client_logic.go | 125 ++++++++++++++++++++++++++++++++++++++ common/message.go | 6 ++ config/client_config.json | 4 ++ go.mod | 5 ++ go.sum | 2 + main.go | 59 ++++++++++++++++++ ui/user_interface.go | 32 ++++++++++ 7 files changed, 233 insertions(+) create mode 100644 client_logic.go create mode 100644 common/message.go create mode 100644 config/client_config.json create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 ui/user_interface.go diff --git a/client_logic.go b/client_logic.go new file mode 100644 index 0000000..f545957 --- /dev/null +++ b/client_logic.go @@ -0,0 +1,125 @@ +package main + +import ( + "encoding/json" + "fmt" + "net" + "os" + + "./common" +) + +// Client holds the state for a chat client +type Client struct { + conn net.Conn + serverAddr string + username string +} + +// NewClient creates a new Client +func NewClient(serverAddr, username string) *Client { + return &Client{ + serverAddr: serverAddr, + username: username, + } +} + +// Connect to the server +func (c *Client) Connect() error { + conn, err := net.Dial("tcp", c.serverAddr) + if err != nil { + return err + } + c.conn = conn + return nil +} + +// JoinChannel allows the client to join a channel +func (c *Client) JoinChannel(channel string) error { + // Create a join channel request payload + joinRequest := map[string]string{ + "action": "join", + "channel": channel, + } + + // Serialize the join channel request to JSON + joinRequestJSON, err := json.Marshal(joinRequest) + if err != nil { + return fmt.Errorf("failed to serialize join request: %v", err) + } + + // Send the join channel request to the server + _, err = c.conn.Write(joinRequestJSON) + if err != nil { + return fmt.Errorf("failed to send join request to server: %v", err) + } + + // Optionally, we can wait for an acknowledgment from the server + // to confirm that the join request was successful. + + return nil +} + +// SendMessage sends a message to a channel +func (c *Client) SendMessage(channel string, message string) error { + // Create a Message object + msg := common.Message{ + Username: c.username, + Content: message, + } + + // Serialize the Message object to JSON + msgJSON, err := json.Marshal(msg) + if err != nil { + return fmt.Errorf("failed to serialize message: %v", err) + } + + // Create a send message request payload + sendRequest := map[string]interface{}{ + "action": "send", + "channel": channel, + "message": msgJSON, + } + + // Serialize the send message request to JSON + sendRequestJSON, err := json.Marshal(sendRequest) + if err != nil { + return fmt.Errorf("failed to serialize send request: %v", err) + } + + // Send the serialized send message request to the server + _, err = c.conn.Write(sendRequestJSON) + if err != nil { + return fmt.Errorf("failed to send message to server: %v", err) + } + + return nil +} + +// ListenForMessages listens for incoming messages from the server +func (c *Client) ListenForMessages() { + buffer := make([]byte, 4096) + + for { + // Read incoming data from the server + n, err := c.conn.Read(buffer) + if err != nil { + fmt.Printf("Error reading from server: %v\n", err) + return + } + + // Deserialize the received JSON into a Message object + var msg common.Message + err = json.Unmarshal(buffer[:n], &msg) + if err != nil { + fmt.Printf("Error deserializing message: %v\n", err) + continue + } + + // Handle the received message + // For now, we'll just print it to the console + fmt.Printf("%s: %s\n", msg.Username, msg.Content) + + // TODO: Update the GUI with the received message + } +} diff --git a/common/message.go b/common/message.go new file mode 100644 index 0000000..a4d9011 --- /dev/null +++ b/common/message.go @@ -0,0 +1,6 @@ +package common + +type Message struct { + Username string `json:"username"` + Content string `json:"content"` +} diff --git a/config/client_config.json b/config/client_config.json new file mode 100644 index 0000000..c1a52de --- /dev/null +++ b/config/client_config.json @@ -0,0 +1,4 @@ +{ + "server_address": "localhost:8080", + "username": "default_user" + } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3403008 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module RidgedChat + +go 1.21.0 + +require fyne.io/fyne/v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6d01d78 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +fyne.io/fyne/v2 v2.4.0 h1:LlyOyHmvkSo9IBm3aY+NVWSBIw+GMnssmyyIMK8F7zM= +fyne.io/fyne/v2 v2.4.0/go.mod h1:AWM1iPM2YfliduZ4u/kQzP9E6ARIWm0gg+57GpYzWro= diff --git a/main.go b/main.go new file mode 100644 index 0000000..7f5015c --- /dev/null +++ b/main.go @@ -0,0 +1,59 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" +) + +// Config holds the client configuration +type Config struct { + ServerAddress string `json:"server_address"` + Username string `json:"username"` +} + +// ReadConfig reads the client configuration from a JSON file +func ReadConfig(filePath string) (*Config, error) { + file, err := ioutil.ReadFile(filePath) + if err != nil { + return nil, err + } + + var config Config + if err := json.Unmarshal(file, &config); err != nil { + return nil, err + } + + return &config, nil +} + +func main() { + // Read client configuration from client_config.json + config, err := ReadConfig("config/client_config.json") + if err != nil { + fmt.Println("Error reading config:", err) + os.Exit(1) + } + + // Initialize the client with the server address and username from the config + client := NewClient(config.ServerAddress, config.Username) + + // Connect to the server + if err := client.Connect(); err != nil { + fmt.Println("Error connecting to server:", err) + os.Exit(1) + } + + // Start listening for messages in a separate goroutine + go client.ListenForMessages() + + // Launch the GUI + go ui.StartGUI() + + // TODO: Implement channel joining and message sending logic + // TODO: Implement graceful shutdown logic + + // Keep the main function running to keep the application alive + select {} +} diff --git a/ui/user_interface.go b/ui/user_interface.go new file mode 100644 index 0000000..35ebadc --- /dev/null +++ b/ui/user_interface.go @@ -0,0 +1,32 @@ +package ui + +import ( + "fyne.io/fyne/v2/app" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/widget" +) + +// StartGUI initializes and starts the GUI for the chat client +func StartGUI() { + // Initialize the Fyne app + myApp := app.New() + myWindow := myApp.NewWindow("RidgeChat - The World's most Ridged Self-Hosted Chat Program") + + // Create UI elements + messageList := widget.NewLabel("Messages will appear here") + inputField := widget.NewEntry() + inputField.SetPlaceHolder("Type your message...") + sendButton := widget.NewButton("Send", func() { + // TODO: Implement send message logic + }) + + // Create layout + content := container.NewVBox( + messageList, + container.NewHBox(inputField, sendButton), + ) + + // Set and show the window content + myWindow.SetContent(content) + myWindow.ShowAndRun() +}