Forked from
R3 / howto-cards LEGACY VERSION
406 commits behind the upstream repository.
-
Jacek Lebioda authoredJacek Lebioda authored
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();
}