Compare commits

..

No commits in common. 'master' and 'dev_contacts' have entirely different histories.

@ -1,18 +1,6 @@
Roundcube Webmail Swipe
=======================
Version 0.3 (2020-04-27, rc-1.4.4)
=================================================
* Update command enabling after (req RC cb8c078)
Version 0.2 (2020-01-03, rc-1.4.2)
=================================================
* Better use of colours from core
Version 0.1 (2019-10-27, rc-1.4)
=================================================
* Add swipe support on contacts list
* Move swipe options to their own dialog
* Replace swipeactions with swipeoptions
* Use listoptions template container (req RC 03425d1)
* Allow menu to use select or radio buttons

@ -21,6 +21,11 @@ as a linked part of the plugin and therefore skins DO NOT fall under the
provisions of the GPL license. See the README file located in the core skins
folder for details on the skin license.
Known issues
------------
* No support in IE
* No vertical swipe in Edge, no support for `touch-action: pan-down;` CSS - [bug report](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10573036/)
Install
-------
* Place this plugin folder into plugins directory of Roundcube
@ -34,15 +39,6 @@ Supported skins
---------------
* Elastic
Supported browsers
------------------
This plugin relies on [Pointer Events][pointer] with fallback support for
[Touch Events][touch] and should work in any browser which supports either of
these, such as: Chrome, Firefox, or Safari. When used with Edge there is no
support for vertical swipe actions, this is because the browser does not
support the `touch-action: pan-down;` CSS property - [bug report][edge].
There is no support for Internet Explorer.
Configuration
-------------
To set the default actions add the following to your Roundcube config file:
@ -110,28 +106,13 @@ to dont_override:
Interaction with other plugins
------------------------------
The `swipe_actions` hook is triggered when the plugin starts up
The `swipe_actions_list` hook is triggered when listing the available actions
on the list options menu.
*Arguments:*
* list_type - the name of list the swipe actions are being performed on, e.g. messagelist, used when selecting/saving config
* actions - an array of actions for this list in the format:
```
$args['actions'] = array(
'list_name' => '*JS list object name*',
'selection_id' => '*JS element identifier e.g. UID*',
'vertical' => array(
'*action_name*' => array('label' => '*display name*'),
...
),
'horizontal' => array(
'*action_name*' => array('label' => '*display name*'),
...
)
);
```
* actions
* direction
*Return values:*
* list_type
* actions
The `swipe-action` JS event is triggered when a swipe action is performed.
@ -148,9 +129,6 @@ an action:
Note: Only 1 of callback and command need to be supplied. If no callback is
defined then the command is passed to the standard Swipe callback function.
[rcplugrepo]: https://plugins.roundcube.net/#/packages/johndoh/swipe
[rcplugrepo]: https://plugins.roundcube.net/packages/johndoh/swipe
[releases]: https://github.com/johndoh/roundcube-swipe/releases
[gpl]: https://www.gnu.org/licenses/gpl.html
[pointer]: https://caniuse.com/#feat=pointer
[touch]: https://caniuse.com/#feat=touch
[edge]: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10573036/
[gpl]: https://www.gnu.org/licenses/gpl.html

@ -5,7 +5,7 @@
"homepage": "https://github.com/johndoh/roundcube-swipe/",
"license": "GPL-3.0",
"type": "roundcube-plugin",
"version": "0.3-git",
"version": "0.1-git",
"authors": [
{
"name": "Philip Weir",
@ -13,13 +13,19 @@
"role": "Developer"
}
],
"repositories": [
{
"type": "composer",
"url": "https://plugins.roundcube.net"
}
],
"require": {
"php": ">=5.2.1",
"roundcube/plugin-installer": ">=0.1.2"
},
"extra": {
"roundcube": {
"min-version": "1.4-git"
"min-version": "1.4"
}
}
}

@ -18,8 +18,4 @@
<roundcube:object name="swipeoptionslist" type="select" direction="down" />
</div>
</div>
</div>
<script>
rcmail.swipe.container_class += ' menu';
rcmail.swipe.element = $('<ul>').addClass(rcmail.swipe.container_class).append($('<li>').append($('<a>').addClass(rcmail.swipe.button_class).append($('<span>').addClass(rcmail.swipe.label_class))));
</script>
</div>

