// ==UserScript==

// @name        NamuRefresher

// @auther      LeKAKiD

// @version     1.2.2

// @exclude     https://arca.live/b/*/write

// @include     https://arca.live/b/*

// @run-at      document-start

// @require     https://code.jquery.com/jquery-3.5.1.min.js

// @grant       GM_addStyle

// @grant       GM_getValue

// @grant       GM_setValue

// ==/UserScript==

GM_addStyle (`

    @keyframes highlight{

        0% {

            background-color: rgba(240, 248, 255, 1);

            opacity:1

        }

        100% {

            background-color: rgba(240, 248, 255, 0);

            opacity:1

        }


    }


    @keyframes loaderspin {

        0% { transform: rotate(0deg);

            box-shadow: 0 0 15px #3d414d;

        }

        5% {

            box-shadow: 0 0 -10px #3d414d;

        }

        15%{

            box-shadow: 0 0 0px #3d414d;

        }

        100% { transform: rotate(360deg);

            box-shadow: 0 0 0px #3d414d;

        }

    }

    #article_loader {

        border: 6px solid #d3d3d3;

        border-top: 6px solid #3d414d;

        border-radius: 50%;

        position: fixed;

        top: 5px;

        left: 10px;

        width: 40px;

        height: 40px;

        z-index: 14 !important;

    }


    #article_loader.fixed {

        top:50px;

    }

    #time_display {

        position: fixed;

        top: 45px;

        left: 10px;

        width: 40px;

        text-align: center;

        opacity: 0;

    }

    #time_display.fixed {

        top: 90px;

    }

    .preview-hide {

        display:none;

    }

`);


var loader_loop = null;

var list = null;

var board = null;


function initLoader() {

    removeLoader();

    $('.root-container').append('<div id="article_loader"></div>');


    var loader = $('#article_loader');


    if ($(window).scrollTop() < 50) {

        loader.addClass('fixed');

    } else {

        loader.removeClass('fixed');

    }


    $(window).on('scroll', function () {

        if ($(window).scrollTop() < 50) {

            loader.addClass('fixed');

        } else {

            loader.removeClass('fixed');

        }

    });


    setLoader();

}


function setLoader() {

    var loader = $('#article_loader');


    if (loader) {

        loader.removeAttr('style');

        setTimeout(function() {

            loader.css('animation', 'loaderspin ' + Setting.refreshTime + 's ease-in-out');

        }, 50);

    }

}


function removeLoader() {

    $('#article_loader').remove();

}


var current_request = null;

function tryRefreshArticle() {

    if(current_request !== null) {

        current_request.abort();

        initLoader();

    }


    current_request = $.ajax({

        type: "GET",

        url: window.location.href,

        timeout: 2000,

        dataType: "html",

        success: (data) => {

            current_request = null;

            setLoader();

            refreshArticle(data);

        },

        error: () => {

            current_request = null;

            console.log("AJAX Request Failed");

        }

    });

}


var comment_requeset = null;

function tryRefreshComment() {

    if(comment_requeset !== null) {

        comment_requeset.abort();

    }


    comment_requeset = $.ajax({

        type: "GET",

        url: window.location.href,

        timeout: 2000,

        dataType: "html",

        success: (data) => {

            comment_requeset = null;

            refreshComment(data);

        },

        error: () => {

            comment_requeset = null;

            console.log("AJAX Request Failed");

        }

    });

}


function getDaystamp(datetime) {

    var date;

    if(datetime)

        date = new Date(datetime);

    else

        date = new Date();


    var year = date.getFullYear();

    var month = date.getMonth() + 1;

    var day = date.getDate();


    if (("" + month).length == 1) {

        month = "0" + month;

    }

    if (("" + day).length == 1) {

        day = "0" + day;

    }


    return `${year}.${month}.${day}`;

}


function getTimestamp(datetime) {

    var date = new Date(datetime);

    date.set

    var hh = date.getHours();

    var mm = date.getMinutes();


    if (("" + hh).length == 1) {

        hh = "0" + hh;

    }

    if (("" + mm).length == 1) {

        mm = "0" + mm;

    }


    return `${hh}:${mm}`;

}


function isToday(datetime) {

    var today = getDaystamp();

    var target = getDaystamp(datetime);


    if(today == target)

        return true;


    return false;

}


function refreshArticle(data) {

    var newlist = $(data).find('.list-table').find('a.vrow').not('.notice');

    newlist.find('.vrow-preview > noscript').each(function(index, item) {

        $(item).parent().html($(item).text());

    });

    if(newlist.length == 0)

        return;


    var list_length = list.find('a.vrow').not('.notice').length;

    var latest_num = list.find('a.vrow').not('.notice').first().find('span.col-id > span').text();


    for(var i = 0; i < list_length; i++) {

        if(newlist.eq(i).find('span.col-id > span').text() > latest_num) {

            newlist.eq(i).addClass('new');

        }

    }


    list.find('a.vrow').not('.notice').remove();

    list.append(newlist);


    list.find('a.new').css('animation', 'highlight ease-in-out 0.5s');

    list.find('a.new').removeClass('new');


    list.children().each(function(index, item) {

        var datetime = $(item).find('time').attr('datetime');


        if(isToday(datetime))

            $(item).find('time').text(getTimestamp(datetime));

    });


    applyPreview();

}


