diff options
author | Tim Almdal <tnalmdal@shaw.ca> | 2009-04-22 16:09:57 +0000 |
---|---|---|
committer | Tim Almdal <tnalmdal@shaw.ca> | 2009-04-22 16:09:57 +0000 |
commit | 475b8fe9ff3f4eee077fd649a1e5aea2568c06b4 (patch) | |
tree | a892d62e17c451db626d031e43753be71b364764 | |
parent | f9ec5d6de466b6a7c9eb4766ca228aff754284f5 (diff) |
Dragging from the thumbgrid to an album in the tree now works.
Refactored the javascript to minimize duplication.
-rw-r--r-- | modules/organize/controllers/organize.php | 118 | ||||
-rw-r--r-- | modules/organize/css/organize.css | 5 | ||||
-rw-r--r-- | modules/organize/helpers/organize_task.php | 31 | ||||
-rw-r--r-- | modules/organize/js/organize.js | 102 | ||||
-rw-r--r-- | modules/organize/views/organize.html.php | 2 | ||||
-rw-r--r-- | modules/organize/views/organize_album.html.php | 8 |
6 files changed, 212 insertions, 54 deletions
diff --git a/modules/organize/controllers/organize.php b/modules/organize/controllers/organize.php index bb74f23a..129fb8bb 100644 --- a/modules/organize/controllers/organize.php +++ b/modules/organize/controllers/organize.php @@ -84,30 +84,8 @@ class Organize_Controller extends Controller { return $v->__toString(); } - function rearrangeStart($id) { - access::verify_csrf(); - $items = $this->input->post("item"); - - $item = ORM::factory("item", $id); - - $task_def = Task_Definition::factory() - ->callback("organize_task::rearrange") - ->description(t("Rearrange the order of albums and photos")) - ->name(t("Rearrange: %name", array("name" => $item->title))); - $task = task::create($task_def, array("items" => $items, "position" => 0, "batch" => - ceil(count($items) * .1))); - - batch::start(); - print json_encode(array("result" => "started", - "task" => array( - "id" => $task->id, - "percent_complete" => $task->percent_complete, - "status" => $task->status, - "done" => $task->done))); - } - function rearrangeRun($id, $task_id) { - Kohana::log("debug", "rearrangeRun($id, $task_id)"); + function runTask($task_id) { access::verify_csrf(); $task = task::run($task_id); @@ -117,38 +95,104 @@ class Organize_Controller extends Controller { "id" => $task->id, "percent_complete" => $task->percent_complete, "status" => $task->status, + "state" => $task->state, "done" => $task->done))); } - function rearrangeFinish($id, $task_id) { - Kohana::log("debug", "rearrangeFinish($id, $task_id)"); + function finishTask($task_id) { access::verify_csrf(); $task = ORM::factory("task", $task_id); if ($task->done) { - try { - $item = ORM::factory("item", $id); - $item->sort_column = "weight"; - $item->save(); - $task->status = t("Rearrange for '%album' completed", array("album" => $item->title)); - } catch (Exception $e) { - $task->state = "error"; - $task->status = $e->getMessage(); + switch ($task->context["type"]) { + case "moveTo": + $task->status = t("Move to '%album' completed", array("album" => $item->title)); + break; + case "rearrange": + try { + $item = ORM::factory("item", $task->context["target"]); + $item->sort_column = "weight"; + $item->save(); + $task->status = t("Rearrange for '%album' completed", array("album" => $item->title)); + } catch (Exception $e) { + $task->state = "error"; + $task->status = $e->getMessage(); + } + break; } + $task->save(); } - + batch::stop(); print json_encode(array("result" => "success")); } - - function rearrangePause($id, $task_id) { + + function cancelTask($task_id) { access::verify_csrf(); $task = ORM::factory("task", $task_id); - message::warning(t("Rearrange album was cancelled prior to completion")); + if ($task->done) { + switch ($task->context["type"]) { + case "moveTo": + message::warning(t("Move to album was cancelled prior to completion")); + break; + case "rearrange": + message::warning(t("Rearrange album was cancelled prior to completion")); + break; + } + } + batch::stop(); print json_encode(array("result" => "success")); } + + function moveStart($id) { + access::verify_csrf(); + $items = $this->input->post("item"); + + $item = ORM::factory("item", $id); + + $task_def = Task_Definition::factory() + ->callback("organize_task::move") + ->description(t("Move albums and photos to '%name'", array("name" => $item->title))) + ->name(t("Move to '%name'", array("name" => $item->title))); + $task = task::create($task_def, array("items" => $items, "position" => 0, "target" => $id, + "type" => "moveTo", + "batch" => ceil(count($items) * .1))); + + batch::start(); + print json_encode(array("result" => "started", + "task" => array( + "id" => $task->id, + "percent_complete" => $task->percent_complete, + "status" => $task->status, + "state" => $task->state, + "done" => $task->done))); + } + + function rearrangeStart($id) { + access::verify_csrf(); + $items = $this->input->post("item"); + + $item = ORM::factory("item", $id); + + $task_def = Task_Definition::factory() + ->callback("organize_task::rearrange") + ->description(t("Rearrange the order of albums and photos")) + ->name(t("Rearrange: %name", array("name" => $item->title))); + $task = task::create($task_def, array("items" => $items, "position" => 0, "target" => $id, + "type" => "rearrange", + "batch" => ceil(count($items) * .1))); + + batch::start(); + print json_encode(array("result" => "started", + "task" => array( + "id" => $task->id, + "percent_complete" => $task->percent_complete, + "status" => $task->status, + "state" => $task->state, + "done" => $task->done))); + } }
\ No newline at end of file diff --git a/modules/organize/css/organize.css b/modules/organize/css/organize.css index a1dc062a..c29f334f 100644 --- a/modules/organize/css/organize.css +++ b/modules/organize/css/organize.css @@ -20,8 +20,13 @@ padding: .3em 0; } +.gBranchDroppable { + border: 1px dotted; +} + .gBranchText { cursor: pointer; + width: auto; } .gBranchCollapsed { diff --git a/modules/organize/helpers/organize_task.php b/modules/organize/helpers/organize_task.php index f923fdc7..a6d89e37 100644 --- a/modules/organize/helpers/organize_task.php +++ b/modules/organize/helpers/organize_task.php @@ -27,7 +27,7 @@ class organize_task_Core { $context = unserialize($task->context); try { - $stop = $context["position"] + $context["batch"]; + $stop = min(count($context["items"]), $context["position"] + $context["batch"]); for (; $context["position"] < $stop; $context["position"]++ ) { $id = $context["items"][$context["position"]]; Database::instance() @@ -35,12 +35,37 @@ class organize_task_Core { } $task->state = "success"; } catch(Exception $e) { - $tast->status = $e->getMessage(); + $task->status = $e->getMessage(); $task->state = "error"; + $task->save(); + throw $e; } $task->context = serialize($context); $total = count($context["items"]); $task->percent_complete = $context["position"] / (float)$total * 100; - $task->done = $context["position"] == $total; + $task->done = $context["position"] == $total || $task->state == "error"; + } + + static function move($task) { + $context = unserialize($task->context); + + try { + $target = ORM::factory("item", $context["target"]); + $stop = min(count($context["items"]), $context["position"] + $context["batch"]); + for (; $context["position"] < $stop; $context["position"]++ ) { + $source = ORM::factory("item", $context["items"][$context["position"]]); + core::move_item($source, $target); + } + $task->state = "success"; + } catch(Exception $e) { + $task->status = $e->getMessage(); + $task->state = "error"; + $task->save(); + throw $e; + } + $task->context = serialize($context); + $total = count($context["items"]); + $task->percent_complete = $context["position"] / (float)$total * 100; + $task->done = $context["position"] == $total || $task->state == "error"; } }
\ No newline at end of file diff --git a/modules/organize/js/organize.js b/modules/organize/js/organize.js index 00db46d3..75d5ccd2 100644 --- a/modules/organize/js/organize.js +++ b/modules/organize/js/organize.js @@ -1,11 +1,14 @@ /* * @todo Trap resize of dialog and resize the child areas (tree, grid and edit form) - * @todo create the dialog close method and reload the page on exit. + * @todo Create a cancel button that leaves the task in pending but clears the task info + * and resets the paused. + * @todo Create a message area in the footer for all the organize messages */ var url; var height; var paused = false; var task = null; +var transitItems = []; // ************************************************************************** // JQuery UI Widgets @@ -64,9 +67,15 @@ var draggable = { } }; -// Droppable -var droppable = { +// Thumbnail Grid Droppable +var thumbDroppable = { tolerance: "pointer", + over: function(event, ui) { + $("#gPlaceHolder").show(); + }, + out: function(event, ui) { + $("#gPlaceHolder").hide(); + }, drop: function(event, ui) { $("#gDragHelper").hide(); $("#gPlaceHolder").hide(); @@ -90,7 +99,40 @@ var droppable = { dataType: "json", success: startRearrangeCallback, type: "POST", - url: get_url("organize/rearrangeStart") + url: get_url("organize/rearrangeStart", {item_id: item_id}) + }); + } +}; + +// Album Tree Droppable +var treeDroppable = { + tolerance: "pointer", + greedy: true, + hoverClass: "gBranchDroppable", + drop: function(event, ui) { + $("#gDragHelper").hide(); + var moveItems = ""; + var targetItemId = $(this).attr("ref"); + if ($(this).hasClass("gBranchSelected")) { + // @todo Error message for moving onto self + return false; + } + var okToMove = true; + $("#gDragHelper li").each(function(i) { + moveItems += "&item[]=" + $(this).attr("ref"); + okToMove &= targetItemId != $(this).attr("ref"); + $("#thumb_" + $(this).attr("ref")).remove(); + }); + if (!okToMove) { + // @todo Error message for moving onto self + return false; + } + $.ajax({ + data: moveItems, + dataType: "json", + success: startMoveCallback, + type: "POST", + url: get_url("organize/moveStart", {item_id: targetItemId}) }); } }; @@ -175,6 +217,45 @@ var getMicroThumbsCallback = function(json, textStatus) { } }; +// @todo see if we can combine the next two callbacks into an object +// as they are basically the same. +var startMoveCallback = function (data, textStatus) { + if (!paused) { + $("#gDialog #ft").css("visibility", "visible"); + $(".gProgressBar").progressbar("value", 0); + task = data.task; + } + $(".gMicroThumbContainer").draggable("disable"); + var done = false; + paused = false; + while (!done && !paused) { + $.ajax({async: false, + success: function(data, textStatus) { + $(".gProgressBar").progressbar("value", data.task.percent_complete); + done = data.task.done; + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + paused = true; + displayAjaxError(XMLHttpRequest.responseText); + }, + dataType: "json", + type: "POST", + url: get_url("organize/runTask", {task_id: task.id}) + }); + } + if (!paused) { + $("#gDialog #ft").css("visibility", "hidden"); + $.ajax({async: false, + success: function(data, textStatus) { + }, + dataType: "json", + type: "POST", + url: get_url("organize/finishTask", {task_id: task.id}) + }); + } + $(".gMicroThumbContainer").draggable("enable"); +}; + var startRearrangeCallback = function (data, textStatus) { if (!paused) { $("#gDialog #ft").css("visibility", "visible"); @@ -196,7 +277,7 @@ var startRearrangeCallback = function (data, textStatus) { }, dataType: "json", type: "POST", - url: get_url("organize/rearrangeRun", task.id) + url: get_url("organize/runTask", {task_id: task.id}) }); } if (!paused) { @@ -206,7 +287,7 @@ var startRearrangeCallback = function (data, textStatus) { }, dataType: "json", type: "POST", - url: get_url("organize/rearrangeFinish", task.id) + url: get_url("organize/finishTask", {task_id: task.id}) }); } $(".gMicroThumbContainer").draggable("enable"); @@ -249,6 +330,7 @@ function organize_dialog_init() { $("#gOrganizeTreeContainer").height(height); $(".gOrganizeBranch .ui-icon").click(organizeToggleChildren); + $(".gBranchText").droppable(treeDroppable); $(".gBranchText").click(organizeOpenFolder); retrieveMicroThumbs(item_id); //showLoading("#gDialog"); @@ -256,7 +338,7 @@ function organize_dialog_init() { $("#gMicroThumbSelectAll").click(toggleSelectAll); $("#gMicroThumbUnselectAll").click(toggleSelectAll); - $("#gMicroThumbPanel").droppable(droppable); + $("#gMicroThumbPanel").droppable(thumbDroppable); $("#gMicroThumbGrid").selectable(selectable); $(".gProgressBar").progressbar(); @@ -312,10 +394,12 @@ function organizeOpenFolder(event) { event.preventDefault(); } -function get_url(uri, task_id) { +function get_url(uri, parms) { var url = rearrangeUrl; url = url.replace("__URI__", uri); - url = url.replace("__TASK_ID__", !task_id ? "" : "/" + task_id); + url = url.replace("__ITEM_ID__", !parms.item_id ? "" : parms.item_id); + url += (parms.item_id && parms.task_id) ? "/" : ""; + url = url.replace("__TASK_ID__", !parms.task_id ? "" : parms.task_id); return url; } diff --git a/modules/organize/views/organize.html.php b/modules/organize/views/organize.html.php index 5a3ace95..e679f907 100644 --- a/modules/organize/views/organize.html.php +++ b/modules/organize/views/organize.html.php @@ -4,7 +4,7 @@ var FATAL_ERROR = "<?= t("Fatal Error") ?>"; var item_id = <?= $item->id ?>; var csrf = "<?= $csrf ?>"; - var rearrangeUrl = "<?= url::site("__URI__/{$item->id}__TASK_ID__?csrf=$csrf") ?>"; + var rearrangeUrl = "<?= url::site("__URI__/__ITEM_ID____TASK_ID__?csrf=$csrf") ?>"; $("#doc3").ready(function() { organize_dialog_init(); }); diff --git a/modules/organize/views/organize_album.html.php b/modules/organize/views/organize_album.html.php index 9f38a2cc..d4296918 100644 --- a/modules/organize/views/organize_album.html.php +++ b/modules/organize/views/organize_album.html.php @@ -3,13 +3,13 @@ <li class="gOrganizeBranch ui-icon-left" ref="<?= $album->id ?>"> <span id="gOrganizeIcon-<?= $album->id ?>" ref="<?= $album->id ?>" class="ui-icon <?= $album_icon ?><? if (empty($album_icon)): ?> gBranchEmpty<? endif ?>">> </span> - <span id="gOrganizeBranch-<?= $album->id ?>" ref="<?= $album->id ?>" + <div id="gOrganizeBranch-<?= $album->id ?>" ref="<?= $album->id ?>" class="<? if ($selected): ?>gBranchSelected <? endif ?>gBranchText"> <?= $album->title ?> - </span> - <span id="gOrganizeChildren-<?= $album->id ?>" + </div> + <div id="gOrganizeChildren-<?= $album->id ?>" class="<? if ($album_icon == "ui-icon-plus"): ?>gBranchCollapsed<? endif ?>"> <?= $children ?> - <span> + <div> </li> </ul> |