@@ -398,6 +398,9 @@ webui.SideBarView = function(mainView) {
398398 '<section id="sidebar-workspace">' +
399399 '<h4>Workspace</h4>' +
400400 '</section>' +
401+ '<section id="sidebar-stash">' +
402+ '<h4>Stash</h4>' +
403+ '</section>' +
401404 '<section id="sidebar-local-branches">' +
402405 '<h4 class="mt-3">Local Branches' +
403406 '<button type="button" class="btn btn-default btn-sidebar-icon btn-add shadow-none" >' +
@@ -430,6 +433,13 @@ webui.SideBarView = function(mainView) {
430433 workspaceElement . addClass ( "active" ) ;
431434 self . mainView . workspaceView . update ( "stage" ) ;
432435 } ) ;
436+
437+ var stashElement = $ ( "#sidebar-stash h4" , self . element ) ;
438+ stashElement . click ( function ( event ) {
439+ $ ( "*" , self . element ) . removeClass ( "active" ) ;
440+ stashElement . addClass ( "active" ) ;
441+ self . mainView . stashView . update ( 0 ) ;
442+ } ) ;
433443 }
434444
435445 self . fetchSection ( $ ( "#sidebar-local-branches" , self . element ) [ 0 ] , "Local Branches" , "local-branches" , "branch" ) ;
@@ -723,10 +733,168 @@ webui.LogView = function(historyView) {
723733 var streamColor = 0 ;
724734} ;
725735
736+ webui . StashView = function ( mainView ) {
737+
738+ var self = this ;
739+
740+ self . show = function ( ) {
741+ mainView . switchTo ( self . element ) ;
742+ } ;
743+
744+ self . update = function ( stashIndex ) {
745+ self . show ( ) ;
746+ self . stashListView . update ( stashIndex ) ;
747+ } ;
748+
749+ self . element = $ ( '<div id="stash-view">' ) [ 0 ] ;
750+
751+ self . stashListView = new webui . StashListView ( self ) ;
752+ self . element . appendChild ( self . stashListView . element ) ;
753+ self . commitView = new webui . StashCommitView ( self ) ;
754+ self . element . appendChild ( self . commitView . element ) ;
755+ self . mainView = mainView ;
756+ }
757+
758+ webui . StashListView = function ( stashView ) {
759+ var self = this ;
760+
761+ self . update = function ( stashIndex ) {
762+ $ ( svg ) . empty ( ) ;
763+ $ ( content ) . empty ( ) ;
764+ self . populate ( ) ;
765+ }
766+
767+ self . populate = function ( ) {
768+ webui . git ( "stash list --format='%gd::%ch::%cL::%cN::%gs'" , function ( data ) {
769+ var start = 0 ;
770+ var count = 0 ;
771+ while ( true ) {
772+ var end = data . indexOf ( "\n" , start ) ;
773+ if ( end != - 1 ) {
774+ var len = end - start ;
775+ } else {
776+ break ;
777+ }
778+ var entry = new Entry ( self , data . substring ( start , start + len ) ) ;
779+ if ( start == 0 ) {
780+ entry . select ( ) ;
781+ }
782+ content . appendChild ( entry . element ) ;
783+
784+ start = end + 1 ;
785+ ++ count ;
786+ }
787+ if ( count == 0 ) {
788+ var emptyStash = $ ( '<h4 class="empty-stash">You have no stashed changes.</h4>' ) ;
789+ var emptyDiv = $ ( '<h1 class="empty-stash"> <br> </h1>' ) ;
790+ $ ( "#log-view div" ) . append ( emptyDiv ) ;
791+ $ ( "#log-view div" ) . append ( emptyStash ) ;
792+ }
793+ svg . setAttribute ( "height" , $ ( content ) . outerHeight ( ) ) ;
794+ svg . setAttribute ( "width" , $ ( content ) . outerWidth ( ) ) ;
795+ } ) ;
796+ }
797+
798+ function Entry ( stashListView , data ) {
799+ var self = this ;
800+
801+ self . abbrevMessage = function ( ) {
802+ var end = self . message . indexOf ( "\n" ) ;
803+ if ( end == - 1 ) {
804+ return self . message
805+ } else {
806+ return self . message . substring ( 0 , end ) ;
807+ }
808+ } ;
809+
810+ self . createElement = function ( ) {
811+ self . element = $ ( '<a class="log-entry list-group-item">' +
812+ '<header>' +
813+ '<h6></h6>' +
814+ '<p class="stash-list-index">' + self . stashIndex + '</p>' +
815+ '<span class="log-entry-date">' + self . date + ' </span> ' +
816+ '<span class="badge">' + self . commit + '</span>' +
817+ '</header>' +
818+ '<p class="list-group-item-text"></p>' +
819+ '</a>' ) [ 0 ] ;
820+ $ ( '<a target="_blank" href="mailto:' + self . authorEmail + '">' + self . authorName + '</a>' ) . appendTo ( $ ( "h6" , self . element ) ) ;
821+ $ ( ".list-group-item-text" , self . element ) [ 0 ] . appendChild ( document . createTextNode ( self . commitMessage ) ) ;
822+
823+ self . element . model = self ;
824+ var model = self ;
825+ $ ( self . element ) . click ( function ( event ) {
826+ model . select ( ) ;
827+ } ) ;
828+ return self . element ;
829+ } ;
830+
831+ self . select = function ( ) {
832+ if ( currentSelection != self ) {
833+ if ( currentSelection ) {
834+ $ ( currentSelection . element ) . removeClass ( "active" ) ;
835+ }
836+ $ ( self . element ) . addClass ( "active" ) ;
837+ currentSelection = self ;
838+ stashListView . stashView . commitView . update ( self ) ;
839+ }
840+ } ;
841+
842+ self . parents = [ ] ;
843+ self . message = ""
844+
845+ var pieces = data . split ( / : : | : \s / gm) ;
846+ self . stashIndex = pieces [ 0 ] . substring ( pieces [ 0 ] . indexOf ( '{' ) + 1 , pieces [ 0 ] . indexOf ( '}' ) ) ;
847+ self . date = pieces [ 1 ] ;
848+ self . authorEmail = pieces [ 2 ] ;
849+ self . authorName = pieces [ 3 ] ;
850+ self . branchName = pieces [ 4 ] ;
851+ self . commit = pieces [ 5 ] . substring ( 0 , pieces [ 5 ] . indexOf ( " " ) ) ;
852+ self . commitMessage = pieces [ 5 ] . substring ( pieces [ 5 ] . indexOf ( " " ) ) . trim ( ) ;
853+
854+ self . createElement ( ) ;
855+ } ;
856+
857+ self . element = $ ( '<div id="log-view" class="list-group"><svg xmlns="http://www.w3.org/2000/svg"></svg><div></div></div>' ) [ 0 ] ;
858+ var svg = self . element . children [ 0 ] ;
859+ var content = self . element . children [ 1 ] ;
860+ var currentSelection = null ;
861+ // var lineHeight = null;
862+ // var streams = [];
863+ // var streamColor = 0;
864+ self . stashView = stashView
865+ }
866+
867+ webui . StashCommitView = function ( stashView ) {
868+ var self = this ;
869+
870+ self . update = function ( entry ) {
871+ if ( currentCommit == entry . commit ) {
872+ // We already display the right data. No need to update.
873+ return ;
874+
875+ }
876+ currentCommit = entry . commit ;
877+ self . showDiff ( ) ;
878+ diffView . update ( "stash show -p stash@{" + entry . stashIndex + "}" ) ;
879+ } ;
880+
881+ self . showDiff = function ( ) {
882+ webui . detachChildren ( commitViewContent ) ;
883+ commitViewContent . appendChild ( diffView . element ) ;
884+ } ;
885+
886+ self . stashView = stashView ;
887+ var currentCommit = null ;
888+ self . element = $ ( '<div id="commit-view">' ) [ 0 ] ;
889+ var commitViewContent = $ ( '<div id="commit-view-content">' ) [ 0 ] ;
890+ self . element . appendChild ( commitViewContent ) ;
891+ var diffView = new webui . DiffView ( undefined , false , self , true ) ;
892+ } ;
893+
726894/*
727895 * == DiffView ================================================================
728896 */
729- webui . DiffView = function ( sideBySide , hunkSelectionAllowed , parent ) {
897+ webui . DiffView = function ( sideBySide , hunkSelectionAllowed , parent , stashedCommit ) {
730898
731899 var self = this ;
732900
@@ -1080,6 +1248,38 @@ webui.DiffView = function(sideBySide, hunkSelectionAllowed, parent) {
10801248 commitExplorerView . show ( ) ;
10811249 } ;
10821250
1251+ self . applySelectedStash = function ( ) {
1252+ if ( ! self . currentDiff ) {
1253+ return ;
1254+ }
1255+ var stashIndex = parseInt ( $ ( ".log-entry.active .stash-list-index" ) . text ( ) ) ;
1256+ webui . git ( "stash apply stash@{" + stashIndex + "}" , function ( output ) {
1257+ webui . showSuccess ( output ) ;
1258+ } ) ;
1259+ }
1260+
1261+ self . popSelectedStash = function ( ) {
1262+ if ( ! self . currentDiff ) {
1263+ return ;
1264+ }
1265+ var stashIndex = parseInt ( $ ( ".log-entry.active .stash-list-index" ) . text ( ) ) ;
1266+ webui . git ( "stash pop stash@{" + stashIndex + "}" , function ( output ) {
1267+ webui . showSuccess ( output ) ;
1268+ parent . stashView . update ( 0 ) ;
1269+ } ) ;
1270+ }
1271+
1272+ self . dropSelectedStash = function ( ) {
1273+ if ( ! self . currentDiff ) {
1274+ return ;
1275+ }
1276+ var stashIndex = parseInt ( $ ( ".log-entry.active .stash-list-index" ) . text ( ) ) ;
1277+ webui . git ( "stash drop stash@{" + stashIndex + "}" , function ( output ) {
1278+ webui . showSuccess ( output . substring ( output . indexOf ( "Dropped" ) ) ) ;
1279+ parent . stashView . update ( 0 ) ;
1280+ } ) ;
1281+ }
1282+
10831283 var html = '<div class="diff-view-container panel panel-default">' ;
10841284 if ( ! ( parent instanceof webui . CommitExplorerView ) ) {
10851285 html +=
@@ -1096,7 +1296,10 @@ webui.DiffView = function(sideBySide, hunkSelectionAllowed, parent) {
10961296 '<button type="button" class="btn btn-default diff-cancel" style="display:none">Cancel</button>' +
10971297 '<button type="button" class="btn btn-default diff-unstage" style="display:none">Unstage</button>' +
10981298 '</div>' +
1099- ( sideBySide ? '' : '<button type="button" class="btn btn-sm btn-default diff-explore">Explore</button>' ) +
1299+ ( ( sideBySide || stashedCommit ) ? '' : '<button type="button" class="btn btn-sm btn-default diff-explore">Explore</button>' ) +
1300+ ( stashedCommit ? '<button type="button" class="btn btn-sm btn-default apply-stash">Apply</button>' :'' ) +
1301+ ( stashedCommit ? '<button type="button" class="btn btn-sm btn-default pop-stash">Pop</button>' :'' ) +
1302+ ( stashedCommit ? '<button type="button" class="btn btn-sm btn-default drop-stash">Drop</button>' :'' ) +
11001303 '</div>' ;
11011304 }
11021305 html += '<div class="panel-body"></div></div>'
@@ -1135,6 +1338,9 @@ webui.DiffView = function(sideBySide, hunkSelectionAllowed, parent) {
11351338 $ ( ".diff-unstage" , self . element ) . click ( function ( ) { self . applySelection ( true , true ) ; } ) ;
11361339
11371340 $ ( ".diff-explore" , self . element ) . click ( function ( ) { self . switchToExploreView ( ) ; } ) ;
1341+ $ ( ".apply-stash" , self . element ) . click ( function ( ) { self . applySelectedStash ( ) ; } ) ;
1342+ $ ( ".pop-stash" , self . element ) . click ( function ( ) { self . popSelectedStash ( ) ; } ) ;
1343+ $ ( ".drop-stash" , self . element ) . click ( function ( ) { self . popSelectedStash ( ) ; } ) ;
11381344
11391345 self . context = 3 ;
11401346 self . complete = false ;
@@ -1820,6 +2026,35 @@ webui.ChangedFilesView = function(workspaceView, type, label) {
18202026 }
18212027 }
18222028
2029+ self . stashByAvailability = function ( ) {
2030+ prevScrollTop = fileListContainer . scrollTop ;
2031+ self . stash ( ) ;
2032+
2033+ var action = "stash" ;
2034+
2035+ var files = self . getFileList ( undefined , "D" , 1 , 0 ) ;
2036+ var rmFiles = self . getFileList ( "D" , undefined , 1 , 0 ) ;
2037+ var combinedFiles = files . concat ( rmFiles ) ;
2038+
2039+ if ( combinedFiles . length > 0 )
2040+ confirmActionForUnavailableFile ( combinedFiles , action ) ;
2041+
2042+ }
2043+
2044+ self . stash = function ( ) {
2045+ var files = self . getFileList ( undefined , "D" , 0 , 1 ) ;
2046+ var rmFiles = self . getFileList ( "D" , undefined , 0 , 1 ) ;
2047+ var combinedFiles = files + " " + rmFiles ;
2048+
2049+ console . log ( combinedFiles ) ;
2050+
2051+ if ( combinedFiles . length != 0 ) {
2052+ webui . git ( "stash push -- " + combinedFiles , function ( output ) {
2053+ webui . showSuccess ( output ) ;
2054+ } ) ;
2055+ }
2056+ }
2057+
18232058 self . getSelectedItemsCount = function ( ) {
18242059 return $ ( ".active" , fileList ) . length ;
18252060 }
@@ -1834,7 +2069,7 @@ webui.ChangedFilesView = function(workspaceView, type, label) {
18342069 '</div>' +
18352070 '</div>' ) [ 0 ] ;
18362071 if ( type == "working-copy" ) {
1837- var buttons = [ { name : "Stage" , callback : self . processByAvailability } , { name : "Cancel" , callback : self . cancelByAvailability } ] ;
2072+ var buttons = [ { name : "Stage" , callback : self . processByAvailability } , { name : "Stash" , callback : self . stash } , { name : " Cancel", callback : self . cancelByAvailability } ] ;
18382073 } else {
18392074 var buttons = [ { name : "Unstage" , callback : self . processByAvailability } ] ;
18402075 }
@@ -1939,6 +2174,7 @@ function MainUi() {
19392174 self . historyView = new webui . HistoryView ( self ) ;
19402175 if ( ! webui . viewonly ) {
19412176 self . workspaceView = new webui . WorkspaceView ( self ) ;
2177+ self . stashView = new webui . StashView ( self ) ;
19422178 }
19432179 } ) ;
19442180 } ) ;
0 commit comments