<commit_before>// Copyright (c) Wireclub Media Inc. All Rights Reserved. See License.md in the project root for license information.

namespace Wireclub.iOS

open System
open System.Text.RegularExpressions
open System.Linq
open System.Drawing
open System.Globalization
open System.Web

open MonoTouch.Foundation
open MonoTouch.UIKit

open Wireclub.Models
open Wireclub.Boundary
open Wireclub.Boundary.Chat
open Wireclub.Boundary.Models

open Newtonsoft.Json

open ChannelEvent


[<RequireQualifiedAccess>]
type ChatSession =
| User of Entity
| ChatRoom of Entity

type RootViewContoller () =
    inherit UIViewController ()

    abstract member Tabs: UITabBar with get
    default this.Tabs with get () = null

    abstract member SetOnlineStatus: OnlineStateType -> unit 
    default this.SetOnlineStatus(online:OnlineStateType) = ()

[<Register("ChatsViewController")>]
type ChatsViewController (rootController:RootViewContoller) as controller =
    inherit UIViewController ()
         
    let mutable (chats:DB.ChatHistory[]) = [| |]

    let readColor = new UIColor(0.3f, 0.3f, 0.3f, 1.0f)
    let unreadColor = new UIColor(0.0f, 0.0f, 0.0f, 1.0f)
    let mutable loaded = false

    let tableSource = { 
        new UITableViewSource() with
        override this.GetCell(tableView, indexPath) =
            match chats with
            | [||] when loaded -> 
                let cell = 
                    match tableView.DequeueReusableCell "no-chat-cell" with
                    | null -> new UITableViewCell (UITableViewCellStyle.Subtitle, "no-chat-cell")
                    | c -> c

                let label = new UILabel(tableView.Frame)
                label.TextAlignment <- UITextAlignment.Center
                label.Text <- "No chats yet."
                cell.ContentView.AddSubview(label)
                cell.SelectionStyle <- UITableViewCellSelectionStyle.None
                cell
            | _ -> 
                let chat = chats.[indexPath.Row]
                let cell = 
                    match tableView.DequeueReusableCell "chat-cell" with
                    | null -> new UITableViewCell (UITableViewCellStyle.Subtitle, "chat-cell")
                    | c -> c
                
                cell.Tag <- indexPath.Row
                match chat.Type with
                | DB.ChatHistoryType.PrivateChat
                | DB.ChatHistoryType.ChatRoom
                | _ ->
                    let color = if chat.Read then readColor else unreadColor
                    cell.TextLabel.Text <- chat.Label
                    cell.TextLabel.TextColor <- color
                    cell.DetailTextLabel.Text <- chat.Last
                    cell.DetailTextLabel.TextColor <- color
                    Image.loadImageForCell (App.imageUrl chat.Image 100) Image.placeholder cell tableView
                
                cell

        override this.RowsInSection(tableView, section) =
            match chats with
            | [||] when loaded -> 1
            | _ -> chats.Length

        override this.GetHeightForRow(tableView, index) =
            match chats with
            | [||] when loaded -> controller.Table.Frame.Height
            | _ -> tableView.RowHeight
    
        override this.RowSelected(tableView, indexPath) =
            match chats with
            | [||] when loaded -> ()
            | _ -> 
                tableView.DeselectRow (indexPath, false)
                let session = chats.[indexPath.Row]
                let entity = {
                    Id = session.EntityId
                    Slug = session.Slug
                    Label = session.Label
                    Image = session.Image
                }
                match session.Type with
                | DB.ChatHistoryType.PrivateChat ->
                    let newController = ChatSessions.start entity
                    controller.NavigationController.PushViewController(newController, true)
                | DB.ChatHistoryType.ChatRoom
                | _ ->
                    let newController = ChatRooms.join entity
                    controller.NavigationController.PushViewController(newController, true)

                
                Async.startWithContinuation 
                    (async {
                        do! DB.updateChatHistoryReadById entity.Id
                        let! unread = DB.fetchChatHistoryUnreadCount ()
                        return unread
                    })
                    (function
                        | 0 -> rootController.Tabs.Items.[0].BadgeValue <- null
                        | unread -> rootController.Tabs.Items.[0].BadgeValue <- string unread
                    )

    }

    [<Outlet>]
    member val Table: UITableView = null with get, set

    member this.Reload () =
        Async.startWithContinuation
            (DB.fetchChatHistory ())
            (fun sessions ->
                chats <- Seq.toArray sessions
                loaded <- true
                this.Table.ReloadData()
            )

    override controller.ViewDidLoad () =
        base.ViewDidLoad ()
        controller.Table.Source <- tableSource

    override this.ViewDidAppear (animated) =
        base.ViewDidAppear (animated)
        this.Reload()


[<Register ("ChatDirectoryViewController")>]
type ChatDirectoryViewController(rootController:RootViewContoller) as controller =
    inherit UIViewController ()

    let mutable directory:ChatDirectoryViewModel option = None
    let rooms () = <commit_msg>Allow deleting of recents chats from the directory<commit_after>// Copyright (c) Wireclub Media Inc. All Rights Reserved. See License.md in the project root for license information.

namespace Wireclub.iOS

open System
open System.Text.RegularExpressions
open System.Linq
open System.Drawing
open System.Globalization
open System.Web

open MonoTouch.Foundation
open MonoTouch.UIKit

open Wireclub.Models
open Wireclub.Boundary
open Wireclub.Boundary.Chat
open Wireclub.Boundary.Models

open Newtonsoft.Json

open ChannelEvent


[<RequireQualifiedAccess>]
type ChatSession =
| User of Entity
| ChatRoom of Entity

