本教程是 Envato Tuts +上的“ 使用PHP构建启动”系列 的一部分。 在本系列文章中,我 将以 我的 Meeting Planner 应用程序作为真实示例 ,指导您完成从概念到现实的启动 。 在此过程的每一步中,我都会将Meeting Planner代码作为开放源代码示例发布,您可以从中学习。 我还将解决与启动相关的业务问题。
计划需要时区
对于Meeting Planner的Alpha版本,我为人们提供了在用户设置中更改其时区的机会。 但是,对于美国西部以外的任何人,他们可能一直想知道为什么他们的日历约会在错误的时间进行。 您必须知道要查找设置页面。
当我接近测试版时,我意识到我需要尽快修复它。 因此,我开始思考如何最好地解决此问题。
在今天的一集中,我将向您介绍自动时区检测的方法以及如何将其集成到用户体验中。
如果还没有,请立即安排您的第一次会议 ,以试用Meeting Planner。 如果您不在“太平洋标准时间”区域内,则可能会看到有关更新时区的提示,如下所述。 请在下面的评论中发布您对体验的反馈。
我确实参与了评论主题,但您也可以在Twitter上与我联系@reifman 。 我总是乐于接受新功能的想法和主题建议,以供将来的教程使用。
提醒一下,Meeting Planner的所有代码都是在PHP的Yii2框架中编写的。 如果您想了解有关Yii2的更多信息,请查看我的平行系列“ 使用Yii2编程” 。 我开发会议计划者的时间越长,对Yii2及其志愿者团队的印象就越深刻。
研究时区检测
当前设置页面允许用户选择时区。 我整理了一个屏幕快照,显示了您单击下拉菜单时出现的所选时区的一部分; 有很多:
这似乎工作良好,但用户不一定会找到它。 实际上,他们无法知道它们是否与我们的服务器位于同一时区。
首先,我研究了一些时区地图选择器,以查看它们是否可以轻松回答。 我发现有两个名称基本相同: Timezone picker :
和quicksketch / timezonepicker:一个基于jQuery和ImageMap的时区选择器 。 虽然我赞赏图形选择器,但它们在移动设备上无法很好地工作,并且没有提供检测功能。
我发现了一个名为Yii2的扩展,称为“ 时区检测器” ,但尚不清楚它如何确定时区以及它的可靠性。
最终,我使用了一个名为jsTimezoneDetect的基本JavaScript解决方案; 您可以在下面看到演示页面 :
它依赖于平台或设备的时区设置,而不是使用可能会被公司网络,ISP和VPN误导的地理位置IP。 它速度很快,提高了准确性。
设计用户体验
我的目标是检测用户的时区,并允许他们快速更新设置,而不会分散注意力。 我最关心的是用户设置他们的时区是在他们将会议时间添加到新会议中时。
例如,当他们单击“开会时间”旁边的加号图标 时 :
例如,如果我住在加拿大多伦多东部时区,并访问会议计划者,则其默认设置为PST,比我晚三小时。 所以我晚上7:30之前的会议时间不正确。
现在,如果jsTimezoneDetect
确定您jsTimezoneDetect
时区(例如多伦多)与您当前的用户设置(例如洛杉矶)不在同一个时区,它将询问您是否要更改它:
在上面的屏幕截图中,我使用了MacOS的日期和时间首选项 (右上)从当前的会议计划器设置更改了时区,并允许我测试更改它的时间。
时区更新后,较早的时间选择将显示在东海岸时间:
但是,下次您添加会议时间时,它将在您正确的时区中。
简化体验
我不希望用户必须跳到设置页面进行更改,而又不想在计划会议时失去位置。 因此,尽管花费了一些时间,但我编写了一些AJAX,该AJAX会从此页面更新他们的时区,以便他们可以继续进行计划。
在下面,您可以看到单击新时区后,状态会提醒您它已更新,您可以继续添加会议时间而不会失去位置:
开发代码集成
为此,我开始研究上面的frontend / views / meeting-time / _form.php。 首先,我添加了JavaScript以检测时区并管理警报:
<?php ActiveForm::end();
$this->registerJsFile(MiscHelpers::buildUrl().'/js/jstz.min.js',['depends' => [\yii\web\JqueryAsset::className()]]);
$this->registerJsFile(MiscHelpers::buildUrl().'/js/meeting_time.js',['depends' => [\yii\web\JqueryAsset::className()]]);
?>
我还创建了一些隐藏的表单变量来支持脚本:
<?php $form = ActiveForm::begin();?>
<?= BaseHtml::activeHiddenInput($model, 'url_prefix',['value'=>\common\components\MiscHelpers::getUrlPrefix(),'id'=>'url_prefix']); ?>
<?= BaseHtml::activeHiddenInput($model, 'tz_dynamic',['id'=>'tz_dynamic']); ?>
<?= BaseHtml::activeHiddenInput($model, 'tz_current',['id'=>'tz_current']); ?>
url_prefix
可帮助管理开发和生产环境之间JavaScript寻址。 tz_current
从MeetingTimeController.php加载。 这是会议计划器中用户的当前时区设置。 tz_dynamic
将由我们的检测脚本填写。
我还在表单顶部创建了两个警报框,默认情况下会使用其IDCSS定义将其隐藏:
<div class="tz_success" id="tz_success">
<div id="w4-tz-success" class="alert-success alert fade in">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<?= Yii::t('frontend','Your timezone has been updated successfully.') ?>
</div>
</div>
<div class="tz_warning" id="tz_alert">
<div id="w4-tz-info" class="alert-info alert fade in">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<?= Yii::t('frontend','Would you like us to change your timezone setting to <span id="tz_new"></span>?') ?>
</div>
</div>
如果检测到的时区与您当前的设置不同, tz_alert
出现tz_alert
。 如果更改时区, tz_success
出现tz_success
。
还要注意空的span标签:
...change your timezone setting to <span id="tz_new"></span>?') ?>
该脚本将在其中放置tz_detect
的AJAX链接,您将在我们的脚本中看到该链接。
这是来自frontend / web / js / meeting_time.js的摘录:
$(document).ready(function(){
// detect user timezone
var tz = jstz.determine(); // Determines the time zone of the browser client
var timezone = tz.name(); //e.g. 'Asia/Kolhata'
$('#tz_dynamic').val(timezone);
// compare to current setting
if (timezone != $('#tz_current').val()) {
// set the text span alert
$('#tz_new').html('<a onclick="setTimezone(\''+timezone+'\')" href="javascript:void(0);">'+timezone+'</a>');
$('#tz_alert').show();
}
});
function setTimezone(timezone) {
$.ajax({
url: $('#url_prefix').val()+'/user-setting/timezone',
data: {'timezone': timezone},
success: function(data) {
$('#tz_alert').hide();
$('#tz_success').show();
return true;
}
});
}
在上面的$(document).ready()
函数中,它调用jsTimezoneDetect()
并检查用户的当前时区是否不同。 如果是,它将用指向setTimezone()
JavaScript链接替换空的span标记,并显示警告框。
setTimezone
函数对UserSettingController.php进行AJAX调用:
public function actionTimezone($timezone) {
// set current logged in user timezone than return
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$user_id = Yii::$app->user->getId();
UserSetting::setUserTimezone($user_id,$timezone);
return true;
}
它可以无缝更新时区设置,而无需访问设置页面。
然后,JavaScript关闭警报并显示成功框。
与PHP相比,JavaScript和AJAX花费的时间总是更多,但是UX在此功能下的确运行良好。
我发现在所有测试中, jsTimezoneDetect
都是快速且完全准确的。
将代码应用于设置页面
我决定将此友好的检测应用于“设置”页面,因此用户不一定需要单击下拉列表并在数十个时区中滑动。
如果他们单击检测到的时区链接,则会显示已成功保存警报,并在本地时区下拉列表中为他们进行设置。 实际上,无需提交表格。
为了实现这一点,我为frontend / web / js / user_setting.js创建了几乎相同JavaScript文件:
$(document).ready(function(){
// detect user timezone
var tz = jstz.determine(); // Determines the time zone of the browser client
var timezone = tz.name(); //e.g. 'Asia/Kolhata'
$('#tz_dynamic').val(timezone);
// compare to current setting
if (timezone != $('#tz_combo').val()) {
// set the text span alert
$('#tz_new').html('<a onclick="setTimezone(\''+timezone+'\')" href="javascript:void(0);">'+timezone+'</a>');
$('#tz_alert').show();
}
});
function setTimezone(timezone) {
$.ajax({
url: $('#url_prefix').val()+'/user-setting/timezone',
data: {'timezone': timezone},
success: function(data) {
$('#tz_alert').hide();
$('#tz_success').show();
$('#tz_combo').val(timezone);
return true;
}
});
}
完成后,它将使用新的时区为用户更新下拉菜单#tz_combo
值。
其他注意事项
对于所有安排第一次会议的新用户而言,所有这些功能都非常有用。 但是会议请求的接收者呢? 亲自见面的人通常位于同一时区,但是虚拟会议(例如电话会议)可能需要不同的时区。
如果您读过“将iCal文件导出到日历 ”一集,您可能还记得我们在ics文件导出中包含时区设置:
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
UID:9832@meetingplanner.io
DTSTART:20160506T013000Z
DTEND:20160506T023000Z
DTSTAMP:20160506T013000Z
ORGANIZER;CN=admin:mailto:jeff@lookahead.io
URL;VALUE=URI:http://localhost:8888/mp/index.php/meeting/command?id=45&cmd=10&actor_id=1&k=ESxJU_2ZRhZIgzHFyJAIiC39RhZuLiM_&obj_id=0
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=robsmith;X-NUM-GUESTS=0:mailto:robsmith@lookahead.me
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=admin;X-NUM-GUESTS=0:mailto:jeff@lookahead.io
CREATED:
DESCRIPTION:It was fun running into you - let's definitely grab that beer! Website: http://www.patxispizza.com/
LAST-MODIFIED:20160506T013000Z
LOCATION:Patxi's Pizza Ballard 5323 Ballard Ave NW Seattle WA 98107
SUMMARY:Meetup for Pizza and Long Delayed Conversation
SEQUENCE:0
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
这样可以确保收件人在将.ics文件导入日历时将看到与组织者相同的时区。
我们所有的会议时间都作为GMT时区中的通用Unix时间戳存储在数据库中,并且我们的显示根据每个用户的本地时区进行调整。
但是,我仍然需要将JavaScript检测添加到会议计划页面和收件人确认页面上,以确保提示他们配置时区以查看正确的会议时间。
展望未来
目前,我正在进行Meeting Planner Beta版的代码冲刺。 在确认会议后,我正在处理与更改或直接更改会议有关的许多功能。 这需要大量的概念性思考,以使人们能够更轻松地进行计划。 我很快会写更多有关此的内容。
与往常一样,请继续关注“ 使用PHP构建您的启动”系列中的本教程和更多后续教程。 您是否已经通过会议计划器安排了会议? 没有? 你在等什么? 现在做! 与往常一样,请让我知道您在下面或评论中的想法。 我很感激。 您也可以与我联系@reifman 。 我总是乐于接受新功能的想法和主题建议,以供将来的教程使用。
我还打算编写有关众筹的教程,因此请考虑关注我们的WeFunder Meeting Planner页面 。
相关链接
翻译自: https://code.tutsplus.com/tutorials/building-your-startup-automatic-timezone-detection--cms-27041