Support basic swipe gestures in Pholio

Summary:
Ref 2700. No sexy animation yet, but allows you to swipe left and right to switch photos. Generally feels pretty good to me.

Also fixes a left/right but and a bug where taps could be interpreted as gestures and simplifies some touch code.

derpdog

Test Plan:
Swiped left and right in Pholio.

{F35239}

Reviewers: chad

Reviewed By: chad

CC: aran

Differential Revision: https://secure.phabricator.com/D5309
This commit is contained in:
epriestley 2013-03-09 13:53:32 -08:00
parent 6b5204dca9
commit cd5038e973
5 changed files with 87 additions and 60 deletions

View file

@ -1750,7 +1750,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-phabricator-gesture' => 'javelin-behavior-phabricator-gesture' =>
array( array(
'uri' => '/res/1222d486/rsrc/js/application/core/behavior-gesture.js', 'uri' => '/res/f186161c/rsrc/js/application/core/behavior-gesture.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -1963,7 +1963,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-pholio-mock-view' => 'javelin-behavior-pholio-mock-view' =>
array( array(
'uri' => '/res/6b8ca4e4/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 'uri' => '/res/c0f94452/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -3313,7 +3313,7 @@ celerity_register_resource_map(array(
), ),
'pholio-css' => 'pholio-css' =>
array( array(
'uri' => '/res/4535277b/rsrc/css/application/pholio/pholio.css', 'uri' => '/res/bc10bf21/rsrc/css/application/pholio/pholio.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -3576,7 +3576,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/fdd3bb5f/core.pkg.css', 'uri' => '/res/pkg/fdd3bb5f/core.pkg.css',
'type' => 'css', 'type' => 'css',
), ),
'9abfe389' => '95ceba95' =>
array( array(
'name' => 'core.pkg.js', 'name' => 'core.pkg.js',
'symbols' => 'symbols' =>
@ -3617,7 +3617,7 @@ celerity_register_resource_map(array(
33 => 'javelin-behavior-global-drag-and-drop', 33 => 'javelin-behavior-global-drag-and-drop',
34 => 'javelin-behavior-phabricator-reveal-content', 34 => 'javelin-behavior-phabricator-reveal-content',
), ),
'uri' => '/res/pkg/9abfe389/core.pkg.js', 'uri' => '/res/pkg/95ceba95/core.pkg.js',
'type' => 'js', 'type' => 'js',
), ),
'dca4a03d' => 'dca4a03d' =>
@ -3790,17 +3790,17 @@ celerity_register_resource_map(array(
'diffusion-icons-css' => 'c8ce2d88', 'diffusion-icons-css' => 'c8ce2d88',
'global-drag-and-drop-css' => 'fdd3bb5f', 'global-drag-and-drop-css' => 'fdd3bb5f',
'inline-comment-summary-css' => '8aaacd1b', 'inline-comment-summary-css' => '8aaacd1b',
'javelin-aphlict' => '9abfe389', 'javelin-aphlict' => '95ceba95',
'javelin-behavior' => 'cd1d650a', 'javelin-behavior' => 'cd1d650a',
'javelin-behavior-aphlict-dropdown' => '9abfe389', 'javelin-behavior-aphlict-dropdown' => '95ceba95',
'javelin-behavior-aphlict-listen' => '9abfe389', 'javelin-behavior-aphlict-listen' => '95ceba95',
'javelin-behavior-aphront-basic-tokenizer' => '9abfe389', 'javelin-behavior-aphront-basic-tokenizer' => '95ceba95',
'javelin-behavior-aphront-drag-and-drop' => '322728f3', 'javelin-behavior-aphront-drag-and-drop' => '322728f3',
'javelin-behavior-aphront-drag-and-drop-textarea' => '322728f3', 'javelin-behavior-aphront-drag-and-drop-textarea' => '322728f3',
'javelin-behavior-aphront-form-disable-on-submit' => '9abfe389', 'javelin-behavior-aphront-form-disable-on-submit' => '95ceba95',
'javelin-behavior-audit-preview' => 'f96657b8', 'javelin-behavior-audit-preview' => 'f96657b8',
'javelin-behavior-dark-console' => 'dca4a03d', 'javelin-behavior-dark-console' => 'dca4a03d',
'javelin-behavior-device' => '9abfe389', 'javelin-behavior-device' => '95ceba95',
'javelin-behavior-differential-accept-with-errors' => '322728f3', 'javelin-behavior-differential-accept-with-errors' => '322728f3',
'javelin-behavior-differential-add-reviewers-and-ccs' => '322728f3', 'javelin-behavior-differential-add-reviewers-and-ccs' => '322728f3',
'javelin-behavior-differential-comment-jump' => '322728f3', 'javelin-behavior-differential-comment-jump' => '322728f3',
@ -3816,32 +3816,32 @@ celerity_register_resource_map(array(
'javelin-behavior-diffusion-commit-graph' => 'f96657b8', 'javelin-behavior-diffusion-commit-graph' => 'f96657b8',
'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8', 'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8',
'javelin-behavior-error-log' => 'dca4a03d', 'javelin-behavior-error-log' => 'dca4a03d',
'javelin-behavior-global-drag-and-drop' => '9abfe389', 'javelin-behavior-global-drag-and-drop' => '95ceba95',
'javelin-behavior-history-install' => '9abfe389', 'javelin-behavior-history-install' => '95ceba95',
'javelin-behavior-konami' => '9abfe389', 'javelin-behavior-konami' => '95ceba95',
'javelin-behavior-lightbox-attachments' => '9abfe389', 'javelin-behavior-lightbox-attachments' => '95ceba95',
'javelin-behavior-load-blame' => '322728f3', 'javelin-behavior-load-blame' => '322728f3',
'javelin-behavior-maniphest-batch-selector' => '7707de41', 'javelin-behavior-maniphest-batch-selector' => '7707de41',
'javelin-behavior-maniphest-subpriority-editor' => '7707de41', 'javelin-behavior-maniphest-subpriority-editor' => '7707de41',
'javelin-behavior-maniphest-transaction-controls' => '7707de41', 'javelin-behavior-maniphest-transaction-controls' => '7707de41',
'javelin-behavior-maniphest-transaction-expand' => '7707de41', 'javelin-behavior-maniphest-transaction-expand' => '7707de41',
'javelin-behavior-maniphest-transaction-preview' => '7707de41', 'javelin-behavior-maniphest-transaction-preview' => '7707de41',
'javelin-behavior-phabricator-active-nav' => '9abfe389', 'javelin-behavior-phabricator-active-nav' => '95ceba95',
'javelin-behavior-phabricator-autofocus' => '9abfe389', 'javelin-behavior-phabricator-autofocus' => '95ceba95',
'javelin-behavior-phabricator-gesture' => '9abfe389', 'javelin-behavior-phabricator-gesture' => '95ceba95',
'javelin-behavior-phabricator-keyboard-shortcuts' => '9abfe389', 'javelin-behavior-phabricator-keyboard-shortcuts' => '95ceba95',
'javelin-behavior-phabricator-nav' => '9abfe389', 'javelin-behavior-phabricator-nav' => '95ceba95',
'javelin-behavior-phabricator-object-selector' => '322728f3', 'javelin-behavior-phabricator-object-selector' => '322728f3',
'javelin-behavior-phabricator-oncopy' => '9abfe389', 'javelin-behavior-phabricator-oncopy' => '95ceba95',
'javelin-behavior-phabricator-remarkup-assist' => '9abfe389', 'javelin-behavior-phabricator-remarkup-assist' => '95ceba95',
'javelin-behavior-phabricator-reveal-content' => '9abfe389', 'javelin-behavior-phabricator-reveal-content' => '95ceba95',
'javelin-behavior-phabricator-search-typeahead' => '9abfe389', 'javelin-behavior-phabricator-search-typeahead' => '95ceba95',
'javelin-behavior-phabricator-tooltips' => '9abfe389', 'javelin-behavior-phabricator-tooltips' => '95ceba95',
'javelin-behavior-phabricator-watch-anchor' => '9abfe389', 'javelin-behavior-phabricator-watch-anchor' => '95ceba95',
'javelin-behavior-refresh-csrf' => '9abfe389', 'javelin-behavior-refresh-csrf' => '95ceba95',
'javelin-behavior-repository-crossreference' => '322728f3', 'javelin-behavior-repository-crossreference' => '322728f3',
'javelin-behavior-toggle-class' => '9abfe389', 'javelin-behavior-toggle-class' => '95ceba95',
'javelin-behavior-workflow' => '9abfe389', 'javelin-behavior-workflow' => '95ceba95',
'javelin-dom' => 'cd1d650a', 'javelin-dom' => 'cd1d650a',
'javelin-event' => 'cd1d650a', 'javelin-event' => 'cd1d650a',
'javelin-install' => 'cd1d650a', 'javelin-install' => 'cd1d650a',
@ -3863,39 +3863,39 @@ celerity_register_resource_map(array(
'lightbox-attachment-css' => 'fdd3bb5f', 'lightbox-attachment-css' => 'fdd3bb5f',
'maniphest-task-summary-css' => 'eb35a026', 'maniphest-task-summary-css' => 'eb35a026',
'maniphest-transaction-detail-css' => 'eb35a026', 'maniphest-transaction-detail-css' => 'eb35a026',
'phabricator-busy' => '9abfe389', 'phabricator-busy' => '95ceba95',
'phabricator-content-source-view-css' => '8aaacd1b', 'phabricator-content-source-view-css' => '8aaacd1b',
'phabricator-core-buttons-css' => 'fdd3bb5f', 'phabricator-core-buttons-css' => 'fdd3bb5f',
'phabricator-core-css' => 'fdd3bb5f', 'phabricator-core-css' => 'fdd3bb5f',
'phabricator-crumbs-view-css' => 'fdd3bb5f', 'phabricator-crumbs-view-css' => 'fdd3bb5f',
'phabricator-directory-css' => 'fdd3bb5f', 'phabricator-directory-css' => 'fdd3bb5f',
'phabricator-drag-and-drop-file-upload' => '322728f3', 'phabricator-drag-and-drop-file-upload' => '322728f3',
'phabricator-dropdown-menu' => '9abfe389', 'phabricator-dropdown-menu' => '95ceba95',
'phabricator-file-upload' => '9abfe389', 'phabricator-file-upload' => '95ceba95',
'phabricator-filetree-view-css' => 'fdd3bb5f', 'phabricator-filetree-view-css' => 'fdd3bb5f',
'phabricator-flag-css' => 'fdd3bb5f', 'phabricator-flag-css' => 'fdd3bb5f',
'phabricator-form-view-css' => 'fdd3bb5f', 'phabricator-form-view-css' => 'fdd3bb5f',
'phabricator-header-view-css' => 'fdd3bb5f', 'phabricator-header-view-css' => 'fdd3bb5f',
'phabricator-jump-nav' => 'fdd3bb5f', 'phabricator-jump-nav' => 'fdd3bb5f',
'phabricator-keyboard-shortcut' => '9abfe389', 'phabricator-keyboard-shortcut' => '95ceba95',
'phabricator-keyboard-shortcut-manager' => '9abfe389', 'phabricator-keyboard-shortcut-manager' => '95ceba95',
'phabricator-main-menu-view' => 'fdd3bb5f', 'phabricator-main-menu-view' => 'fdd3bb5f',
'phabricator-menu-item' => '9abfe389', 'phabricator-menu-item' => '95ceba95',
'phabricator-nav-view-css' => 'fdd3bb5f', 'phabricator-nav-view-css' => 'fdd3bb5f',
'phabricator-notification' => '9abfe389', 'phabricator-notification' => '95ceba95',
'phabricator-notification-css' => 'fdd3bb5f', 'phabricator-notification-css' => 'fdd3bb5f',
'phabricator-notification-menu-css' => 'fdd3bb5f', 'phabricator-notification-menu-css' => 'fdd3bb5f',
'phabricator-object-item-list-view-css' => 'fdd3bb5f', 'phabricator-object-item-list-view-css' => 'fdd3bb5f',
'phabricator-object-selector-css' => '8aaacd1b', 'phabricator-object-selector-css' => '8aaacd1b',
'phabricator-paste-file-upload' => '9abfe389', 'phabricator-paste-file-upload' => '95ceba95',
'phabricator-prefab' => '9abfe389', 'phabricator-prefab' => '95ceba95',
'phabricator-project-tag-css' => 'eb35a026', 'phabricator-project-tag-css' => 'eb35a026',
'phabricator-remarkup-css' => 'fdd3bb5f', 'phabricator-remarkup-css' => 'fdd3bb5f',
'phabricator-shaped-request' => '322728f3', 'phabricator-shaped-request' => '322728f3',
'phabricator-side-menu-view-css' => 'fdd3bb5f', 'phabricator-side-menu-view-css' => 'fdd3bb5f',
'phabricator-standard-page-view' => 'fdd3bb5f', 'phabricator-standard-page-view' => 'fdd3bb5f',
'phabricator-textareautils' => '9abfe389', 'phabricator-textareautils' => '95ceba95',
'phabricator-tooltip' => '9abfe389', 'phabricator-tooltip' => '95ceba95',
'phabricator-transaction-view-css' => 'fdd3bb5f', 'phabricator-transaction-view-css' => 'fdd3bb5f',
'phabricator-zindex-css' => 'fdd3bb5f', 'phabricator-zindex-css' => 'fdd3bb5f',
'sprite-apps-large-css' => 'fdd3bb5f', 'sprite-apps-large-css' => 'fdd3bb5f',

View file

@ -94,7 +94,7 @@ final class PholioMockImagesView extends AphrontView {
'div', 'div',
array( array(
'id' => $panel_id, 'id' => $panel_id,
'sigil' => 'mock-panel', 'sigil' => 'mock-panel touchable',
'class' => 'pholio-mock-image-panel', 'class' => 'pholio-mock-image-panel',
), ),
$mock_wrapper); $mock_wrapper);

View file

@ -38,6 +38,25 @@
border-color: #686868; border-color: #686868;
} }
.device .pholio-mock-carousel-thumb-item {
width: 5px;
height: 5px;
padding: 0px;
border-radius: 5px;
margin: 5px 2px;
background: #383838;
border-color: #686868;
}
.device .pholio-mock-carousel-thumb-current {
background: #dfdfdf;
border-color: #ffffff;
}
.device .pholio-mock-carousel-thumb-item img {
display: none;
}
.pholio-mock-carousel-thumbnail { .pholio-mock-carousel-thumbnail {
margin: auto; margin: auto;
position: relative; position: relative;

View file

@ -20,7 +20,7 @@ JX.behavior('phabricator-gesture', function(config) {
var p1; var p1;
JX.Stratcom.listen( JX.Stratcom.listen(
['touchstart', 'mousedown'], ['touchstart', 'touchcancel', 'mousedown'],
'touchable', 'touchable',
function(e) { function(e) {
if (JX.Device.getDevice() == 'desktop') { if (JX.Device.getDevice() == 'desktop') {
@ -29,14 +29,12 @@ JX.behavior('phabricator-gesture', function(config) {
if (JX.Stratcom.pass()) { if (JX.Stratcom.pass()) {
return; return;
} }
if (target) {
if (target && e.getType() == 'touchstart') { try {
// This corresponds to a second finger touching while the first finger JX.DOM.invoke(target, 'gesture.swipe.cancel', get_swipe_data());
// is held: stop the swipe. } finally {
var event_data = get_swipe_data(); stop_swipe();
var event_target = target; }
stop_swipe();
JX.DOM.invoke(event_target, 'gesture.swipe.cancel', event_data);
return; return;
} }
@ -89,30 +87,30 @@ JX.behavior('phabricator-gesture', function(config) {
}); });
JX.Stratcom.listen( JX.Stratcom.listen(
['touchend', 'touchcancel', 'mouseup'], ['touchend', 'mouseup'],
null, null,
function(e) { function(e) {
if (!target) { if (!target) {
return; return;
} }
// NOTE: Clear the event state first so we don't keep swiping if a try {
// handler throws. if (swiping) {
var event_target = target; JX.DOM.invoke(target, 'gesture.swipe.end', get_swipe_data());
var event_data = get_swipe_data(); }
stop_swipe(); } finally {
stop_swipe();
JX.DOM.invoke(event_target, 'gesture.swipe.end', event_data); }
}); });
function get_swipe_data() { function get_swipe_data() {
var dir = (p1.x > p0.x) ? 'left' : 'right'; var direction = (p1.x > p0.x) ? 'right' : 'left';
var length = Math.abs(p1.x - p0.x); var length = Math.abs(p1.x - p0.x);
return { return {
p0: p0, p0: p0,
p1: p1, p1: p1,
dir: dir, direction: direction,
length: length length: length
}; };
} }

View file

@ -598,6 +598,16 @@ JX.behavior('pholio-mock-view', function(config) {
}) })
.register(); .register();
JX.DOM.listen(panel, 'gesture.swipe.end', null, function(e) {
var data = e.getData();
if (data.length <= (JX.Vector.getDim(panel) / 2)) {
// If the user didn't move their finger far enough, don't switch.
return;
}
switch_image(data.direction == 'right' ? -1 : 1);
});
/* -( Render )------------------------------------------------------------- */ /* -( Render )------------------------------------------------------------- */