@@ -7780,7 +7780,8 @@ function rcube_webmail() {
77807780 // on the list when dragging starts (and stops), this is slow, but
77817781 // I didn't find a method to check droptarget on over event
77827782 accept : function ( node ) {
7783- if ( ! node . is ( '.mailbox' ) ) {
7783+ // Break on .is-being-sorted to enable sorting.
7784+ if ( ! node . is ( '.mailbox' ) || node . is ( '.is-being-sorted' ) ) {
77847785 return false ;
77857786 }
77867787
@@ -7798,8 +7799,49 @@ function rcube_webmail() {
77987799 dest = ref . folder_id2name ( this . id ) ;
77997800
78007801 ref . subscription_move_folder ( source , dest ) ;
7802+ ref . make_folder_lists_sortable ( ) ;
78017803 } ,
78027804 } ) ;
7805+
7806+ this . make_folder_lists_sortable ( ) ;
7807+ } ;
7808+
7809+ this . make_folder_lists_sortable = ( ) => {
7810+ var sortableHandle = $ ( '<div>' ) . addClass ( 'sortable-handle' ) ;
7811+ // Destroy and re-create all sortable lists because this gets called in scenarios, in which new lists might
7812+ // exist (e.g. if a folder was moved into another one that previously didn't have child-folders).
7813+ $ ( 'ul.ui-sortable' ) . sortable ( 'destroy' ) ;
7814+ // (Re-)Add handle icons to every sortable folder.
7815+ $ ( '.sortable-handle' ) . remove ( ) ;
7816+ $ ( 'li.mailbox:not(.protected) > .custom-switch' , this . subscription_list . container ) . prepend ( sortableHandle ) ;
7817+ // (Re-)create the sorting.
7818+ $ ( this . subscription_list . container ) . parent ( ) . find ( 'ul' ) . each ( ( _i , el ) => {
7819+ $ ( el ) . sortable ( {
7820+ axis : 'y' ,
7821+ containment : 'parent' ,
7822+ items : '> li.mailbox:not(.protected)' ,
7823+ handle : '.sortable-handle' ,
7824+ update : ( ) => this . save_reordered_folder_list ( ) ,
7825+ // Add/remove a marker to disable dropping on other elements during sorting (see accept() of droppable).
7826+ start : ( _ev , ui ) => ui . item . addClass ( 'is-being-sorted' ) ,
7827+ stop : ( _ev , ui ) => ui . item . removeClass ( 'is-being-sorted' ) ,
7828+ } ) ;
7829+ } ) ;
7830+ } ;
7831+
7832+ this . save_reordered_folder_list = ( ) => {
7833+ const mainList = ref . subscription_list . container . sortable ( 'toArray' ) ;
7834+ const subLists = ref . subscription_list . container . find ( '.ui-sortable' ) . map ( ( i , elem ) => ( {
7835+ parentId : elem . parentElement . id ,
7836+ elems : $ ( elem ) . sortable ( 'toArray' ) ,
7837+ } ) ) . toArray ( ) ;
7838+ // Sort sub-lists after their their parent element, so the sorting for the settings page doesn't get confused
7839+ // (which will hook child-folders onto wrong parents if we don't do this).
7840+ subLists . forEach ( ( subList ) => {
7841+ mainList . splice ( mainList . indexOf ( subList . parentId ) + 1 , 0 , ...subList . elems ) ;
7842+ } ) ;
7843+ params = mainList . map ( ( e ) => e . replace ( / ^ r c m l i / , 'folderorder[]=' ) ) . join ( '&' ) ;
7844+ this . http_post ( 'folder-reorder' , params , this . display_message ( '' , 'loading' ) ) ;
78037845 } ;
78047846
78057847 this . folder_id2name = function ( id ) {
@@ -7855,7 +7897,7 @@ function rcube_webmail() {
78557897 } ;
78567898
78577899 // Add folder row to the table and initialize it
7858- this . add_folder_row = function ( id , name , display_name , is_protected , subscribed , class_name , refrow , subfolders ) {
7900+ this . add_folder_row = function ( id , name , display_name , is_protected , subscribed , class_name , refrow , subfolders , insert_before_elem ) {
78597901 if ( ! this . gui_objects . subscriptionlist ) {
78607902 return false ;
78617903 }
@@ -7993,7 +8035,11 @@ function rcube_webmail() {
79938035 }
79948036 }
79958037
7996- if ( parent && n == parent ) {
8038+ if ( insert_before_elem && $ ( insert_before_elem ) . parents ( 'li' ) [ 0 ] === parent ) {
8039+ // In this case we theoretically could have skipped the sorting above, but trying to do that resulted in
8040+ // strange side effects, so I kept the code in.
8041+ $ ( insert_before_elem ) . before ( row ) ;
8042+ } else if ( parent && n == parent ) {
79978043 $ ( 'ul' , parent ) . first ( ) . append ( row ) ;
79988044 } else {
79998045 while ( p = $ ( n ) . parent ( ) . parent ( ) . get ( 0 ) ) {
@@ -8034,6 +8080,8 @@ function rcube_webmail() {
80348080 this . triggerEvent ( 'clonerow' , { row : row , id : id } ) ;
80358081 }
80368082
8083+ this . make_folder_lists_sortable ( ) ;
8084+
80378085 return row ;
80388086 } ;
80398087
@@ -8082,6 +8130,12 @@ function rcube_webmail() {
80828130 delete ref . env . subscriptionrows [ fname ] ;
80838131 } ) ;
80848132
8133+ if ( this . env . folder_ordered_manually ) {
8134+ // We need to store this information now, because it's not available anymore after removing the row from
8135+ // the DOM.
8136+ next_sibling = row . nextElementSibling ;
8137+ }
8138+
80858139 // get row off the list
80868140 row = $ ( row ) . detach ( ) ;
80878141
@@ -8093,7 +8147,11 @@ function rcube_webmail() {
80938147 }
80948148
80958149 // move the existing table row
8096- this . add_folder_row ( id , name , display_name , is_protected , subscribed , class_name , row , subfolders ) ;
8150+ this . add_folder_row ( id , name , display_name , is_protected , subscribed , class_name , row , subfolders , next_sibling ) ;
8151+
8152+ if ( this . env . folder_ordered_manually ) {
8153+ this . save_reordered_folder_list ( ) ;
8154+ }
80978155 } ;
80988156
80998157 // remove the table row of a specific mailbox from the table
0 commit comments