summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Almdal <tnalmdal@shaw.ca>2009-04-22 16:09:57 +0000
committerTim Almdal <tnalmdal@shaw.ca>2009-04-22 16:09:57 +0000
commit475b8fe9ff3f4eee077fd649a1e5aea2568c06b4 (patch)
treea892d62e17c451db626d031e43753be71b364764
parentf9ec5d6de466b6a7c9eb4766ca228aff754284f5 (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.php118
-rw-r--r--modules/organize/css/organize.css5
-rw-r--r--modules/organize/helpers/organize_task.php31
-rw-r--r--modules/organize/js/organize.js102
-rw-r--r--modules/organize/views/organize.html.php2
-rw-r--r--modules/organize/views/organize_album.html.php8
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>