diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/organize/controllers/organize.php | 144 | ||||
-rw-r--r-- | modules/organize/helpers/organize_theme.php | 4 | ||||
-rw-r--r-- | modules/organize/js/organize.js | 26 | ||||
-rw-r--r-- | modules/organize/views/organize_dialog.html.php | 6 | ||||
-rw-r--r-- | modules/organize/views/organize_thumb_grid.html.php | 8 |
5 files changed, 106 insertions, 82 deletions
diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index 76a22b73..f56ad006 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -60,7 +60,7 @@ class Organize_Controller extends Controller { "url" => url::site("organize/run/$task->id?csrf=" . access::csrf_token()))); } - function rearrange($target_id, $before) { + function rearrange($target_id, $before_or_after) { access::verify_csrf(); $target = ORM::factory("item", $target_id); $parent = $target->parent(); @@ -71,11 +71,12 @@ class Organize_Controller extends Controller { ->callback("Organize_Controller::rearrange_task_handler") ->description(t("Rearrange Image")) ->name(t("Rearrange Images")); - $task = task::create($task_def, array("target_id" => $target_id, "before" => $before, - "parent_id" => $parent->id, - "weight" => item::get_max_weight(), - "total" => $parent->children_count(), - "source_ids" => $this->input->post("source_ids"))); + $task = task::create( + $task_def, + array("target_id" => $target_id, + "before_or_after" => $before_or_after, + "parent_id" => $parent->id, + "source_ids" => $this->input->post("source_ids"))); print json_encode( array("result" => "started", @@ -168,71 +169,84 @@ class Organize_Controller extends Controller { } static function rearrange_task_handler($task) { - $phase = $task->get("phase", "before_drop"); - $source_ids = $task->get("source_ids"); - $parent = ORM::factory("item", $task->get("parent_id")); - $weight = $task->get("weight"); - $target_id = $task->get("target_id"); - $is_before = $task->get("before") == "before"; - - // @todo at some point if we allow drag from album tree this needs to be changed - if ($phase == "dropping") { - $children = ORM::factory("item") - ->where("parent_id", $parent->id) - ->where("weight < ", $weight) - ->in("id", $source_ids) - ->orderby(array($parent->sort_column => $parent->sort_order)) - ->find_all(); - if ($children->count() == 0) { - $phase = "after_drop"; - $task->set("phase", $phase); - } - } - if ($phase != "dropping") { - $dropping = false; - $children = ORM::factory("item") - ->where("parent_id", $parent->id) - ->where("weight < ", $weight) - ->in("id", $source_ids, true) - ->orderby(array($parent->sort_column => $parent->sort_order)) - ->find_all(); + $start = microtime(true); + $mode = $task->get("mode", "init"); + + if ($task->percent_complete == 0) { + batch::start(); } - $completed = $task->get("completed", 0); + while (microtime(true) - $start < 1.5) { + switch ($mode) { + case "init": + $album = ORM::factory("item", $task->get("parent_id")); + if ($album->sort_column != "weight") { + $mode = "convert-to-weight-order"; + } else { + $mode = "find-insertion-point"; + } + break; - $start = microtime(true); - foreach ($children as $child) { - $step = microtime(true); - if (microtime(true) - $start > 0.5) { + case "convert-to-weight-order": + $i = 0; + $album = ORM::factory("item", $task->get("parent_id")); + foreach ($album->children() as $child) { + // Do this directly in the database to avoid sending notifications + Database::Instance()->update("items", array("weight" => ++$i), array("id" => $child->id)); + } + $album->sort_column = "weight"; + $album->sort_order = "ASC"; + $album->save(); + $mode = "find-insertion-point"; + $task->percent_complete = 25; break; - } - if ($phase == "before_drop" && $child->id == $target_id && $is_before) { - $task->set("dropping", true); - $task->set("phase", "dropping"); + + case "find-insertion-point": + $target = ORM::factory("item", $task->get("target_id")); + $target_weight = $target->weight; + + if ($task->get("before_or_after") == "after") { + $target_weight++; + } + $task->set("target_weight", $target_weight); + $task->percent_complete = 40; + $mode = "make-a-hole"; break; - } - Database::instance()->query( - "UPDATE {items} SET `weight` = " . item::get_max_weight() . - " WHERE `id` = " . $child->id); - - $completed++; - if ($phase == "before_drop" && $child->id == $task->get("target_id")) { - $task->set("dropping", true); - $task->set("phase", "dropping"); + + case "make-a-hole": + $target_weight = $task->get("target_weight"); + $source_ids = $task->get("source_ids"); + $count = count($source_ids); + $parent_id = $task->get("parent_id"); + Database::Instance()->query( + "UPDATE {items} " . + "SET `weight` = `weight` + $count " . + "WHERE `weight` >= $target_weight AND `parent_id` = {$parent_id}"); + + $mode = "insert-source-items"; + $task->percent_complete = 80; + break; + + case "insert-source-items": + $target_weight = $task->get("target_weight"); + foreach ($source_ids as $source_id) { + Database::Instance()->update( + "items", array("weight" => $target_weight++), array("id" => $source_id)); + } + $mode = "done"; + break; + + case "done": + $album = ORM::factory("item", $task->get("parent_id")); + module::event("album_rearrange", $album); + batch::stop(); + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + $task->set("content", self::_get_micro_thumb_grid($album, 0)->__toString()); break; } } - if ($completed == $task->get("total")) { - Database::instance()->query( - "UPDATE {items} SET `sort_column` = \"weight\"" . - " WHERE `id` = " . $parent->id); - module::event("album_rearrange", $parent); - $task->done = true; - $task->state = "success"; - $task->set("content", self::_get_micro_thumb_grid($parent, 0)->__toString()); - $task->percent_complete = 100; - } else { - $task->percent_complete = (int)(100 * $completed / $task->get("total")); - } - $task->set("completed", $completed); + + $task->set("mode", $mode); } } diff --git a/modules/organize/helpers/organize_theme.php b/modules/organize/helpers/organize_theme.php index de812261..61b6fe7d 100644 --- a/modules/organize/helpers/organize_theme.php +++ b/modules/organize/helpers/organize_theme.php @@ -21,6 +21,10 @@ class organize_theme { static function head($theme) { $item = $theme->item(); if ($item && access::can("edit", $item) && $item->is_album()) { + // @todo: Defer loading js/css until we're loading the organize dialog as <script> and + // <link> elements so that we're not forcing them to be downloaded on every page view (which + // is expensive in terms of browser latency). When we do that, we'll have to figure out an + // approach that lets us continue to use the Kohana cascading filesystem. $theme->script("organize.js"); $theme->css("organize.css"); } diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index 0f8f7fa1..ec6bd924 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -8,16 +8,19 @@ helper: function(event, ui) { var selected = $(".ui-draggable.ui-state-selected img"); if (selected.length) { - var set = $('<div class="gDragHelper"></div>').css({zIndex: 2000, width: 80, height: Math.ceil(selected.length / 5) * 16 }), - offset = $(this).offset(), - click = { left: event.pageX - offset.left, top: event.pageY - offset.top }; + var set = $('<div class="gDragHelper"></div>') + .css({ + zIndex: 2000, + width: 80, + height: Math.ceil(selected.length / 5) * 16 + }); + var offset = $(this).offset(); + var click = {left: event.pageX - offset.left, top: event.pageY - offset.top}; selected.each(function(i) { var row = parseInt(i / 5); var j = i - (row * 5); - var o = $(this).offset(); - var copy = $(this).clone() .css({ width: $(this).width(), height: $(this).height(), display: "block", @@ -25,7 +28,7 @@ left: o.left - event.pageX, top: o.top - event.pageY }) .appendTo(set) - .animate({width: 10, height: 10, outlineWidth: 1, margin: 1, left: (20 * j), top: (row * 20)}, 500); + .animate({ width: 10, height: 10, outlineWidth: 1, margin: 1, left: (20 * j), top: (row * 20) }, 500); }); return set; } @@ -35,6 +38,7 @@ start: function(event, ui) { $("#gMicroThumbPanel .ui-state-selected").hide(); }, + drag: function(event, ui) { var top = $("#gMicroThumbPanel").offset().top; var height = $("#gMicroThumbPanel").height(); @@ -52,8 +56,9 @@ greedy: true, drop: function(event, ui) { $.organize.do_drop({ - url: rearrange_url.replace("__TARGET_ID__", $(".currentDropTarget").attr("ref")) - .replace("__BEFORE__", $(".currentDropTarget").css("borderLeftStyle") == "solid" ? "before" : "after"), + url: rearrange_url + .replace("__TARGET_ID__", $(".currentDropTarget").attr("ref")) + .replace("__BEFORE__", $(".currentDropTarget").css("borderLeftStyle") == "solid" ? "before" : "after"), source: $(ui.helper).children("img") }); } @@ -86,8 +91,9 @@ if (source_ids.length) { $("#gOrganize .gProgressBar").progressbar().progressbar("value", 0); $("#gOrganizeProgress").animate( - {height: "toggle", display: "toggle"}, - {duration: "fast", + { height: "toggle", display: "toggle" }, + { + duration: "fast", step: function() { }, complete: function() { diff --git a/modules/organize/views/organize_dialog.html.php b/modules/organize/views/organize_dialog.html.php index cd987819..7c09266f 100644 --- a/modules/organize/views/organize_dialog.html.php +++ b/modules/organize/views/organize_dialog.html.php @@ -11,10 +11,10 @@ <h3><?= t("Albums") ?></h3> </div> <div id="gMessage" class="yui-u"> - <div class="gInfo"><?= t("Select one or more items to edit; drag and drop items to re-order or move between albums") ?></div> + <div class="gInfo"><?= t("Drag and drop photos to re-order or move between albums") ?></div> </div> </div> - <div id= "gOrganizeContentPane" class="yui-gf"> + <div id="gOrganizeContentPane" class="yui-gf"> <div id="gOrganizeTreeContainer" class="yui-u first"> <ul id="gOrganizeAlbumTree"> <?= $album_tree ?> @@ -22,7 +22,7 @@ </div> <div id="gOrganizeDetail" class="yui-u"> <div id="gMicroThumbPanel" - ref="<?= url::site("organize/content/__ITEM_ID__/__OFFSET__") ?>"> + ref="<?= url::site("organize/content/__ITEM_ID__/__OFFSET__") ?>"> <ul id="gMicroThumbGrid"> <?= $micro_thumb_grid ?> </ul> diff --git a/modules/organize/views/organize_thumb_grid.html.php b/modules/organize/views/organize_thumb_grid.html.php index 671e0ce4..5adb487a 100644 --- a/modules/organize/views/organize_thumb_grid.html.php +++ b/modules/organize/views/organize_thumb_grid.html.php @@ -1,10 +1,10 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> <? foreach ($item->children(25, $offset) as $child): ?> <li class="gMicroThumbGridCell" ref="<?= $child->id ?>"> -<div id="gMicroThumb_<?= $child->id ?>" - class="gMicroThumb <?= $child->is_album() ? "gAlbum" : "gPhoto" ?>"> - <?= $child->thumb_img(array("class" => "gThumbnail", "ref" => $child->id), 90, true) ?> -</div> + <div id="gMicroThumb_<?= $child->id ?>" + class="gMicroThumb <?= $child->is_album() ? "gAlbum" : "gPhoto" ?>"> + <?= $child->thumb_img(array("class" => "gThumbnail", "ref" => $child->id), 90, true) ?> + </div> </li> <? endforeach ?> |