function refreshComment(data) {

    $('.article-comment > .list-area').remove();

    $('.article-comment > .title').after($(data).find('.article-comment > .list-area'));


    if(Setting.hideAvatar)

        hideAvatar();

}


function initRefresher() {

    if(loader_loop !== null) {

        stopRefresher();

    }

    initLoader();

    loader_loop = setInterval(tryRefreshArticle, Setting.refreshTime * 1000);


    document.addEventListener("visibilitychange", () => {

        if (document.hidden) {

            stopRefresher();

        } else {

            if (loader_loop === null && Setting.useRefresh) {

                $(document).ready(function() {

                    initLoader();

                    loader_loop = setInterval(tryRefreshArticle, Setting.refreshTime * 1000);

                });

            }

        }

    });

}


function stopRefresher() {

    clearInterval(loader_loop);

    loader_loop = null;

    removeLoader();

}


function hideNotice() {

    list.find('.notice').css('display', 'none');

}


function showNotice() {

    list.find('.notice').removeAttr('style');

}


function hideAvatar() {

    $('.avatar').css('display', 'none');

    $('.input-wrapper > .input').css('width', 'calc(100% - 4.5rem - .5rem)');

}


function showAvatar() {

    $('.avatar').removeAttr('style');

    $('.input-wrapper > .input').removeAttr('style');

}


function applyPreview() {

    list.children().each(function(index, item) {

        var tag = $(item).find('span.tag').text();

        tag = (tag == "") ? "일반" : tag;


        if(Setting.usePreviewFilter && (Setting.filteredCategory['전체'] || Setting.filteredCategory[tag])) {

            $(item).find('.vrow-preview').css('display', 'none');

        }

        else {

            $(item).find('.vrow-preview').removeAttr('style');

        }

    });

}


function applyReplyRefresh() {

    var btn = '<a class="btn btn-success" href="#"><span class="icon ion-android-refresh"></span> 새로고침</a>';


    $(btn).insertAfter('.article-comment .title a').click(function() {

        tryRefreshComment();

        return false;

    });

}


var DefaultSetting = {

    useRefresh: true,

    refreshTime: 5,

    hideNotice: false,

    hideAvatar: true,

    usePreviewFilter: false,

    filteredCategory: {}

}

var Setting = {};


function resetSetting() {

    Setting = JSON.parse(JSON.stringify(DefaultSetting));

    saveSetting();

    loadSetting();

}


function loadSetting() {

    Setting.useRefresh = GM_getValue('Setting.useRefresh', DefaultSetting.useRefresh);

    Setting.refreshTime = GM_getValue('Setting.refreshTime', DefaultSetting.refreshTime);

    Setting.hideNotice = GM_getValue('Setting.hideNotice', DefaultSetting.hideNotice);

    Setting.hideAvatar = GM_getValue('Setting.hideAvatar', DefaultSetting.hideAvatar);

    Setting.usePreviewFilter = GM_getValue('Setting.usePreviewFilter', DefaultSetting.usePreviewFilter);

    Setting.filteredCategory = JSON.parse(GM_getValue('Setting.filteredCategory.' + board, JSON.stringify(DefaultSetting.filteredCategory)));


    $('.refresher-setting-userefresh').text(Setting.useRefresh ? '게시물 자동 새로고침 사용' : '게시물 자동 새로고침 안함');

    $('.refresher-setting-refreshtime').text('새로고침 시간 간격: ' + Setting.refreshTime + '초');

    $('.refresher-setting-hidenotice').text(Setting.hideNotice ? '채널 공지 숨기기' : '채널 공지 보이기');

    $('.refresher-setting-hideavatar').text(Setting.hideAvatar ? '프로필 아바타 숨기기' : '프로필 아바타 보이기');

    $('.refresher-setting-usepreviewfilter').text(Setting.usePreviewFilter ? '미리보기 필터 사용 중...' : '미리보기 필터 사용 안함');


    if(!Setting.usePreviewFilter) {

        $('.refresher-previewfilter').hide();

    }


    $('a[category]').each(function(index, item) {

        var category = $(item).attr('category');

        var value = Setting.filteredCategory[category];

        if(value === undefined)

            Setting.filteredCategory[category] = false;


        if(value) {

            $(item).text($(item).attr('category') + ": 숨기기");

        }

        else {

            $(item).text($(item).attr('category') + ": 보이기");

        }

    });

}


function saveSetting() {

    GM_setValue('Setting.useRefresh', Setting.useRefresh);

    GM_setValue('Setting.refreshTime', Setting.refreshTime);

    GM_setValue('Setting.hideNotice', Setting.hideNotice);

    GM_setValue('Setting.hideAvatar', Setting.hideAvatar);

    GM_setValue('Setting.usePreviewFilter', Setting.usePreviewFilter);

    GM_setValue('Setting.filteredCategory.' + board, JSON.stringify(Setting.filteredCategory));

}


