<commit_before>﻿/// <reference path="Scripts/jquery-1.9.0.js" />
/// <reference path="Scripts/jQuery.tmpl.js" />
/// <reference path="Scripts/jquery.cookie.js" />
/// <reference path="Chat.ui.js" />
/// <reference path="Scripts/moment.min.js" />

(function ($, connection, window, ui, utility) {
    "use strict";

    var chat = connection.chat,
        messageHistory = {},
        historyLocation = 0,
        originalTitle = document.title,
        unread = 0,
        isUnreadMessageForUser = false,
        loadingHistory = false,
        checkingStatus = false,
        typing = false,
        $ui = $(ui),
        messageSendingDelay = 1500,
        pendingMessages = {},
        privateRooms = null,
        mentionStrings = null,
        customMentionRegex = null,
        currentMessageCount = null,
        nextMessageCountUpdateAt = null,
        messagesReceivedSince = 0;

    function failPendingMessages() {
        for (var id in pendingMessages) {
            clearTimeout(pendingMessages[id]);
            ui.failMessage(id);
            delete pendingMessages[id];
        }
    }

    function isSelf(user) {
        return chat.state.name === user.Name;
    }

    function getNoteCssClass(user) {
        if (user.IsAfk === true) {
            return 'afk';
        }
        else if (user.Note) {
            return 'message';
        }
        return '';
    }

    function getNote(user) {
        if (user.IsAfk === true) {
            if (user.AfkNote) {
                return 'AFK - ' + user.AfkNote;
            }
            return 'AFK';
        }

        return user.Note;
    }

    function getFlagCssClass(user) {
        return (user.Flag) ? 'flag flag-' + user.Flag : '';
    }

    function performLogout() {
        var d = $.Deferred();
        $.post('account/logout', {}).done(function () {
            d.resolveWith(null);
            document.location = document.location.pathname;
        });

        return d.promise();
    }

    function logout() {
        performLogout().done(function () {
            chat.server.send('/logout', chat.state.activeRoom)
                .fail(function (e) {
                    ui.addMessage(e, 'error', chat.state.activeRoom);
                });
        });
    }

    function populateRoom(room) {
        var d = $.Deferred();

        connection.hub.log('getRoomInfo(' + room + ')');

        // Populate the list of users rooms and messages 
        chat.server.getRoomInfo(room)
                .done(function (roomInfo) {
                    connection.hub.log('getRoomInfo.done(' + room + ')');

                    $.each(roomInfo.Users, function () {
                        var userViewModel = getUserViewModel(this);
                        ui.addUser(userViewModel, room);
                        ui.setUserActivity(userViewModel);
                    });

                    $.each(roomInfo.Owners, function () {
                        ui.setRoomOwner(this, room);
                    });

                    var messageIds = [];
                    $.each(roomInfo.RecentMessages, function () {
                        var viewModel = getMessageViewModel(this);

                        messageIds.push(viewModel.id);
                        ui.addChatMessage(viewModel, room);
                    });

                    ui.changeRoomTopic(roomInfo);

                    // mark room as initialized to differentiate messages
                    // that are added after initial population
                    ui.setInitialized(room);
                    ui.scrollToBottom(room);
                    ui.setRoomListStatuses(room);

                    d.resolveWith(chat);

                    // Watch the messages after the defer, since room messages
                    // may be appended if we are just joining the room
                    ui.watchMessageScroll(messageIds, room);
                })
                .fail(function (e) {
                    connection.hub.log('getRoomInfo.failed(' + room + ', ' + e + ')');
                    d.rejectWith(chat);
                });

        return d.promise();
    }

    function populateLobbyRooms() {
        try {
            // Populate the user list with room names
            chat.server.getRooms()
                .done(function (rooms) {
                    ui.populateLobbyRooms(rooms, privateRooms);
                    ui.setInitialized('Lobby');
                });
        }
        catch (e) {
            connection.hub.log('getRooms failed');
        }
    }

    function scrollIfNecessary(callback, room) {
        var nearEnd = ui.isNearTheEnd(room);

        callback();

        if (nearEnd) {
            ui.scrollToBottom(room);
        }
    }

    function getUserViewModel(user, isOwner) {
        var lastActive = user.LastActivity.fromJsonDate();
        return {
            name: user.Name,
            hash: user.Hash,
            owner: isOwner,
            active: user.Active,
            noteClass: getNoteCssClass(user),
            note: getNote(user),
            flagClass: getFlagCssClass(user),
            flag: user.Flag,
            country: user.Country,
            lastActive: lastActive,
            timeAgo: $.timeago(lastActive),
            admin: user.IsAdmin,
            mention: user.Mention
        };
    }

    function getMessageViewModel(message) {
        var reUsername = new RegExp("\\b@?" + chat.state.name.replace(/\./, '\\.') + "\\b", "i");
        var reCustom = new RegExp(customMentionRegex, "i");

        return {
            name: message.User.Name,
            hash: message.User.Hash,
            mention: message.User.Mention,
            message: message.HtmlEncoded ? message.Content : ui.processContent(message.Content),
            htmlContent: message.HtmlContent,
            id: message.Id,
            date: message.When.fromJsonDate(),
            highlight: (reUsername.test(message.Content) || reCustom.test(message.Content)) ? 'highlight' : '',
            isOwn: reUsername.test(message.User.name),
            isMine: message.User.Name === chat.state.name,
            imageUrl: message.ImageUrl,
            source: message.Source,
            messageType: message.MessageType
        };
    }

    // Save some state in a cookie
    function updateCookie() {
        var state = {
            activeRoom: chat.state.activeRoom,
            preferences: ui.getState()
        },
        jsonState = window.JSON.stringify(state);

        $.cookie('jabbr.state', jsonState, { path: '/', expires: 30 });
    }

    function updateTitle() {
        // ugly hack via http://stackoverflow.com/a/2952386/188039
        setTimeout(function () {
            if (unread === 0) {
                document.title = originalTitle;
            } else {
                document.title = (isUnreadMessageForUser ? '*' : '') + '(' + unread + ') ' + originalTitle;
            }
        }, 200);
    }

    function clearUnread() {
        isUnreadMessageForUser = false;
        unread = 0;
        updateUnread(chat.state.activeRoom, false);
    }
    
    function incrementMessageCount() {
        updateMessageCount(1);
    }
    
    function updateMessageCount(delta) {
        delta = typeof delta !== 'undefined' ? delta : 0;

        if (currentMessageCount == null || messagesReceivedSince > nextMessageCountUpdateAt) {
            chat.server.getMessageCount()
                .done(function(count) {
                    currentMessageCount = count;
                    messagesReceivedSince = delta;
                    nextMessageCountUpdateAt = Math.floor((Math.random() * 300) + 100);
                    console.log(nextMessageCountUpdateAt);
                    ui.setMessageCount(currentMessageCount + messagesReceivedSince);
                });
        } else {
            messagesReceivedSince += delta;
            ui.setMessageCount(currentMessageCount + messagesReceivedSince);
        }
    }

    function updateUnread(room, isMentioned) {
        if (ui.hasFocus() === false) {
            isUnreadMessageForUser = (isUnreadMessageForUser || isMentioned);

            unread = unread + 1;
        } else {
            //we're currently focused so remove
            //the * notification
            isUnreadMessageForUser = false;
        }<commit_msg>jshint fix<commit_after>﻿/// <reference path="Scripts/jquery-1.9.0.js" />
/// <reference path="Scripts/jQuery.tmpl.js" />
/// <reference path="Scripts/jquery.cookie.js" />
/// <reference path="Chat.ui.js" />
/// <reference path="Scripts/moment.min.js" />

(function ($, connection, window, ui, utility) {
    "use strict";

    var chat = connection.chat,
        messageHistory = {},
        historyLocation = 0,
        originalTitle = document.title,
        unread = 0,
        isUnreadMessageForUser = false,
        loadingHistory = false,
        checkingStatus = false,
        typing = false,
        $ui = $(ui),
        messageSendingDelay = 1500,
        pendingMessages = {},
        privateRooms = null,
        mentionStrings = null,
        customMentionRegex = null,
        currentMessageCount = null,
        nextMessageCountUpdateAt = null,
        messagesReceivedSince = 0;

    function failPendingMessages() {
        for (var id in pendingMessages) {
            clearTimeout(pendingMessages[id]);
            ui.failMessage(id);
            delete pendingMessages[id];
        }
    }

    function isSelf(user) {
        return chat.state.name === user.Name;
    }

    function getNoteCssClass(user) {
        if (user.IsAfk === true) {
            return 'afk';
        }
        else if (user.Note) {
            return 'message';
        }
        return '';
    }

    function getNote(user) {
        if (user.IsAfk === true) {
            if (user.AfkNote) {
                return 'AFK - ' + user.AfkNote;
            }
            return 'AFK';
        }

        return user.Note;
    }

    function getFlagCssClass(user) {
        return (user.Flag) ? 'flag flag-' + user.Flag : '';
    }

    function performLogout() {
        var d = $.Deferred();
        $.post('account/logout', {}).done(function () {
            d.resolveWith(null);
            document.location = document.location.pathname;
        });

        return d.promise();
    }

    function logout() {
        performLogout().done(function () {
            chat.server.send('/logout', chat.state.activeRoom)
                .fail(function (e) {
                    ui.addMessage(e, 'error', chat.state.activeRoom);
                });
        });
    }

    function populateRoom(room) {
        var d = $.Deferred();

        connection.hub.log('getRoomInfo(' + room + ')');

        // Populate the list of users rooms and messages 
        chat.server.getRoomInfo(room)
                .done(function (roomInfo) {
                    connection.hub.log('getRoomInfo.done(' + room + ')');

                    $.each(roomInfo.Users, function () {
                        var userViewModel = getUserViewModel(this);
                        ui.addUser(userViewModel, room);
                        ui.setUserActivity(userViewModel);
                    });

                    $.each(roomInfo.Owners, function () {
                        ui.setRoomOwner(this, room);
                    });

                    var messageIds = [];
                    $.each(roomInfo.RecentMessages, function () {
                        var viewModel = getMessageViewModel(this);

                        messageIds.push(viewModel.id);
                        ui.addChatMessage(viewModel, room);
                    });

                    ui.changeRoomTopic(roomInfo);

                    // mark room as initialized to differentiate messages
                    // that are added after initial population
                    ui.setInitialized(room);
                    ui.scrollToBottom(room);
                    ui.setRoomListStatuses(room);

                    d.resolveWith(chat);

                    // Watch the messages after the defer, since room messages
                    // may be appended if we are just joining the room
                    ui.watchMessageScroll(messageIds, room);
                })
                .fail(function (e) {
                    connection.hub.log('getRoomInfo.failed(' + room + ', ' + e + ')');
                    d.rejectWith(chat);
                });

        return d.promise();
    }

    function populateLobbyRooms() {
        try {
            // Populate the user list with room names
            chat.server.getRooms()
                .done(function (rooms) {
                    ui.populateLobbyRooms(rooms, privateRooms);
                    ui.setInitialized('Lobby');
                });
        }
        catch (e) {
            connection.hub.log('getRooms failed');
        }
    }

    function scrollIfNecessary(callback, room) {
        var nearEnd = ui.isNearTheEnd(room);

        callback();

        if (nearEnd) {
            ui.scrollToBottom(room);
        }
    }

    function getUserViewModel(user, isOwner) {
        var lastActive = user.LastActivity.fromJsonDate();
        return {
            name: user.Name,
            hash: user.Hash,
            owner: isOwner,
            active: user.Active,
            noteClass: getNoteCssClass(user),
            note: getNote(user),
            flagClass: getFlagCssClass(user),
            flag: user.Flag,
            country: user.Country,
            lastActive: lastActive,
            timeAgo: $.timeago(lastActive),
            admin: user.IsAdmin,
            mention: user.Mention
        };
    }

    function getMessageViewModel(message) {
        var reUsername = new RegExp("\\b@?" + chat.state.name.replace(/\./, '\\.') + "\\b", "i");
        var reCustom = new RegExp(customMentionRegex, "i");

        return {
            name: message.User.Name,
            hash: message.User.Hash,
            mention: message.User.Mention,
            message: message.HtmlEncoded ? message.Content : ui.processContent(message.Content),
            htmlContent: message.HtmlContent,
            id: message.Id,
            date: message.When.fromJsonDate(),
            highlight: (reUsername.test(message.Content) || reCustom.test(message.Content)) ? 'highlight' : '',
            isOwn: reUsername.test(message.User.name),
            isMine: message.User.Name === chat.state.name,
            imageUrl: message.ImageUrl,
            source: message.Source,
            messageType: message.MessageType
        };
    }

    // Save some state in a cookie
    function updateCookie() {
        var state = {
            activeRoom: chat.state.activeRoom,
            preferences: ui.getState()
        },
        jsonState = window.JSON.stringify(state);

        $.cookie('jabbr.state', jsonState, { path: '/', expires: 30 });
    }

    function updateTitle() {
        // ugly hack via http://stackoverflow.com/a/2952386/188039
        setTimeout(function () {
            if (unread === 0) {
                document.title = originalTitle;
            } else {
                document.title = (isUnreadMessageForUser ? '*' : '') + '(' + unread + ') ' + originalTitle;
            }
        }, 200);
    }

    function clearUnread() {
        isUnreadMessageForUser = false;
        unread = 0;
        updateUnread(chat.state.activeRoom, false);
    }
    
    function incrementMessageCount() {
        updateMessageCount(1);
    }
    
    function updateMessageCount(delta) {
        delta = typeof delta !== 'undefined' ? delta : 0;

        if (currentMessageCount === null || messagesReceivedSince > nextMessageCountUpdateAt) {
            chat.server.getMessageCount()
                .done(function(count) {
                    currentMessageCount = count;
                    messagesReceivedSince = delta;
                    nextMessageCountUpdateAt = Math.floor((Math.random() * 300) + 100);
                    console.log(nextMessageCountUpdateAt);
                    ui.setMessageCount(currentMessageCount + messagesReceivedSince);
                });
        } else {
            messagesReceivedSince += delta;
            ui.setMessageCount(currentMessageCount + messagesReceivedSince);
        }
    }

    function updateUnread(room, isMentioned) {
        if (ui.hasFocus() === false) {
            isUnreadMessageForUser = (isUnreadMessageForUser || isMentioned);

            unread = unread + 1;
        } else {
            //we're currently focused so remove
            //the * notification
            isUnreadMessageForUser = false;
        }
{'fraction_non_alphanumeric': 0.11562049062049062, 'fraction_numerical': 0.00468975468975469, 'mean_word_length': 1.5747678018575852, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, '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': '3544718', 'n_tokens_mistral': 4526, 'n_tokens_neox': 4270, 'n_words': 853}