This commit is contained in:
2026-07-01 12:43:09 +07:00
parent 0d1e240227
commit 44888520cb
16 changed files with 588 additions and 22 deletions

View File

@@ -25,6 +25,7 @@ import (
"time"
"client/internal/blocker"
"client/internal/camera"
"client/internal/guard"
"client/internal/screen"
"client/internal/winapi"
@@ -124,6 +125,8 @@ type App struct {
lastSyncTime time.Time
isStreamingSc bool
streamScStop chan struct{}
isStreamingCam bool
streamCamStop chan struct{}
statusMsg string
expectingLogin bool
needsClearPortalStorage bool
@@ -212,6 +215,13 @@ func (a *App) startup(ctx context.Context) {
// Request Location Access (macOS)
winapi.RequestLocationAccess()
winapi.RequestCameraAndMicAccess()
winapi.RequestScreenCaptureAccess()
// Log initial permission statuses
log.Printf("[PERMISSIONS] Camera Status: %d (0=NotDetermined, 1=Restricted, 2=Denied, 3=Authorized)", winapi.GetCameraPermission())
log.Printf("[PERMISSIONS] Microphone Status: %d (0=NotDetermined, 1=Restricted, 2=Denied, 3=Authorized)", winapi.GetMicrophonePermission())
log.Printf("[PERMISSIONS] Screen Capture Status: %d (0=NoAccess, 1=Authorized, -1=NotSupported)", winapi.GetScreenCapturePermission())
// Register blocker callbacks
blocker.Instance.OnBlocked = func(procName string, title string) {
@@ -261,7 +271,7 @@ func (a *App) tearDownBeforeQuit() {
blocker.Instance.Stop()
a.stopScreenshotStream()
runtime.EventsEmit(a.ctx, "stop_webcam_stream")
a.stopWebcamStream()
a.disconnectWS()
guard.Stop()
}
@@ -1046,6 +1056,7 @@ func (a *App) fetchAllowedApps(classId int64) {
}
a.mu.Unlock()
log.Printf("[CLIENT] Allowed apps fetched from server: %s", res.Keywords)
blocker.Instance.SetKeywords(res.Keywords)
blocker.Instance.Start()
}
@@ -1141,9 +1152,9 @@ func (a *App) connectWS() {
case "stop_screenshot_stream":
a.stopScreenshotStream()
case "start_webcam_stream":
runtime.EventsEmit(a.ctx, "start_webcam_stream")
a.startWebcamStream()
case "stop_webcam_stream":
runtime.EventsEmit(a.ctx, "stop_webcam_stream")
a.stopWebcamStream()
case "chat:message":
senderRole, _ := msg.Data["senderRole"].(string)
if senderRole == "staff" {
@@ -1244,6 +1255,69 @@ func (a *App) stopScreenshotStream() {
log.Println("[WS] Screenshot screen-streaming stopped.")
}
func (a *App) startWebcamStream() {
a.mu.Lock()
if a.isStreamingCam {
a.mu.Unlock()
return
}
a.isStreamingCam = true
a.streamCamStop = make(chan struct{})
a.mu.Unlock()
if err := camera.StartCapture(); err != nil {
log.Printf("[WS] Failed to start native camera: %v", err)
a.mu.Lock()
a.isStreamingCam = false
a.mu.Unlock()
return
}
go func() {
ticker := time.NewTicker(250 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ticker.C:
frame := camera.GetFrame()
if frame == "" {
continue
}
a.mu.Lock()
conn := a.wsConn
a.mu.Unlock()
if conn != nil {
_ = conn.WriteJSON(map[string]any{
"event": "webcam_stream_frame",
"data": map[string]any{
"imageBuffer": frame,
},
})
}
case <-a.streamCamStop:
return
}
}
}()
log.Println("[WS] Webcam native streaming started.")
}
func (a *App) stopWebcamStream() {
a.mu.Lock()
defer a.mu.Unlock()
if !a.isStreamingCam {
return
}
a.isStreamingCam = false
close(a.streamCamStop)
camera.StopCapture()
log.Println("[WS] Webcam native streaming stopped.")
}
func (a *App) alertChatIncoming(from, preview string) {
if preview == "" {
preview = "Bạn có tin nhắn mới"