lchat/web/wasm/app.go

228 lines
6.9 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 messages []map[string]interface{}
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{}
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(messages) < len(body) {
for _, message := range body[len(messages):] {
messageDiv := createMessage(message["message"].(string), message["name"].(string), message["sender"].(string) == userId, message["id"].(string), time.Unix(int64(message["sent"].(float64)), 0))
messageBox.Call("appendChild", messageDiv)
}
} else {
}
messageBox.Get("lastChild").Get("style").Set("margin-bottom", "22.5px")
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
}
username := localStorage.Call("getItem", "username").String()
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
}
var body map[string]interface{}
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")
}
message := createMessage(sendField.Get("value").String(), username, true, body["id"].(string), time.Now())
message.Get("style").Set("margin-bottom", "22.5px")
messageBox.Call("appendChild", message)
messageBox.Set("scrollTop", messageBox.Get("scrollTopMax").Float())
}()
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 {}
}