Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replaced Masonry with Packery #100

Merged
merged 4 commits into from
Feb 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
],
"description": "Live, controllable graphics system rendered in a browser",
"dependencies": {
"masonry": "~3.1.5",
"draggabilly": "~1.1.2",
"packery": "~1.3.2",
"imagesloaded": "~3.1.5",
"bootstrap": "~3.2.0",
"bsw-yeti": "~3.2.0",
Expand Down
7 changes: 5 additions & 2 deletions lib/dashboard/public/dashboard.jade
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mixin panels(bundle)
each panel in bundle.dashboard.panels
div(class='#{ bundle.name } #{ panel.name } panel panel-default panel-span-#{ panel.width }')
div(class='#{ bundle.name } #{ panel.name } panel panel-default panel-span-#{ panel.width }',
data-panel=panel.name)
.panel-heading
h3.panel-title=panel.title
i(class="fa panel-icon #{ panel.faIcon }")
Expand Down Expand Up @@ -88,7 +89,8 @@ html(lang="en")
script(src='/components/bootstrap/dist/js/bootstrap.min.js')
script(src='/components/bootstrap/js/tooltip.js')
script(src='/components/bootstrap/js/popover.js')
script(src='/components/masonry/dist/masonry.pkgd.min.js')
script(src='/components/draggabilly/dist/draggabilly.pkgd.min.js')
script(src='/components/packery/dist/packery.pkgd.min.js')
script(src='/components/imagesloaded/imagesloaded.pkgd.min.js')
script(src='/components/moment/min/moment.min.js')
script(src='/components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js')
Expand All @@ -111,6 +113,7 @@ html(lang="en")
window.socket = io.connect('//#{ ncgConfig.host }:#{ ncgConfig.port }/');
script(src='/nodecg-api.js')

script(src='/dashboard/panels.dashboard.js')
script(src='/dashboard/dashboard.js')

//- Bundle javascript
Expand Down
22 changes: 7 additions & 15 deletions lib/dashboard/public/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ window.onload = function () {
}

$panelsContainer.imagesLoaded(function () {
//Apply initial masonry
applyMasonry($panelsContainer);
//Init Packery
initPackery($panelsContainer);

try {
//Create a MutationObserver which will watch for changes to the DOM and re-apply masonry
observer = new MutationObserver(function () {
applyMasonry($panelsContainer);
applyPackery();
});

// define what element should be observed by the observer
Expand All @@ -165,21 +165,13 @@ window.onload = function () {

// re-apply masonry onClick, useful for checkboxes that toggle controls
$panelsContainer.click(function () {
applyMasonry($panelsContainer);
applyPackery();
});

// TODO: have masonry re-apply when a textarea is resized
function applyMasonry(selector) {
selector.masonry({
columnWidth: 128 + 16, //.panel-span-1 width = 128, +16 for 8px pad on each side
itemSelector: '.dashboard-panels > .panel'
});
}

// Initialize all panel info popovers
$panels.find('.panel-info').popover();
// Initialize all panel info popovers
$panels.find('.panel-info').popover();

// Helper for .btn-file inputs, makes them fire the expected event and display expected filename
// Helper for .btn-file inputs, makes them fire the expected event and display expected filename
$('.btn-file :file').on('change', function() {
var input = $(this),
numFiles = input.get(0).files ? input.get(0).files.length : 1,
Expand Down
4 changes: 4 additions & 0 deletions lib/dashboard/public/dashboard.less
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ textarea {
padding: 0 16px 32px 16px;
}

.panel {
margin-bottom: 0;
}

.panel-title {
display: inline-block;
}
Expand Down
106 changes: 106 additions & 0 deletions lib/dashboard/public/panels.dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
var $packeryContainer,
isPackeryInit = false;

function arrayUnique(array) {
var a = array.concat();
for (var i = 0; i < a.length; ++i) {
for (var j = i + 1; j < a.length; ++j) {
if (a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
}

function initPackery($panelsContainer) {
var itemSelector = '.panel';

$packeryContainer = $panelsContainer.packery({
columnWidth: 128, //.panel-span-1 width = 128
gutter: 16, // gutter = 8*2
// disable initial layout
isInitLayout: false
});

var pckry = $packeryContainer.data('packery');

// Initial sort
var sortOrder = []; // global variable for saving order, used later
var storedSortOrder = localStorage.getItem('panelSortingOrder');
if (storedSortOrder) {
storedSortOrder = JSON.parse(storedSortOrder);

//create a hash of items
var itemsByPanelName = {},
allPanels = [];
var panelName;
for (var i = 0, len = pckry.items.length; i < len; i++) {
var item = pckry.items[i];
panelName = $(item.element).attr('data-panel');
allPanels[i] = panelName;
itemsByPanelName[panelName] = item;
}

// Merge the saved panel array with our currently loaded panels, remove dupes
var allPanelsOrdered = arrayUnique(storedSortOrder.concat(allPanels));

// Remove panels that no longer exist
var removededOld = allPanelsOrdered.filter(function (val) {
return allPanels.indexOf(val) !== -1;
});

// overwrite packery item order
i = 0;
len = removededOld.length;
for (; i < len; i++) {
panelName = removededOld[i];
pckry.items[i] = itemsByPanelName[panelName];
}
}

// Manually trigger initial layout
$packeryContainer.packery();
isPackeryInit = true;

$packeryContainer.find(itemSelector).each(function (i, itemElem) {
// make element draggable with Draggabilly
var draggie = new Draggabilly(itemElem, {
"handle": '.panel-heading'
});

// bind Draggabilly events to Packery
$packeryContainer.packery('bindDraggabillyEvents', draggie);
});

// Daggabilly shtuff

// Currently, there is no built-in option to force dragged elements to gravitate to their
// nearest neighbour in a specific direction. This will reset their locations 100ms after a drag
// causing them to gravitate.
$packeryContainer.packery('on', 'dragItemPositioned', function (pckryInstance, draggedItem) {
setTimeout(function () {
$packeryContainer.packery();
}, 100);
});

function orderItems() {
var itemElems = pckry.getItemElements();

// reset / empty order array
sortOrder.length = 0;

for (var i = 0; i < itemElems.length; i++) {
sortOrder[i] = itemElems[i].getAttribute('data-panel');
}

// save ordering
localStorage.setItem('panelSortingOrder', JSON.stringify(sortOrder));
}

$packeryContainer.packery('on', 'layoutComplete', orderItems);
$packeryContainer.packery('on', 'dragItemPositioned', orderItems);
}

function applyPackery() {
if (isPackeryInit) $packeryContainer.packery();
}