function initSettingView() {

    $('.refresher-setting').remove();


    var nav = $('ul.navbar-nav').first();

    var menubtn = `<li class="nav-item dropdown">

                    <a aria-expanded="false" class="nav-link dropdown-toggle" href="#" title="Refresher 설정" data-toggle="dropdown" aria-haspopup="true">

                    <span class="hidden-sm-down">Refresher 설정</span>

                    <span class="hidden-md-up">Refresher 설정</span>

                    </a>

                </li>`;

    var menulist = `<div class="dropdown-menu left">

                    <div class="dropdown-item refresher-setting-reset">설정 초기화</div>

                    <div class="dropdown-divider"></div>

                    <div class="dropdown-item refresher-setting-userefresh">새로고침 기능</div>

                    <div class="dropdown-item refresher-setting-refreshtime">시간 간격란</div>

                    <div class="dropdown-divider"></div>

                    <div class="dropdown-item refresher-setting-hidenotice">공지사항 숨기기 여부</div>

                    <div class="dropdown-item refresher-setting-hideavatar">프로필 아바타 숨기기 여부</div>

                    <div class="dropdown-divider"></div>

                    <div class="dropdown-item refresher-setting-usepreviewfilter">미리보기 필터 기능</div>

                    <div class="refresher-previewfilter"></div>

                </div>`;


    $(menubtn).appendTo(nav).append(menulist);


    var category = $('.board-category a');

    $('.refresher-previewfilter').append('<a class="dropdown-item refresher-previewfilter-category" category="전체">전체: 보이기</a>');

    category.each(function(index, item) {

        var data = $(item).text();

        data = data == "전체" ? "일반" : data;

        $('.refresher-previewfilter').append('<a class="dropdown-item refresher-previewfilter-category" category="' + data + '">' + data + ': 보이기</a>');

    });


    $('.refresher-setting-reset').click(function() {

        resetSetting();

        location.reload();

    });

    $('.refresher-setting-userefresh').click(function() {

        Setting.useRefresh = !Setting.useRefresh;

        if(Setting.useRefresh) {

            $(this).text('게시물 자동 새로고침 사용');

            initRefresher();

        }

        else {

            $(this).text('게시물 자동 새로고침 안함');

            stopRefresher();

        }

        saveSetting();

        return false;

    });

    $('.refresher-setting-refreshtime').click(function() {

        switch(Setting.refreshTime) {

            case 3:

                Setting.refreshTime = 5;

                break;

            case 5:

                Setting.refreshTime = 10;

                break;

            case 10:

                Setting.refreshTime = 3;

                break;

        }

        $(this).text('새로고침 시간 간격: ' + Setting.refreshTime + '초');

        if(Setting.useRefresh) {

            clearInterval(loader_loop);

            initLoader();

            loader_loop = setInterval(tryRefreshArticle, Setting.refreshTime * 1000);

        }

        saveSetting();

        return false;

    });

    $('.refresher-setting-hidenotice').click(function() {

        Setting.hideNotice = !Setting.hideNotice;

        if(Setting.hideNotice) {

            $(this).text('채널 공지 숨기기');

            hideNotice();

        }

        else {

            $(this).text('채널 공지 보이기');

            showNotice();

        }

        saveSetting();

        return false;

    });

    $('.refresher-setting-hideavatar').click(function() {

        Setting.hideAvatar = !Setting.hideAvatar;

        if(Setting.hideAvatar) {

            $('.refresher-setting-hideavatar').text('프로필 아바타 숨기기');

            hideAvatar();

        }

        else {

            $('.refresher-setting-hideavatar').text('프로필 아바타 보이기');

            showAvatar();

        }

        saveSetting();

        return false;

    });

    $('.refresher-setting-usepreviewfilter').click(function() {

        Setting.usePreviewFilter = !Setting.usePreviewFilter;

        if(Setting.usePreviewFilter) {

            $(this).text('미리보기 필터 사용 중...');

            $('.refresher-previewfilter').show();

        }

        else {

            $(this).text('미리보기 필터 사용 안함');

            $('.refresher-previewfilter').hide();

        }

        applyPreview();

        saveSetting();

        return false;

    });


    $('.refresher-previewfilter-category').click(function() {

        var category = $(this).attr('category');

        Setting.filteredCategory[category] = !Setting.filteredCategory[category];

        $(this).text(category + (Setting.filteredCategory[category] ? ": 숨기기" : ": 보이기"));

        applyPreview();

        saveSetting();

        return false;

    });

}


function init() {

    board = $('div.board-title > a').not('.subscribe-btn').attr('href').replace('/b/', '');

    list = $('.list-table');


    initSettingView();

    loadSetting();


    if(Setting.useRefresh)

        initRefresher();


    if(Setting.hideNotice)

        hideNotice();


    if(Setting.hideAvatar)

        hideAvatar();


    applyPreview();

    applyReplyRefresh();

}


init();