Skip to content
Snippets Groups Projects
Forked from R3 / howto-cards LEGACY VERSION
406 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
landing.js 8.52 KiB
window.cards_limit = 6;
var storage_key = "pinnedCards";
if (window.is_internal) {
    storage_key += "Internal"
} else {
    storage_key += "External"
}
let $left_inner_container = document.getElementById("left-inner-container");
let $right_inner_container = document.getElementById("right-inner-container");
let $drop_to_add = document.getElementById("drop-to-add");
// =============  DATA  ========================================
let pinned_cards_store = localStorage.getItem(storage_key);
window.pinned_cards = [
];
// =============  DOM functions  ========================================
let create_card = function(icon, title, caption, link) {
    let new_div = document.createElement('div');
    new_div.innerHTML = `
    <a class="card-link card-dynamic" ondragstart="window.cardDragStart(event)" ondragend="window.cardDragEnd(event)" href="${link}">
    <div class="card" draggable="True" ondragstart="window.cardDragStart(event)" ondragend="window.cardDragEnd(event)" data-icon='${icon}' data-title='${title}' data-caption='${caption}' data-link="${link}">
        <div class="card-header">
            <div class="card-icon">${icon}</div>
            <div class="card-title">${title}</div>
        </div>
        <div class="card-content">
            <div class="card-caption">${caption}</div>
        </div>
    </div>
    </a>
    `;
    return new_div;
};
let create_pinned_card = function(icon, title, caption, link) {
    let new_div = document.createElement('div');
    new_div.innerHTML = `
    <a class="card-link card-dynamic-pinned" ondragstart="window.pinnedCardDragStart(event)" ondragend="window.pinnedCardDragEnd(event)"   href="${link}">
    <div class="card-pinned" draggable="True" draggable="false" ondragstart="window.pinnedCardDragStart(event)" ondragend="window.pinnedCardDragEnd(event)"  data-icon='${icon}' data-title='${title}' data-caption='${caption}' data-link="${link}">
        <div class="card-header">
            <div class="card-icon">${icon}</div>
        </div>
        <div class="card-content">
            <div class="card-title">${title}</div>
        </div>
    </div>
    </a>
    `;
    return new_div;
}
let attach_card = function(container, card) {
    container.append(card);
}
let attach_pinned_card = function(container, card) {
    let card_el = create_pinned_card(card.icon, card.title, card.caption, card.link);
    let first_child = container.children[1];
    // might as well remove all children and rebuild the contents using window.pinned_cards
    container.insertBefore(card_el, first_child);
}
// =============  Helper functions  ========================================
let list_contains = function(the_list, the_object, key) {
    for (const element of the_list) {
        if (the_object[key] === element[key])
            return true;
    }
    return false;
}
let remove_from_list = function(the_list, the_object, key) {
    var index = -1;
    for (var i = 0; i < the_list.length; i++) {
        if (the_list[i][key] == the_object[key]) {
            index = i;
            break;
        }
    }
    if (index != -1) {
        the_list.splice(i, 1);
    }
}
// =============  DRAG&DROP functions  ========================================
window.cardDragStart = function(event) {
    var target = event.target;
    if (target.nodeName == 'A') {
        target = target.firstElementChild;
    }
    // First, attach classes for animations
    target.classList.add('card-dragged');
    target.children[1].classList.add('card-dragged');
    target.children[0].classList.add('card-dragged');
    $right_inner_container.classList.add('droppable');
    // Attach data about the card to drag&drop event
    let card = {
        "title": target.dataset['title'],
        "icon": target.dataset['icon'],
        "caption": target.dataset['caption'],
        "link": target.dataset['link'],
        "type": "big"
    }
    event.dataTransfer.setData("card", JSON.stringify(card));
    // Allow drag&drop
    event.dataTransfer.effectAllowed = 'move';
    return true;
}
window.cardDragEnd = function(event) {
    var target = event.target;
    if (target.nodeName == 'A') {
        target = target.firstElementChild;
    }
    target.classList.remove('card-dragged');
    target.children[1].classList.remove('card-dragged');
    target.children[0].classList.remove('card-dragged');
    $right_inner_container.classList.remove('droppable');
    return true;
}
window.pinnedCardDragStart = function(event) {
    var target = event.target;
    if (target.nodeName == 'A') {
        target = target.firstElementChild;
    }
    $left_inner_container.classList.add('droppable');
    // Attach data about the card to drag&drop event
    let card = {
        "title": target.dataset['title'],
        "icon": target.dataset['icon'],
        "caption": target.dataset['caption'],
        "link": target.dataset['link'],
        "type": "small"
    }
    event.dataTransfer.setData("card", JSON.stringify(card));
    // Allow drag&drop
    event.dataTransfer.effectAllowed = 'move';
    return true;
}
window.pinnedCardDragEnd = function(event) {
    $left_inner_container.classList.remove('droppable');
    return true;
}
window.cardDrop = function(event) {
    let serializedCard = event.dataTransfer.getData("card");
    let card = JSON.parse(serializedCard);
    // Don't react to dropping small (shortcut) cards
    if (card['type'] == "small") {
        return;
    }
    // Add limit of pinned cards
    if (window.pinned_cards.length >= window.cards_limit) {
        return;
    }
    if (!list_contains(window.pinned_cards, card, "title")) {
        window.pinned_cards.push(card);
        localStorage.setItem(storage_key, JSON.stringify(pinned_cards));
        window.cards = window.cards.filter(function(el) { return el['title'] != card['title'];});
        rebuild_pinned_cards();
        rebuild_cards();
    }
    refresh_drop_to_add_button();

    if (event.preventDefault) event.preventDefault();
    if (event.stopPropagation) event.stopPropagation();
}
window.cardDropDiscard = function(event) {
    let serializedCard = event.dataTransfer.getData("card");
    let card = JSON.parse(serializedCard);
    if (card['type'] == "big")
        return;
    if (list_contains(window.pinned_cards, card, "title")) {
        remove_from_list(window.pinned_cards, card, "title");
        localStorage.setItem(storage_key, JSON.stringify(pinned_cards));
        cards.push(card);
        rebuild_pinned_cards();
        rebuild_cards();
    }
    refresh_drop_to_add_button();
    if (event.preventDefault) event.preventDefault();
    if (event.stopPropagation) event.stopPropagation();
}
window.allowDrop = function(event) {
    event.preventDefault();
}
window.rebuild_cards = function() {
    while ($left_inner_container.firstChild) {
        $left_inner_container.removeChild($left_inner_container.firstChild);
    }
    for (const card of window.cards) {
        let card_el = create_card(card.icon, card.title, card.caption, card.link);
        attach_card($left_inner_container, card_el);
    }
}
window.rebuild_pinned_cards = function() {
    var old_pinned_cards = document.getElementsByClassName("card-dynamic-pinned");
    while (old_pinned_cards.length > 0){
        old_pinned_cards[0].parentNode.removeChild(old_pinned_cards[0]);
    }
    for (const card of pinned_cards) {
        let card_el = create_pinned_card(card.icon, card.title, card.caption, card.link);
        attach_pinned_card($right_inner_container, card);
    }
}
window.refresh_drop_to_add_button = function() {
    if (window.pinned_cards.length == window.cards_limit) {
        $drop_to_add.style.display = "none"
    } else {
        $drop_to_add.style.display = "block"
    }
}
window.clear_pinned = function() {
    for (card of pinned_cards) {
        cards.push(card);
    }
    pinned_cards = [];
    localStorage.setItem(storage_key, JSON.stringify(pinned_cards));
    rebuild_pinned_cards();
    rebuild_cards();
    refresh_drop_to_add_button();
}
window.start_cards = function() {
    // =============  Initialization  ========================================
    if (pinned_cards_store == null) {
        localStorage.setItem(storage_key, JSON.stringify(pinned_cards));
    } else {
        pinned_cards = JSON.parse(pinned_cards_store);
        // Sort alphabetically
        pinned_cards = pinned_cards.sort(function(a, b) { if (a.title > b.title) return -1; else if (a.title < b.title) return 1; else return 0; });
        // Remove duplicates of pinned cards
        for (const card of pinned_cards) {
            remove_from_list(cards, card, "title");
        }
    }
    refresh_drop_to_add_button();
    rebuild_cards();
    rebuild_pinned_cards();
}