Size: 2.8 KB Modified: 27/06/2026 2:54 AM
using System.Text.Json.Serialization;

namespace KaiChat.Mobile;

public sealed class ConversationSummary
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = "";

    [JsonPropertyName("title")]
    public string Title { get; set; } = "Chat";

    [JsonPropertyName("createdAt")]
    public DateTime CreatedAt { get; set; }

    [JsonPropertyName("updatedAt")]
    public DateTime UpdatedAt { get; set; }

    [JsonPropertyName("messageCount")]
    public int MessageCount { get; set; }
}

public sealed class Conversation
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = "";

    [JsonPropertyName("title")]
    public string Title { get; set; } = "Chat";

    [JsonPropertyName("messages")]
    public List<ChatMessageDto> Messages { get; set; } = new();
}

public sealed class ChatMessageDto
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = "";

    [JsonPropertyName("role")]
    public string Role { get; set; } = "";

    [JsonPropertyName("content")]
    public string Content { get; set; } = "";

    [JsonPropertyName("thinking")]
    public string? Thinking { get; set; }

    [JsonPropertyName("timestamp")]
    public DateTime Timestamp { get; set; }
}

public sealed class OutboxMessage
{
    public string ClientId { get; set; } = Guid.NewGuid().ToString("N");
    public string ConversationId { get; set; } = "";
    public string Text { get; set; } = "";
    public string? Title { get; set; }
    public string MessageId { get; set; } = Guid.NewGuid().ToString("N")[..8];
    public string? TruncateBeforeMessageId { get; set; }
    public DateTime QueuedAt { get; set; } = DateTime.UtcNow;
}

public sealed class ChatItem : BindableObject
{
    private string _text = "";
    private bool _isClosed;

    public string Id { get; init; } = Guid.NewGuid().ToString("N")[..8];
    public string Role { get; init; } = "";

    public string Text
    {
        get => _text;
        set
        {
            _text = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(DisplayText));
        }
    }

    public bool IsClosed
    {
        get => _isClosed;
        set
        {
            _isClosed = value;
            OnPropertyChanged();
        }
    }

    public bool IsUser => Role == "user";
    public bool IsAssistant => Role == "assistant";
    public string DisplayText => Text;
    public Color BubbleColor => IsUser ? Color.FromArgb("#58a6ff") : Color.FromArgb("#1c2333");
    public Color TextColor => Color.FromArgb("#e6edf3");
    public LayoutOptions BubbleAlignment => IsUser ? LayoutOptions.End : LayoutOptions.Start;
}

public sealed class ConversationListItem
{
    public string Id { get; init; } = "";
    public string Title { get; init; } = "Chat";
    public string Subtitle { get; init; } = "";
}
Offline