# Typing Indicators Investigation

## Overview

This document outlines how to investigate and implement typing indicators for the Kosmi bridge. Typing indicators show when users are actively typing messages.

## Monitoring Approach

### Using the Auth Monitoring Script

The `cmd/monitor-auth/main.go` script already captures all WebSocket traffic. To investigate typing indicators:

```bash
# Run the monitoring script
./bin/monitor-auth -room "https://app.kosmi.io/room/@hyperspaceout"

# In the Kosmi room, start typing (but don't send)
# Watch the console output for WebSocket messages
```

### What to Look For

Typing indicators are typically implemented as:

1. **GraphQL Subscription** (receiving typing events):
   ```graphql
   subscription {
     userTyping(roomId: "...") {
       user {
         id
         displayName
       }
       isTyping
     }
   }
   ```

2. **GraphQL Mutation** (sending typing status):
   ```graphql
   mutation {
     setTyping(roomId: "...", isTyping: true)
   }
   ```

3. **WebSocket Message Format**:
   - Look for messages with type `"next"` or `"data"`
   - Payload might contain `userTyping`, `typing`, `isTyping`, or similar fields
   - Usually sent when user starts/stops typing

### Expected Message Patterns

**When user starts typing:**
```json
{
  "type": "next",
  "id": "typing-subscription",
  "payload": {
    "data": {
      "userTyping": {
        "user": {
          "id": "user-123",
          "displayName": "Alice"
        },
        "isTyping": true
      }
    }
  }
}
```

**When user stops typing:**
```json
{
  "type": "next",
  "id": "typing-subscription",
  "payload": {
    "data": {
      "userTyping": {
        "user": {
          "id": "user-123",
          "displayName": "Alice"
        },
        "isTyping": false
      }
    }
  }
}
```

## Implementation Plan

Once typing indicators are discovered:

### 1. Add Subscription to GraphQL Client

In `bridge/kosmi/graphql_ws_client.go`, add a typing subscription:

```go
func (c *GraphQLWSClient) subscribeToTyping() error {
    typingMsg := WSMessage{
        ID:   "subscribe-typing",
        Type: messageTypeSubscribe,
        Payload: map[string]interface{}{
            "query": `subscription OnUserTyping($roomId: String!) {
                userTyping(roomId: $roomId) {
                    user {
                        id
                        displayName
                        username
                    }
                    isTyping
                }
            }`,
            "variables": map[string]interface{}{
                "roomId": c.roomID,
            },
        },
    }

    return c.conn.WriteJSON(typingMsg)
}
```

### 2. Handle Typing Events

Add a callback for typing events:

```go
type TypingPayload struct {
    Data struct {
        UserTyping struct {
            User struct {
                ID          string `json:"id"`
                DisplayName string `json:"displayName"`
                Username    string `json:"username"`
            } `json:"user"`
            IsTyping bool `json:"isTyping"`
        } `json:"userTyping"`
    } `json:"data"`
}

func (c *GraphQLWSClient) OnTyping(callback func(*TypingPayload)) {
    c.typingCallback = callback
}
```

### 3. Send Typing Status

Add a method to send typing status:

```go
func (c *GraphQLWSClient) SendTyping(isTyping bool) error {
    msg := WSMessage{
        ID:   fmt.Sprintf("set-typing-%d", time.Now().Unix()),
        Type: messageTypeSubscribe,
        Payload: map[string]interface{}{
            "query": `mutation SetTyping($roomId: String!, $isTyping: Boolean!) {
                setTyping(roomId: $roomId, isTyping: $isTyping) {
                    ok
                }
            }`,
            "variables": map[string]interface{}{
                "roomId":   c.roomID,
                "isTyping": isTyping,
            },
        },
    }

    return c.conn.WriteJSON(msg)
}
```

### 4. Integrate with Matterbridge

In `bridge/kosmi/kosmi.go`, map typing events to Matterbridge:

```go
func (b *Bkosmi) handleTypingEvent(payload *TypingPayload) {
    username := payload.Data.UserTyping.User.DisplayName
    if username == "" {
        username = payload.Data.UserTyping.User.Username
    }

    rmsg := config.Message{
        Username: username,
        Channel:  "main",
        Account:  b.Account,
        Event:    config.EventUserTyping,
        Protocol: "kosmi",
    }

    if payload.Data.UserTyping.IsTyping {
        b.Remote <- rmsg
    }
}
```

### 5. Send Typing from IRC

When IRC users type, send typing indicator to Kosmi:

```go
func (b *Bkosmi) Send(msg config.Message) (string, error) {
    // Handle typing indicators
    if msg.Event == config.EventUserTyping {
        if b.client != nil {
            b.client.SendTyping(true)
            // Set a timer to send false after 5 seconds
            time.AfterFunc(5*time.Second, func() {
                b.client.SendTyping(false)
            })
        }
        return "", nil
    }
    
    // ... rest of Send implementation
}
```

## Use Cases

### 1. Show Typing in IRC

When Kosmi users type, show in IRC:
```
*** Alice is typing...
```

### 2. Show Typing in Kosmi

When IRC users type, send typing indicator to Kosmi.

### 3. Fake Typing During Image Generation

When generating room code images (which takes ~2-3 seconds), send typing indicator:

```go
func (b *Bkosmi) sendRoomCodeImage(roomCode string) error {
    // Send typing indicator
    if b.client != nil {
        b.client.SendTyping(true)
        defer b.client.SendTyping(false)
    }

    // Generate and send image
    // ...
}
```

This makes the bot appear more responsive while processing.

## Testing

1. **Manual Testing**:
   - Run monitoring script
   - Type in Kosmi (don't send)
   - Observe WebSocket traffic
   - Document the message format

2. **Integration Testing**:
   - Implement typing support
   - Test bidirectional typing indicators
   - Verify timing (typing should stop after inactivity)

3. **Edge Cases**:
   - Multiple users typing simultaneously
   - Typing indicator timeout
   - Connection loss during typing

## Status

- ✅ Monitoring script created (`cmd/monitor-auth/main.go`)
- ⏳ **TODO**: Run monitoring script and capture typing events
- ⏳ **TODO**: Document actual message format
- ⏳ **TODO**: Implement typing support (optional)

## Notes

- Typing indicators are a "nice to have" feature
- Implementation depends on Kosmi actually supporting them
- If not supported, this can be skipped
- The monitoring script is ready to capture the traffic when needed