@ -5,10 +5,6 @@
@import (reference) "../../../../skins/elastic/styles/variables";
@import (reference) "../../../../skins/elastic/styles/mixins";
// Calculate default colors from default list background color
@color-swipe-default-background: contrast(@color-layout-list-background, darken(@color-layout-list-background, 10%), lighten(@color-layout-list-background, 40%));
@color-swipe-default: contrast(@color-swipe-default-background, lighten(@color-swipe-default-background, 30%), darken(@color-swipe-default-background, 40%), 57%);
#swipe-action {
position: absolute;
display: flex;
@ -16,38 +12,54 @@
border-collapse: collapse;
&.horizontal {
background-color: @color-swipe-default-background;
color: @color-swipe-default;
background-color: lighten(@color-black, 85%);
color: lighten(@color-black, 50%);
&.swipe_active,
&.swipe_mark {
background-color: fadeout(@color-main, 85%);
color: @color-main;
}
&.swipe_danger {
background-color: @color-message-error-box-background;
color: @color-message-error;
}
&.swipe_move {
background-color: @color-message-warning-box-background;
color: @color-message-warning;
}
&.swipe_success,
&.swipe_compose {
background-color: @color-message-success-box-background;
color: @color-message-success;
}
}
&.vertical {
background-color: transparent;
color: lighten(@color-black, 70%);
top: 2em;
z-index: 1000;
color: @color-swipe-default;
}
height: 1.5em;
&.horizontal,
&.vertical > .swipe-container {
&.swipe_active,
&.swipe_mark {
background-color: @color-message-information;
color: @color-message-text;
color: @color-main;
}
&.swipe_danger {
background-color: @color-message-error;
color: @color-message-error-text;
&.swipe_move {
color: @color-message-warning;
}
&.swipe_move {
background-color: @color-message-warning;
color: @color-message-warning-text;
&.swipe_danger {
color: @color-message-error;
}
&.swipe_success,
&.swipe_compose {
background-color: @color-message-success;
color: @color-message-success-text;
color: @color-message-success;
}
}
@ -61,9 +73,22 @@
opacity: 1;
&::before {
margin: 0 .5rem;
margin: 0 .25em 0 .5em;
font-size: inherit
}
// icons not defined in .toolbarmenu
&.archive::before {
content: @fa-var-archive;
}
&.refresh::before {
content: @fa-var-sync;
}
&.reply.one::before {
content: @fa-var-reply;
}
}
&.left {
@ -72,21 +97,21 @@
.swipe-action::before {
float: right;
margin: 0 .5em 0 .25em;
}
}
&.down {
margin: 0 auto;
padding: .01rem;
background-color: @color-layout-list-background;
background-color: #fff;
border-radius: 50%;
border: 1px solid @color-swipe-default-background;
box-shadow: 0 0 10px lighten(@color-black, 75%);
.swipe-action {
&::before {
float: none;
margin: .4rem;
padding: .25rem;
padding: 0;
margin: .4em;
line-height: 1;
font-size: 1.2em;
width: auto;
@ -106,14 +131,14 @@
background-color: @color-layout-list-background;
}
.toolbar.menu a.button.swipe {
.toolbar a.button.swipe {
display: none;
}
// no support in IE
html.layout-small.touch:not(.ie),
html.layout-phone.touch:not(.ie) {
.toolbar.menu {
.toolbar {
a.button {
&.swipe {
display: inline-block;

@ -1 +1 @@
#swipe-action{position:absolute;display:flex;align-items:center;border-collapse:collapse}#swipe-action>.swipe-container.down .swipe-action>.swipe-label,.toolbar.menu a.button.swipe{display:none}#swipe-action.horizontal{background-color:#e6e6e6;color:grey}#swipe-action.vertical{top:2em;z-index:1000;color:grey}#swipe-action.horizontal.swipe_active,#swipe-action.horizontal.swipe_mark,#swipe-action.vertical>.swipe-container.swipe_active,#swipe-action.vertical>.swipe-container.swipe_mark{background-color:#37beff;color:#fff}#swipe-action.horizontal.swipe_danger,#swipe-action.vertical>.swipe-container.swipe_danger{background-color:#ff5552;color:#fff}#swipe-action.horizontal.swipe_move,#swipe-action.vertical>.swipe-container.swipe_move{background-color:#ffd452;color:#2c363a}#swipe-action.horizontal.swipe_compose,#swipe-action.horizontal.swipe_success,#swipe-action.vertical>.swipe-container.swipe_compose,#swipe-action.vertical>.swipe-container.swipe_success{background-color:#41b849;color:#fff}#swipe-action>.swipe-container{margin:0;padding:0;list-style-type:none}#swipe-action>.swipe-container .swipe-action{font-size:1.2em;opacity:1}#swipe-action>.swipe-container .swipe-action::before{margin:0 .5rem;font-size:inherit}#swipe-action>.swipe-container.left{position:absolute;right:0}#swipe-action>.swipe-container.left .swipe-action::before{float:right}#swipe-action>.swipe-container.down{margin:0 auto;padding:.01rem;background-color:#fff;border-radius:50%;border:1px solid #e6e6e6}#swipe-action>.swipe-container.down .swipe-action::before{float:none;margin:.4rem;padding:.25rem;line-height:1;font-size:1.2em;width:auto;height:auto}.swipe-active:not(#swipe-action),.swipe-active>td{background-color:#fff}html.layout-phone.touch:not(.ie) .toolbar.menu a.button.swipe,html.layout-small.touch:not(.ie) .toolbar.menu a.button.swipe{display:inline-block}html.layout-phone.touch:not(.ie) .toolbar.menu a.button.swipe:before,html.layout-small.touch:not(.ie) .toolbar.menu a.button.swipe:before{content:"\f25a"}html.edge #swipeoptionsmenu>.swipeoptions-down{display:none}
#listoptions-menu{overflow-y:auto;margin:-0.5em -1em;padding:.75em 1.25em}#listoptions-menu::-webkit-scrollbar{-webkit-appearance:none}#listoptions-menu::-webkit-scrollbar:vertical{width:.6rem}#listoptions-menu::-webkit-scrollbar:horizontal{height:.6rem}#listoptions-menu::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,0.4);border-radius:.3rem;border:2px solid #fff}#listoptions-menu>fieldset.swipe-menu{display:none;margin-top:1.5rem}#swipe-action{position:absolute;display:flex;align-items:center;border-collapse:collapse}#swipe-action.horizontal{background-color:#f1f3f4;color:#161b1d}#swipe-action.vertical{background-color:transparent;color:#c5cfd3;top:2em;height:1.5em}#swipe-action.checkmail{color:#37beff}#swipe-action.select,#swipe-action.deselect{background-color:#8b9fa7;color:#fff}#swipe-action.delete,#swipe-action.junk{background-color:#ff5552;color:#fff}#swipe-action.flagged,#swipe-action.unflagged,#swipe-action.read,#swipe-action.unread{background-color:#37beff;color:#fff}#swipe-action.forward,#swipe-action.reply,#swipe-action.replyall,#swipe-action.notjunk{background-color:#41b849;color:#fff}#swipe-action.move,#swipe-action.archive{background-color:#ffd452;color:#fff}#swipe-action>.swipe-container>.swipe-action{line-height:100%;font-size:1.2em}#swipe-action>.swipe-container>.swipe-action::before{font-size:1.25em;display:block;float:left;margin:0 .25rem 0 0;width:1.18em;height:1em;font-family:'Icons';font-style:normal;font-weight:900;text-decoration:inherit;text-align:center;speak:none;font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin:0 .25em 0 .5em}#swipe-action>.swipe-container>.swipe-action.archive::before{content:"\f187"}#swipe-action>.swipe-container>.swipe-action.checkmail::before{content:"\f021"}#swipe-action>.swipe-container>.swipe-action.delete::before{content:"\f2ed"}#swipe-action>.swipe-container>.swipe-action.flagged::before{content:"\f024"}#swipe-action>.swipe-container>.swipe-action.unflagged::before{content:"\f024";font-weight:400}#swipe-action>.swipe-container>.swipe-action.forward::before{content:"\f064"}#swipe-action>.swipe-container>.swipe-action.junk::before{content:"\f7e4"}#swipe-action>.swipe-container>.swipe-action.notjunk::before{content:"\f01c"}#swipe-action>.swipe-container>.swipe-action.move::before{content:"\f0b2"}#swipe-action>.swipe-container>.swipe-action.read::before{content:"\f111";font-weight:400}#swipe-action>.swipe-container>.swipe-action.unread::before{content:"\f111"}#swipe-action>.swipe-container>.swipe-action.reply::before{content:"\f3e5"}#swipe-action>.swipe-container>.swipe-action.replyall::before{content:"\f122"}#swipe-action>.swipe-container>.swipe-action.select::before{content:"\f14a";font-weight:400}#swipe-action>.swipe-container>.swipe-action.deselect::before{content:"\f0c8";font-weight:400}#swipe-action>.swipe-container.left{position:absolute;right:0}#swipe-action>.swipe-container.left>.swipe-action::before{float:right;margin:0 .5em 0 .25em}#swipe-action>.swipe-container.down{margin:0 auto;background-color:#fff;border-radius:50%;box-shadow:0 0 10px #d4dbde}#swipe-action>.swipe-container.down>.swipe-action::before{float:none;padding:0;margin:10px;line-height:1em}#swipe-action>.swipe-container.down>.swipe-action>.swipe-label{display:none}.swipe-active:not(#swipe-action),.swipe-active>td{background-color:#fff}

@ -4,7 +4,7 @@
* @licstart The following is the entire license notice for the
* JavaScript code in this file.
*
* Copyright (C) Philip Weir
* Copyright (C) 2018-2019 Philip Weir
*
* The JavaScript code in this page is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
@ -16,11 +16,6 @@
*/
rcube_webmail.prototype.swipe = {
container_class: 'swipe-container',
button_class: 'swipe-action',
label_class: 'swipe-label',
element: null,
position_target: function(obj, pos, transition, max_move) {
var translate = '';
@ -34,9 +29,7 @@ rcube_webmail.prototype.swipe = {
}
}
// Edge (Trident) does not support transform on <tr>s
// Roundcube 1.4 detects Edge Trident version as 537.36 see #6952
if (bw.edge && (bw.vendver < 75 || bw.vendver > 537) && $(obj).is('tr')) {
if (bw.edge && $(obj).is('tr')) { // Edge does not support transform on <tr>s
$(obj).children('td').css('transform', translate);
}
else {
@ -48,8 +41,8 @@ rcube_webmail.prototype.swipe = {
if (!props.uid)
return;
var prev_uid = rcmail.env[rcmail.env.swipe_selection_id];
rcmail.env[rcmail.env.swipe_selection_id] = props.uid;
var prev_uid = rcmail.env[rcmail.env.task == 'addressbook' ? 'cid' : 'uid'];
rcmail.env[rcmail.env.task == 'addressbook' ? 'cid' : 'uid'] = props.uid;
var type = null;
if (matches = command.match(/([a-z0-9_-]+)\/([a-z0-9-_]+)/)) {
@ -61,7 +54,8 @@ rcube_webmail.prototype.swipe = {
rcmail.mark_message(command);
}
else if (type == 'compose') {
rcmail.command(command, '', props.obj, props.originalEvent, true);
rcmail.enable_command(command, true);
rcmail.command(command, '', props.obj, props.originalEvent);
}
else if (type == 'select') {
rcmail.env.swipe_list.highlight_row(props.uid, true);
@ -78,7 +72,7 @@ rcube_webmail.prototype.swipe = {
rcmail.enable_command(command, prev_command);
}
rcmail.env[rcmail.env.swipe_selection_id] = prev_uid;
rcmail.env[rcmail.env.task == 'addressbook' ? 'cid' : 'uid'] = prev_uid;
},
select_action: function(direction, obj) {
@ -139,7 +133,7 @@ rcube_webmail.prototype.swipe = {
'command': obj && obj.hasClass('flagged') ? 'mark/unflagged' : 'mark/flagged'
},
'swipe-select': {
'class': (obj && obj.hasClass('selected') ? 'select invert' : 'selection') + ' swipe_active',
'class': (obj && obj.hasClass('selected') ? 'select invert' : 'select all') + ' swipe_active',
'text': obj && obj.hasClass('selected') ? 'swipe.deselect' : 'select',
'command': obj && obj.hasClass('selected') ? 'select/deselect' : 'select/select'
},
@ -180,30 +174,22 @@ rcube_webmail.prototype.swipe = {
'moveevent': 'pointermove',
'endevent': 'pointerup',
'cancelevent': 'pointercancel',
'minmove': 5,
'id': function(e) { return e.pointerId; },
'type': function(e) { return e.pointerType; },
'pos': function(e, x) { return e.originalEvent[ x ? 'pageX' : 'pageY']; },
'clearswipe': function(e) {
rcmail.swipe.position_target(opts[swipedata.axis].target_obj, 0);
opts[swipedata.axis].target_obj.removeClass('swipe-active');
swipedata = {};
rcmail.swipe.active = null;
// reset #swipe-action
$('#swipe-action').removeClass().hide();
$('.swipe-container').attr('class', rcmail.swipe.container_class);
$('.swipe-action').attr('class', rcmail.swipe.button_class);
rcmail.swipe.set_scroll_css();
$('.swipe-container').attr('class', rcmail.env.swipe_container_class);
$('.swipe-action').attr('class', rcmail.env.swipe_button_class);
if (opts.parent_obj)
opts.parent_obj.off(swipeevents.moveevent, rcube_event.cancel);
// restore normal scrolling on touch devices
if (swipedata.axis == 'vertical' && !bw.pointer) {
rcmail.swipe.parent.css('overflow-y', 'auto');
}
swipedata = {};
rcmail.swipe.active = null;
}
};
var swipedata = {};
@ -214,7 +200,6 @@ rcube_webmail.prototype.swipe = {
swipeevents.moveevent = 'touchmove';
swipeevents.endevent = 'touchend';
swipeevents.cancelevent = 'touchcancel';
swipeevents.minmove = 15;
swipeevents.id = function(e) { return e.changedTouches.length == 1 ? e.changedTouches[0].identifier : -1; };
swipeevents.type = function(e) { return 'touch'; };
swipeevents.pos = function(e, x) { return e.originalEvent.targetTouches[0][ x ? 'pageX' : 'pageY']; };
@ -228,7 +213,6 @@ rcube_webmail.prototype.swipe = {
swipedata.y = swipeevents.pos(e, false);
swipedata.id = swipeevents.id(e);
swipedata.scrollable = rcmail.swipe.parent[0].offsetHeight < rcmail.swipe.parent[0].scrollHeight;
swipedata.scrolltop = rcmail.swipe.parent.scrollTop();
if (opts.parent_obj)
opts.parent_obj.off(swipeevents.moveevent, rcube_event.cancel);
@ -247,7 +231,7 @@ rcube_webmail.prototype.swipe = {
changeX = opts.horizontal ? (changeX < 0 ? Math.max(opts.horizontal.maxmove * -1, changeX) : Math.min(opts.horizontal.maxmove, changeX)) : 0;
// use Math.abs() to ensure value is always a positive number
var min_move = swipeevents.minmove; // the minimum amount of pointer movement required to trigger the swipe
var min_move = 5; // the minimum amount of pointer movement required to trigger the swipe
var temp_axis;
if (opts.vertical && (Math.abs(changeY) > min_move || opts.vertical.target_obj.hasClass('swipe-active'))) {
temp_axis = 'vertical';
@ -265,17 +249,14 @@ rcube_webmail.prototype.swipe = {
// do not interfere with normal list scrolling
if (temp_axis == 'vertical' && rcmail.swipe.parent.scrollTop() != 0) {
if (swipedata.scrollable)
rcmail.swipe.set_scroll_css();
if (bw.pointer && swipedata.scrollable)
rcmail.swipe.parent.css('touch-action', 'pan-y');
if (swipedata.axis)
swipeevents.clearswipe(e);
return;
}
else if (temp_axis == 'horizontal' && !bw.pointer && swipedata.scrolltop != rcmail.swipe.parent.scrollTop()) {
return;
}
// save the axis info
swipedata.axis = temp_axis;
@ -287,8 +268,8 @@ rcube_webmail.prototype.swipe = {
return;
$('#swipe-action').attr('class', temp_axis).data('callback', action.callback);
$('.swipe-container').attr('class', rcmail.swipe.container_class + ' ' + direction);
$('.swipe-action').attr('class', rcmail.swipe.button_class + ' ' + action.class);
$('.swipe-container').attr('class', rcmail.env.swipe_container_class + ' ' + direction);
$('.swipe-action').attr('class', rcmail.env.swipe_button_class + ' ' + action.class);
$('.swipe-label').text(rcmail.gettext(action.text));
if (!opts[swipedata.axis].target_obj.hasClass('swipe-active')) {
@ -304,21 +285,17 @@ rcube_webmail.prototype.swipe = {
if (opts.parent_obj)
opts.parent_obj.on(swipeevents.moveevent, rcube_event.cancel);
// prevent up scroll when vertical active on touch devices
if (rcmail.swipe.active == 'vertical' && !bw.pointer && changeY > 0)
rcmail.swipe.parent.css('overflow-y', 'hidden');
}
// the user must swipe a certain about before the action is activated, try to prevent accidental actions
// do not activate if there is no callback
if (((swipedata.axis == 'vertical' && changeY > opts[swipedata.axis].minmove) ||
(swipedata.axis == 'horizontal' && (changeX < (opts[swipedata.axis].minmove * -1) || changeX > opts[swipedata.axis].minmove))) && action.callback) {
$('#swipe-action.horizontal,#swipe-action.vertical > .swipe-container').addClass(action.class);
$('#swipe-action').addClass(action.class);
}
else {
// reset the swipe if the user takes the row back to the start
$('#swipe-action.horizontal,#swipe-action.vertical > .swipe-container').removeClass(action.class);
$('#swipe-action').removeClass(action.class);
$('#swipe-action').data('callback', null);
}
@ -339,31 +316,25 @@ rcube_webmail.prototype.swipe = {
if (swipedata.axis)
swipeevents.clearswipe(e);
});
},
set_scroll_css: function() {
// Edge (Trident) does not support pan-down, only pan-y
if (bw.pointer && rcmail.swipe.parent.scrollTop() == 0 && !(bw.edge && bw.vendver < 75)) {
// allow vertical pointer events to fire (if one is configured)
var action = rcmail.swipe.select_action('down');
rcmail.swipe.parent.css('touch-action', action.callback ? 'pan-down' : 'pan-y');
}
else {
rcmail.swipe.parent.css('touch-action', 'pan-y');
}
}
};
$(document).ready(function() {
if (window.rcmail && ((bw.touch && !bw.ie) || bw.pointer)) {
rcmail.addEventListener('init', function() {
rcmail.env.swipe_list = rcmail[rcmail.env.swipe_list_name];
rcmail.env.swipe_list = rcmail.task == 'addressbook' ? rcmail.contact_list : rcmail.message_list;
rcmail.env.swipe_menuname = 'messagelistmenu';
rcmail.env.swipe_container_class = 'swipe-container toolbarmenu';
rcmail.env.swipe_button_class = 'swipe-action';
var list_container = $(rcmail.env.swipe_list.list).parent();
if (rcmail.env.swipe_list.draggable || !list_container[0].addEventListener)
return;
var swipe_action = $('<div>').attr('id', 'swipe-action').append(rcmail.swipe.element);
// minic toolbarmenu structure to pickup CSS from core
var swipe_action = $('<div>').attr('id', 'swipe-action').append(
$('<ul>').addClass(rcmail.env.swipe_container_class).append($('<li>').append($('<a>').addClass(rcmail.env.swipe_button_class).append($('<span>').addClass('swipe-label'))))
);
rcmail.swipe.parent = list_container;
rcmail.swipe.parent.prepend(swipe_action.hide());
@ -434,14 +405,27 @@ $(document).ready(function() {
rcmail.swipe.init(swipe_config);
// prevent accidental list scroll when swipe active
rcmail.swipe.parent.on('scroll', function() { rcmail.swipe.set_scroll_css(); }).trigger('scroll');
rcmail.env.swipe_list.addEventListener('getselection', function(p) {
if (rcmail.swipe.active && rcmail.env[rcmail.env.swipe_selection_id]) {
p.res = [rcmail.env[rcmail.env.swipe_selection_id]];
return false;
rcmail.swipe.parent.on('scroll', function() {
if (!bw.pointer) {
if (rcmail.swipe.active)
return false;
}
});
else if ($(this).scrollTop() == 0) {
// allow vertical pointer events to fire (if one is configured)
var action = rcmail.swipe.select_action('down');
// Edge does not support pan-down, only pan-y
rcmail.swipe.parent.css('touch-action', action.callback && ! bw.edge ? 'pan-down' : 'pan-y');
}
}).trigger('scroll');
if (rcmail.env.task == 'addressbook') {
rcmail.contact_list.addEventListener('getselection', function(p) {
if ($('.swipe-active').length == 1 && rcmail.env.cid) {
p.res = [rcmail.env.cid];
return false;
}
});
}
});
// right/left/down swipe on list
@ -462,7 +446,7 @@ $(document).ready(function() {
'transition': 'translatex',
'action_sytle': function(o) {
return {
'top': o.position().top + (bw.mz ? rcmail.swipe.parent.scrollTop() : 0),
'top': o.position().top,
'left': o.position().left,
'width': o.width() + 'px',
'height': (o.height() - 2) + 'px' // subtract the border

@ -7,7 +7,7 @@
*
* @author Philip Weir
*
* Copyright (C) Philip Weir
* Copyright (C) 2018-2019 Philip Weir
*
* This program is a Roundcube (https://roundcube.net) plugin.
* For more information see README.md.
@ -27,7 +27,7 @@
*/
class swipe extends rcube_plugin
{
public $task = '^((?!login).)*$';
public $task = 'mail|addressbook';
private $menu_file = null;
private $dont_override = array();
private $disabled_actions = array();
@ -35,8 +35,6 @@ class swipe extends rcube_plugin
private $config = array();
private $actions = array(
'messagelist' => array(
'list_name' => 'message_list',
'selection_id' => 'uid',
'vertical' => array(
'checkmail' => array('label' => 'checkmail')
),
@ -54,8 +52,6 @@ class swipe extends rcube_plugin
)
),
'contactlist' => array(
'list_name' => 'contact_list',
'selection_id' => 'cid',
'vertical' => array(),
'horizontal' => array(
'vcard_attachments' => array('label' => 'vcard_attachments.forwardvcard', 'plugin' => true),
@ -63,8 +59,7 @@ class swipe extends rcube_plugin
'delete' => array('label' => 'delete'),
'swipe-select' => array('label' => 'select')
)
),
'none' => null
)
);
private $rcube;
private $list_type;
@ -72,19 +67,9 @@ class swipe extends rcube_plugin
public function init()
{
$this->rcube = rcube::get_instance();
$this->list_type = $this->rcube->task == 'addressbook' ? 'contactlist' : 'messagelist';
$this->add_texts('localization/');
switch ($this->rcube->task) {
case 'addressbook':
$this->list_type = 'contactlist';
break;
case 'mail':
$this->list_type = 'messagelist';
break;
default:
$this->list_type = 'none';
}
$this->add_hook('ready', array($this, 'setup'));
$this->register_action('plugin.swipe.save_settings', array($this, 'save_settings'));
}
@ -100,47 +85,35 @@ class swipe extends rcube_plugin
$this->menu_file = '/' . $this->local_skin_path() . '/includes/menu.html';
$filepath = slashify($this->home) . $this->menu_file;
if (is_file($filepath) && is_readable($filepath)) {
// Allow other plugins to interact with the actions list
$data = rcube::get_instance()->plugins->exec_hook('swipe_actions', array('list_type' => $this->list_type, 'actions' => $this->actions[$this->list_type]));
$this->list_type = $data['list_type'];
$this->actions[$this->list_type] = $data['actions'];
if (empty($this->actions[$this->list_type])) {
// no swipe actions found, disable the plugin
return;
}
$config = $this->config[$this->list_type];
$this->rcube->output->set_env('swipe_actions', array(
'left' => $config['left'],
'right' => $config['right'],
'down' => $config['down']
));
$this->rcube->output->set_env('swipe_list_name', $this->actions[$this->list_type]['list_name']);
$this->rcube->output->set_env('swipe_selection_id', $this->actions[$this->list_type]['selection_id']);
$this->include_stylesheet($this->local_skin_path() . '/swipe.css');
$this->include_script('swipe.js');
$this->rcube->output->add_label('swipe.swipeoptions', 'swipe.markasflagged', 'swipe.markasunflagged', 'swipe.markasread',
'swipe.markasunread', 'refresh', 'moveto', 'reply', 'replyall', 'forward', 'select', 'swipe.deselect', 'compose');
$this->rcube->output->add_handler('swipeoptionslist', array($this, 'options_list'));
}
if ($this->_allowed_action('*')) {
// add swipe actions link to the menu
$this->add_button(array(
'command' => 'plugin.swipe.options',
'type' => 'link',
'class' => 'button swipe disabled',
'classact' => 'button swipe',
'title' => 'swipe.swipeoptions',
'innerclass' => 'inner',
'label' => 'swipe.swipeoptions'
), 'listcontrols');
// add swipe actions popup menu
$this->rcube->output->add_handler('swipeoptionslist', array($this, 'options_list'));
$html = $this->rcube->output->just_parse("<roundcube:include file=\"$this->menu_file\" skinpath=\"plugins/swipe\" />");
$this->rcube->output->add_footer($html);
}
if ($this->_allowed_action('*')) {
// add swipe actions link to the menu
$this->add_button(array(
'command' => 'plugin.swipe.options',
'type' => 'link',
'class' => 'button swipe disabled',
'classact' => 'button swipe',
'title' => 'swipe.swipeoptions',
'innerclass' => 'inner',
'label' => 'swipe.swipeoptions'
), 'listcontrols');
// add swipe actions popup menu
$html = $this->rcube->output->just_parse("<roundcube:include file=\"$this->menu_file\" skinpath=\"plugins/swipe\" />");
$this->rcube->output->add_footer($html);
}
}
@ -151,8 +124,11 @@ class swipe extends rcube_plugin
$args['id'] = 'swipeoptions-' . $args['direction'];
$args['name'] = 'swipe_' . $args['direction'];
// Allow other plugins to interact with the action list
$data = rcube::get_instance()->plugins->exec_hook('swipe_actions_list', array('actions' => $swipe_actions, 'direction' => $args['direction']));
$options = array();
foreach ($swipe_actions as $action => $info) {
foreach ($data['actions'] as $action => $info) {
if (!$this->_allowed_action($args['direction'], $action, $info)) {
continue;
}
@ -162,7 +138,7 @@ class swipe extends rcube_plugin
asort($options);
// don't add none if there are no available actions, JS detects empty lists and hides the option
if (!empty($options)) {
if (count($options) > 0) {
$options = array('none' => $this->gettext('none')) + $options;
}
@ -192,10 +168,6 @@ class swipe extends rcube_plugin
{
$this->_load_config();
// Allow other plugins to interact with the actions list
$data = rcube::get_instance()->plugins->exec_hook('swipe_actions', array('list_type' => $this->list_type, 'actions' => $this->actions[$this->list_type]));
$this->list_type = $data['list_type'];
$save = false;
foreach (array('left', 'right', 'down') as $direction) {
if (($prop = rcube_utils::get_input_value('swipe_' . $direction, rcube_utils::INPUT_POST)) && $this->_allowed_action($direction)) {
@ -217,9 +189,7 @@ class swipe extends rcube_plugin
// initialize internal config
foreach (array_keys($this->actions) as $list) {
if ($list != 'none') {
$this->config[$list] = array('left' => 'none', 'right' => 'none', 'down' => 'none');
}
$this->config[$list] = array('left' => 'none', 'right' => 'none', 'down' => 'none');
}
// get user config
@ -248,10 +218,10 @@ class swipe extends rcube_plugin
in_array('swipe_actions.' . $this->list_type . '.' . $direction, $this->dont_override)) {
$result = false;
}
elseif (in_array($action, $this->disabled_actions) || in_array($this->rcube->task . $action, $this->disabled_actions)) {
else if (in_array($action, $this->disabled_actions) || in_array($this->rcube->task . $action, $this->disabled_actions)) {
$result = false;
}
elseif (isset($opts['plugin']) && !in_array($action, $this->laoded_plugins)) {
else if (isset($opts['plugin']) && !in_array($action, $this->laoded_plugins)) {
// check plugin is enabled
$result = false;
}

Loading…
Cancel
Save