lchat/web/wasm/app.go

223 lines
6.7 KiB
Go
Raw Normal View History

2024-11-12 19:34:06 +00:00
package main
import (
"bytes"
"encoding/json"
"git.ailur.dev/ailur/jsFetch"
"syscall/js"
"time"
)
var messageDivs = make(map[string]js.Value)
2024-11-12 19:34:06 +00:00
func refreshMessages(localStorage js.Value, messageBox js.Value, userId string) {
jsonBody, err := json.Marshal(map[string]interface{}{
"token": localStorage.Call("getItem", "token").String(),
})
if err != nil {
alert("Failed to encode request: " + err.Error())
return
}
response, err := jsFetch.Post(localStorage.Call("getItem", "server").String()+"/api/messages", "application/json", bytes.NewReader(jsonBody))
if err != nil {
alert("Failed to contact server: " + err.Error())
return
}
if response.StatusCode != 200 {
if response.StatusCode == 500 {
alert("Something went wrong on our end. Please try again later.")
} else {
var body map[string]interface{}
err := json.NewDecoder(response.Body).Decode(&body)
if err != nil {
alert("Failed to decode response: " + err.Error())
} else {
alert(body["error"].(string))
}
}
return
}
var body map[string]interface{}
2024-11-12 19:34:06 +00:00
err = json.NewDecoder(response.Body).Decode(&body)
if err != nil {
alert("Failed to decode response: " + err.Error())
return
}
if !messageBox.Get("lastChild").IsNull() {
messageBox.Get("lastChild").Get("style").Set("margin-bottom", "15px")
}
if len(messageDivs) > len(body) {
for id, _ := range messageDivs {
_, exists := body[id]
if !exists {
messageDivs[id].Call("remove")
delete(messageDivs, id)
}
2024-11-12 19:34:06 +00:00
}
}
2024-11-12 19:34:06 +00:00
for id, message := range body {
_, exists := messageDivs[id]
if !exists {
messageDiv := createMessage(message.(map[string]interface{})["message"].(string), message.(map[string]interface{})["name"].(string), message.(map[string]interface{})["sender"].(string) == userId, message.(map[string]interface{})["id"].(string), time.Unix(int64(message.(map[string]interface{})["sent"].(float64)), 0))
messageBox.Call("appendChild", messageDiv)
messageDivs[id] = messageDiv
}
2024-11-12 19:34:06 +00:00
}
if !messageBox.Get("lastChild").IsNull() {
messageBox.Get("lastChild").Get("style").Set("margin-bottom", "22.5px")
}
2024-11-12 19:34:06 +00:00
messageBox.Set("scrollTop", messageBox.Get("scrollTopMax").Float())
}
func alert(message string) {
js.Global().Call("alert", message)
}
func createMessage(message string, user string, delete bool, id string, timestamp time.Time) js.Value {
div := js.Global().Get("document").Call("createElement", "div")
author := js.Global().Get("document").Call("createElement", "span")
author.Get("classList").Call("add", "author")
author.Set("innerText", user)
content := js.Global().Get("document").Call("createElement", "span")
content.Get("classList").Call("add", "content")
content.Set("innerText", message)
timestampSpan := js.Global().Get("document").Call("createElement", "span")
timestampSpan.Get("classList").Call("add", "timestamp")
timestampSpan.Set("innerText", timestamp.Format("15:04"))
if delete {
div.Get("style").Set("padding-bottom", "55px")
deleteButton := js.Global().Get("document").Call("createElement", "button")
deleteButton.Set("innerText", "Delete")
deleteButton.Call("addEventListener", "click", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
jsonBody, err := json.Marshal(map[string]interface{}{
"id": id,
"token": js.Global().Get("localStorage").Call("getItem", "token").String(),
})
if err != nil {
alert("Failed to encode request: " + err.Error())
return
}
response, err := jsFetch.Post(js.Global().Get("localStorage").Call("getItem", "server").String()+"/api/delete", "application/json", bytes.NewReader(jsonBody))
if err != nil {
alert("Failed to contact server: " + err.Error())
return
}
if response.StatusCode != 200 {
if response.StatusCode == 500 {
alert("Something went wrong on our end. Please try again later.")
} else {
var body map[string]interface{}
err := json.NewDecoder(response.Body).Decode(&body)
if err != nil {
alert("Failed to decode response: " + err.Error())
} else {
alert(body["error"].(string))
}
}
return
}
div.Call("remove")
}()
return nil
}))
div.Call("appendChild", deleteButton)
}
div.Call("appendChild", author)
div.Call("appendChild", content)
return div
}
func main() {
localStorage := js.Global().Get("localStorage")
login := js.Global().Get("document").Call("getElementById", "login")
app := js.Global().Get("document").Call("getElementById", "app")
logout := js.Global().Get("document").Call("getElementById", "logout")
sendField := js.Global().Get("document").Call("getElementById", "sendField")
send := js.Global().Get("document").Call("getElementById", "send")
messageBox := js.Global().Get("document").Call("getElementById", "messageBox")
if localStorage.Call("getItem", "server").IsNull() {
localStorage.Call("setItem", "server", "https://chat.ailur.dev:1974")
}
if localStorage.Call("getItem", "token").IsNull() {
return
}
userId := localStorage.Call("getItem", "userId").String()
login.Get("style").Set("display", "none")
app.Get("style").Set("display", "initial")
logout.Call("addEventListener", "click", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
localStorage.Call("removeItem", "token")
js.Global().Get("location").Set("href", "login")
}()
return nil
}))
send.Call("addEventListener", "click", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
jsonBody, err := json.Marshal(map[string]interface{}{
"message": sendField.Get("value").String(),
"token": localStorage.Call("getItem", "token").String(),
})
if err != nil {
alert("Failed to encode request: " + err.Error())
return
}
response, err := jsFetch.Post(localStorage.Call("getItem", "server").String()+"/api/send", "application/json", bytes.NewReader(jsonBody))
if err != nil {
alert("Failed to contact server: " + err.Error())
return
}
if response.StatusCode != 200 {
if response.StatusCode == 500 {
alert("Something went wrong on our end. Please try again later.")
} else {
var body map[string]interface{}
err := json.NewDecoder(response.Body).Decode(&body)
if err != nil {
alert("Failed to decode response: " + err.Error())
} else {
alert(body["error"].(string))
}
}
return
}
}()
return nil
}))
go refreshMessages(localStorage, messageBox, userId)
go func() {
webSocket := js.Global().Get("WebSocket").New(localStorage.Call("getItem", "server").String() + "/api/ping")
webSocket.Set("onmessage", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go refreshMessages(localStorage, messageBox, userId)
return nil
}))
}()
select {}
}