]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Re-do the logic for the event micro-app's dropdowns (way trickier than it seems at...
authorZach Copley <zach@status.net>
Thu, 8 Sep 2011 07:42:13 +0000 (00:42 -0700)
committerZach Copley <zach@status.net>
Thu, 8 Sep 2011 07:45:56 +0000 (00:45 -0700)
plugins/Event/event.js
plugins/Event/eventform.php
plugins/Event/eventtimelist.php
plugins/Event/newevent.php

index 8ed25a899bff11674efa006380a047a7dbc5d267..696176edbde81b562daf05711a604c4a5637d3f6 100644 (file)
 $(document).ready(function() {
 
-    var today = new Date();
+    // get current time from server
+    var today = new Date($('now').val());
 
     $("#event-startdate").datepicker({
-        // Don't let the user set a crazy start date
+        // Don't let the user set a start date < before today
         minDate: today,
-        onClose: function(dateText, picker) {
-            // Don't let the user set a crazy end date
-            var newStartDate = new Date(dateText);
-            var endDate = new Date($("#event-startdate").val());
-            if (endDate < newStartDate) {
-                $("#event-enddate").val(dateText);
-            }
-            if (dateText !== null) {
-                $("#event-enddate").datepicker('option', 'minDate', new Date(dateText));
-            }
-        },
-        onSelect: function() {
-            var startd = $("#event-startdate").val();
-            var endd = $("#event-enddate").val();
-            var sdate = new Date(startd);
-            var edate = new Date(endd);
-            if (sdate !== edate) {
-                updateTimes();
-            }
-        }
+        onClose: onStartDateSelected
     });
 
     $("#event-enddate").datepicker({
         minDate: today,
-        onSelect: function() {
-            var startd = $("#event-startdate").val();
-            var endd = $("#event-enddate").val();
-            var sdate = new Date(startd);
-            var edate = new Date(endd);
-            if (sdate !== edate) {
-                updateTimes();
+        onClose: onEndDateSelected
+    });
+
+    $("#event-starttime").change(function(e) {
+        var tz = $("#tz").val();
+
+        var startDate = $("#event-startdate").val();
+        var startTime = $("#event-starttime option:selected").val().replace(/(pm|am)/, ' $1');
+        var startStr = startDate + ' ' + startTime + ' ' + tz;
+
+        var endDate =  $("#event-enddate").val();
+        var endTime = $("#event-endtime option:selected").val();
+        var endStr = endDate + ' ' + endTime.replace(/(pm|am)/, ' $1') + ' ' + tz;
+
+        // just need to compare hours
+        var start = new Date(startStr);
+        var end = new Date(endStr);
+
+        updateTimes(startStr, (startDate === endDate), function (data) {
+            var times = [];
+            $.each(data, function(key, val) {
+                times.push('<option value="' + key + '">' + val + '</option>');
+            });
+            $("#event-endtime").html(times.join(''));
+
+            if (start > end) {
+                $("#event-endtime").val(startTime).attr("selected", "selected");
+            } else {
+                $("#event-endtime").val(endTime).attr("selected", "selected");
+            }
+        });
+
+    });
+
+    $("#event-endtime").change(function(e) {
+        var HOUR = 60 * 60 * 1000;
+        var tz = $("#tz").val();
+        var startDate = $("#event-startdate").val();
+        var endDate = $("#event-enddate").val();
+        var starttime = $("#event-starttime option:selected").val();
+        var endtime = $("#event-endtime option:selected").val();
+        var endtimeText = $("#event-endtime option:selected").text();
+
+        // If the end time is in the next day then update the start date
+        if (startDate === endDate) {
+            var startstr = startDate + ' ' + starttime.replace(/(pm|am)/, ' $1') + ' ' + tz;
+            var start = new Date(startstr);
+            var matches = endtimeText.match(/\(.*\)/);
+            var hours;
+            if (matches) {
+                hours = matches[0].substr(1).split(' ')[0]; // get x from (x hours)
+                if (hours) {
+                    if (hours == 30) {
+                        hours = .5; // special case: x == 30 from (30 mins)
+                    }
+                    var end = new Date(start.getTime() + (hours * HOUR));
+                    if (end.getDate() > start.getDate()) {
+                        $("#event-enddate").datepicker('setDate', end);
+                        var endstr = endDate + ' 12:00 am ' +  tz;
+                        updateTimes(endstr, false, function(data) {
+                            var times = [];
+                            $.each(data, function(key, val) {
+                                times.push('<option value="' + key + '">' + val + '</option>');
+                            });
+                            $("#event-endtime").html(times.join(''));
+
+                            if (start > end) {
+                                $("#event-endtime").val(starttime).attr("selected", "selected");
+                            } else {
+                                $("#event-endtime").val(endtime).attr("selected", "selected");
+                            }
+                        });
+                    }
+                }
             }
         }
     });
 
-    function updateTimes() {
-        var startd = $("#event-startdate").val();
-        var endd = $("#event-enddate").val();
+    function onStartDateSelected(dateText, inst) {
+        var tz = $("#tz").val();
+        var startTime = $("#event-starttime option:selected").val();
+        var startDateTime = new Date(dateText + ' ' + startTime.replace(/(pm|am)/, ' $1') + ' ' + tz);
+
+        // When we update the start date and time, we need to update the end date and time
+        // to make sure they are equal or in the future
+        $("#event-enddate").datepicker('option', 'minDate', startDateTime);
+
+        recalculateTimes();
+    }
+
+    function onEndDateSelected(dateText, inst) {
+        recalculateTimes();
+    }
+
+    function recalculateTimes(showDuration) {
+        var tz = $("#tz").val();
 
-        var startt = $("#event-starttime option:selected").val();
-        var endt = $("#event-endtime option:selected").val();
+        var startDate = $("#event-startdate").val();
+        var startTime = $("#event-starttime option:selected").val();
+        var startStr = startDate + ' ' + startTime.replace(/(pm|am)/, ' $1') + ' ' + tz;
+        var startDateTime = new Date(startStr);
 
-        var sdate = new Date(startd + " " + startt);
-        var edate = new Date(endd + " " + endt);
-        var duration = (startd === endd);
+        var endDate = $("#event-enddate").val();
+        var endTime = $("#event-endtime option:selected").val();
+        var endDateTime = new Date(endDate + ' ' + endTime.replace(/(pm|am)/, ' $1') + ' ' + tz);
+        var showDuration = true;
+
+        if (endDateTime.getDate() !== startDateTime.getDate()) {
+            starStr = endDate + ' 12:00 am ' +  tz;
+            showDuration = false;
+        }
 
-        $.getJSON($('#timelist_action_url').val(),
-            { start: startt, ajax: true, duration: duration },
-            function(data) {
-                var times = [];
-                $.each(data, function(key, val) {
+        updateTimes(startStr, showDuration, function(data) {
+            var times = [];
+            $.each(data, function(key, val) {
                 times.push('<option value="' + key + '">' + val + '</option>');
             });
-
             $("#event-endtime").html(times.join(''));
-            if (startt < endt) {
-                $("#event-endtime").val(endt).attr("selected", "selected");
+            if (startDateTime > endDateTime) {
+                $("#event-endtime").val(startTime).attr("selected", "selected");
+            } else {
+                $("#event-endtime").val(endTime).attr("selected", "selected");
             }
-        })
+        });
     }
 
-    $("#event-starttime").change(function(e) {
-        updateTimes();
-    });
+    function updateTimes(start, duration, onSuccess) {
+        $.getJSON($('#timelist_action_url').val(), {start: start, ajax: true, duration: duration}, onSuccess);
+    }
 
 });
index c09a7ab171f9e00c24efbe80e518bc9acb74ee1d..ab50e6d47e4004c8d3062547680e64ec86709b4e 100644 (file)
@@ -123,7 +123,12 @@ class EventForm extends Form
 
         $this->li();
 
-        $times = EventTimeList::getTimes();
+        $times = EventTimeList::getTimes($today->format('m/d/Y 12:00') . ' am ' . $today->format('T'));
+
+        common_debug(var_export($times, true));
+
+        $start = EventTimeList::nearestHalfHour('@' . $today->getTimestamp());
+        $start->setTimezone(new DateTimeZone(common_timezone()));
 
         $this->out->dropdown(
             'event-starttime',
@@ -131,11 +136,15 @@ class EventForm extends Form
             _m('LABEL','Start time'),
             $times,
             // TRANS: Field title on event form. %s is the abbreviated timezone
-            sprintf(_m("Time the event starts (%s)."), $today->format("T")),
+            sprintf(_m("Time the event starts (%s)."), $today->format('T')),
             false,
-            null
+            $start->format('g:ia')
         );
 
+        // Need to keep JavaScript TZ in sync with PHP TZ
+        $this->out->hidden('tz', $today->format('T'));
+        $this->out->hidden('now', $today->format('F d, Y H:i:s T'));
+
         $this->unli();
 
         $this->li();
@@ -150,18 +159,11 @@ class EventForm extends Form
 
         $this->li();
 
-        // XXX: Initial end time should be at least 30 mins out?  We could do
-        // every 15 minute instead -z
-        $keys   = array_keys($times);
-        $endStr = date('m/d/y', strtotime('now')) . " {$keys[0]}";
-        $end    = new DateTime($endStr);
-        $end->modify('+30');
-
         $this->out->dropdown(
             'event-endtime',
             // TRANS: Field label on event form.
             _m('LABEL','End time'),
-            EventTimeList::getTimes($end->format('c'), true),
+            EventTimeList::getTimes('@' . $start->getTimestamp(), true),
             // TRANS: Field title on event form.
             _m('Time the event ends.'),
             false,
index 9238f294d0a8fadd114ecdb0e9776ca5922875b9..2436a4fc6e62b2d70a7f8d740ab7de67589431cf 100644 (file)
@@ -39,10 +39,10 @@ class EventTimeList {
      */
     public static function nearestHalfHour($time)
     {
-        $start = strtotime($time);
+        $startd = new DateTime($time);
 
-        $minutes = date('i', $start);
-        $hour = date('H', $start);
+        $minutes = $startd->format('i');
+        $hour    = $startd->format('H');
 
         if ($minutes >= 30) {
             $minutes = '00';
@@ -51,39 +51,34 @@ class EventTimeList {
             $minutes = '30';
         }
 
-        $newTimeStr = date('m/d/y', $start) . " {$hour}:{$minutes}:00";
-        return new DateTime($newTimeStr);
+        $startd->setTime($hour, $minutes, 0);
+
+        return $startd;
     }
 
     /**
      * Output a list of times in half-hour intervals
      *
-     * @param string  $start       Time to start with (date/time string)
+     * @param string  $start       Time to start with (date string, usually a ts)
      * @param boolean $duration    Whether to include the duration of the event
      *                             (from the start)
-     * @return array  $times (UTC time string => localized time string)
+     * @return array  $times (localized 24 hour time string => fancy time string)
      */
     public static function getTimes($start = 'now', $duration = false)
     {
-        $newTime = self::nearestHalfHour($start);
+        $newTime = new DateTime($start);
+        $times   = array();
+        $len     = 0;
 
         $newTime->setTimezone(new DateTimeZone(common_timezone()));
-        $times = array();
-        $len   = 0;
 
-        for ($i = 0; $i < 48; $i++) {
-            // make sure we store the time as UTC
-            $newTime->setTimezone(new DateTimeZone('UTC'));
-            $utcTime = $newTime->format('H:i:s');
+        for ($i = 0; $i < 47; $i++) {
 
-            // localize time for user
-            $newTime->setTimezone(new DateTimeZone(common_timezone()));
-            $localTime = $newTime->format('g:ia');
+            $localTime = $newTime->format("g:ia");
 
             // pretty up the end-time option list a bit
             if ($duration) {
-                $len += 30;
-                $hours    = $len / 60;
+                $hours = $len / 60;
                 switch ($hours) {
                 case 0:
                     // TRANS: 0 minutes abbreviated. Used in a list.
@@ -98,14 +93,18 @@ class EventTimeList {
                     $total = ' ' . _m('(1 hour)');
                     break;
                 default:
-                    // TRANS: Number of hours (%d). Used in a list.
-                    $total = ' ' . sprintf(_m('(%d hour)','(%d hours)',$hours), $hours);
+                    // TRANS: Number of hours (%.1f and %d). Used in a list.
+                    $format = is_float($hours) 
+                        ? _m('(%.1f hours)')
+                        : _m('(%d hours)');
+                    $total = ' ' . sprintf($format, $hours);
                     break;
                 }
                 $localTime .= $total;
+                $len += 30;
             }
 
-            $times[$utcTime] = $localTime;
+            $times[$newTime->format('g:ia')] = $localTime;
             $newTime->modify('+30min'); // 30 min intervals
         }
 
index 1bfcddba3440176f5253397baaa44a8a8a4420a7..14e3168d42b1648688a175da5224f26da259cbed 100644 (file)
@@ -101,6 +101,7 @@ class NeweventAction extends Action
             $this->location    = $this->trimmed('location');
             $this->url         = $this->trimmed('url');
             $this->description = $this->trimmed('description');
+            $tz                = $this->trimmed('tz');
 
             $startDate = $this->trimmed('startdate');
 
@@ -128,11 +129,11 @@ class NeweventAction extends Action
                 $endTime = '00:00';
             }
 
-            $start = $startDate . ' ' . $startTime;
+            $start = $startDate . ' ' . $startTime . ' ' . $tz;
 
             common_debug("Event start: '$start'");
 
-            $end = $endDate . ' ' . $endTime;
+            $end = $endDate . ' ' . $endTime . ' ' . $tz;
 
             common_debug("Event start: '$end'");