Files
clipboard-on-the-go/client/sync.go
Space-Banane 4e637bc27d first commit
2026-01-17 15:19:07 +01:00

145 lines
3.3 KiB
Go

package main
import (
"bytes"
"fmt"
"log"
"github.com/getlantern/systray"
"github.com/gorilla/websocket"
"golang.design/x/clipboard"
)
var (
conn *websocket.Conn
lastClipboard []byte
identification string
isConnected bool
)
func onReady() {
// Use embedded icon
systray.SetIcon(EmbeddedIcon)
systray.SetTitle("Clipboard Sync")
systray.SetTooltip("Clipboard synchronization active")
mStatus := systray.AddMenuItem("Status: Connecting...", "Connection status")
mStatus.Disable()
systray.AddSeparator()
mQuit := systray.AddMenuItem("Quit", "Quit the application")
// Start clipboard monitoring
go monitorClipboard()
// Start client connection
go startClient(mStatus)
// Handle menu interactions
go func() {
for {
select {
case <-mQuit.ClickedCh:
systray.Quit()
}
}
}()
}
func onExit() {
if conn != nil {
conn.Close()
}
log.Println("Exiting clipboard sync client")
}
func startClient(statusItem *systray.MenuItem) {
// Use embedded configuration
identification = EmbeddedIdentification
server_ip := EmbeddedServerIP
server_port := EmbeddedServerPort
server_connection := "ws://" + server_ip + ":" + server_port + "/ws"
if identification == "" || server_ip == "" || server_port == "" {
log.Println("Missing configuration")
statusItem.SetTitle("Status: Config error")
return
}
// Connect to the server
var connectErr error
conn, _, connectErr = websocket.DefaultDialer.Dial(server_connection, nil)
if connectErr != nil {
log.Println("Error connecting to server:", connectErr)
statusItem.SetTitle("Status: Connection failed")
return
}
// Send identification to the server
sendMessage(conn, websocket.TextMessage, []byte(identification))
isConnected = true
statusItem.SetTitle(fmt.Sprintf("Status: Connected (%s)", identification))
log.Println("Connected to server")
// Listen for messages from the server
for {
messageType, message, err := conn.ReadMessage()
if err != nil {
log.Println("Error reading message:", err)
isConnected = false
statusItem.SetTitle("Status: Disconnected")
return
}
handleMessage(messageType, message)
}
}
func handleMessage(messageType int, message []byte) {
log.Printf("Received clipboard update: %d bytes", len(message))
// Update local clipboard tracking to avoid re-sending
lastClipboard = make([]byte, len(message))
copy(lastClipboard, message)
// Write to clipboard
clipboard.Write(clipboard.FmtText, message)
log.Println("Clipboard updated")
}
func sendMessage(conn *websocket.Conn, messageType int, message []byte) {
err := conn.WriteMessage(messageType, message)
if err != nil {
log.Println("Error sending message:", err)
}
}
func monitorClipboard() {
for {
if isConnected && conn != nil {
data := clipboard.Read(clipboard.FmtText)
// Check if clipboard has changed
if len(data) > 0 && !bytes.Equal(data, lastClipboard) {
log.Printf("Clipboard changed, sending to server: %d bytes", len(data))
sendMessage(conn, websocket.TextMessage, data)
lastClipboard = make([]byte, len(data))
copy(lastClipboard, data)
}
}
}
}
func getDefaultIcon() []byte {
return EmbeddedIcon
}
func main() {
// Initialize clipboard
clip_err := clipboard.Init()
if clip_err != nil {
log.Fatal("Failed to initialize clipboard:", clip_err)
}
// Run systray application
systray.Run(onReady, onExit)
}