type RootViewContoller () =
    inherit UIViewController ()

    abstract member Tabs: UITabBar with get
    default this.Tabs with get () = null

    abstract member SetOnlineStatus: OnlineStateType -> unit 
    default this.SetOnlineStatus(online:OnlineStateType) = ()

[<Register("ChatsViewController")>]
type ChatsViewController (rootController:RootViewContoller) as controller =
    inherit UIViewController ()
         
    let mutable (chats:DB.ChatHistory[]) = [| |]

    let readColor = new UIColor(0.3f, 0.3f, 0.3f, 1.0f)
    let unreadColor = new UIColor(0.0f, 0.0f, 0.0f, 1.0f)
    let mutable loaded = false

    let tableSource = { 
        new UITableViewSource() with
        override this.GetCell(tableView, indexPath) =
            match chats with
            | [||] when loaded -> 
                let cell = 
                    match tableView.DequeueReusableCell "no-chat-cell" with
                    | null -> new UITableViewCell (UITableViewCellStyle.Subtitle, "no-chat-cell")
                    | c -> c

                let label = new UILabel(tableView.Frame)
                label.TextAlignment <- UITextAlignment.Center
                label.Text <- "No chats yet."
                cell.ContentView.AddSubview(label)
                cell.SelectionStyle <- UITableViewCellSelectionStyle.None
                cell
            | _ -> 
                let chat = chats.[indexPath.Row]
                let cell = 
                    match tableView.DequeueReusableCell "chat-cell" with
                    | null -> new UITableViewCell (UITableViewCellStyle.Subtitle, "chat-cell")
                    | c -> c
                
                cell.Tag <- indexPath.Row
                match chat.Type with
                | DB.ChatHistoryType.PrivateChat
                | DB.ChatHistoryType.ChatRoom
                | _ ->
                    let color = if chat.Read then readColor else unreadColor
                    cell.TextLabel.Text <- chat.Label
                    cell.TextLabel.TextColor <- color
                    cell.DetailTextLabel.Text <- chat.Last
                    cell.DetailTextLabel.TextColor <- color
                    Image.loadImageForCell (App.imageUrl chat.Image 100) Image.placeholder cell tableView
                
                cell

        override this.RowsInSection(tableView, section) =
            match chats with
            | [||] when loaded -> 1
            | _ -> chats.Length

        override this.GetHeightForRow(tableView, index) =
            match chats with
            | [||] when loaded -> controller.Table.Frame.Height
            | _ -> tableView.RowHeight
    
        override this.CanEditRow (tableView, index) = true

        override this.TitleForDeleteConfirmation (tableView, index) = "Leave"

        override this.CommitEditingStyle (tableView, style, index) = 
            let session = chats.[index.Row]
            let removeRow _ =
                Async.startWithContinuation
                    (DB.fetchChatHistory ())
                    (fun sessions ->
                        chats <- Seq.toArray sessions
                        if chats.Count() > 0 then
                            tableView.DeleteRows([| index |], UITableViewRowAnimation.Automatic)
                        else
                            tableView.ReloadData()
                    )

            match session.Type with
            | DB.ChatHistoryType.ChatRoom ->
                Async.startNetworkWithContinuation
                    (Chat.leave session.Slug)
                    (function 
                        | Api.ApiOk _ ->
                            Async.startWithContinuation
                                (DB.removeChatHistoryById session.EntityId)
                                (removeRow)
                        | error -> controller.HandleApiFailure error 
                    )
            | DB.ChatHistoryType.PrivateChat
            | _ -> 
                Async.startWithContinuation
                    (DB.removeChatHistoryById session.EntityId)
                    (removeRow)


        override this.RowSelected(tableView, indexPath) =
            match chats with
            | [||] when loaded -> ()
            | _ -> 
                tableView.DeselectRow (indexPath, false)
                let session = chats.[indexPath.Row]
                let entity = {
                    Id = session.EntityId
                    Slug = session.Slug
                    Label = session.Label
                    Image = session.Image
                }
                match session.Type with
                | DB.ChatHistoryType.PrivateChat ->
                    let newController = ChatSessions.start entity
                    controller.NavigationController.PushViewController(newController, true)
                | DB.ChatHistoryType.ChatRoom
                | _ ->
                    let newController = ChatRooms.join entity
                    controller.NavigationController.PushViewController(newController, true)

                
                Async.startWithContinuation 
                    (async {
                        do! DB.updateChatHistoryReadById entity.Id
                        let! unread = DB.fetchChatHistoryUnreadCount ()
                        return unread
                    })
                    (function
                        | 0 -> rootController.Tabs.Items.[0].BadgeValue <- null
                        | unread -> rootController.Tabs.Items.[0].BadgeValue <- string unread
                    )

    }

    [<Outlet>]
    member val Table: UITableView = null with get, set

    member this.Reload () =
        Async.startWithContinuation
            (DB.fetchChatHistory ())
            (fun sessions ->
                chats <- Seq.toArray sessions
                loaded <- true
                this.Table.ReloadData()
            )

    override controller.ViewDidLoad () =
        base.ViewDidLoad ()
        controller.Table.Source <- tableSource
        controller.Table.AllowsMultipleSelectionDuringEditing <- false

    override this.ViewDidAppear (animated) =
        base.ViewDidAppear (animated)
        this.Reload()


[<Register ("ChatDirectoryViewController")>]
type ChatDirectoryViewController(rootController:RootViewContoller) as controller =
    inherit UIViewController ()

    let mutable directory:ChatDirectoryViewModel option = None
    let rooms () = 
{'fraction_non_alphanumeric': 0.07640772052959005, 'fraction_numerical': 0.003748604243100973, 'mean_word_length': 1.5758011503697618, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1649265', 'n_tokens_mistral': 3273, 'n_tokens_neox': 2964, 'n_words': 708}