11import _ from 'lodash'
22import React from 'react'
3+ import { withRouter } from 'react-router'
34import { connect } from 'react-redux'
45import update from 'react-addons-update'
56import MessageList from '../../../components/MessageList/MessageList'
@@ -30,12 +31,30 @@ class MessagesView extends React.Component {
3031
3132 constructor ( props ) {
3233 super ( props )
33- this . state = { threads : [ ] , activeThreadId : null , showEmptyState : true , showAll : [ ] }
34+ this . state = {
35+ threads : [ ] ,
36+ activeThreadId : null ,
37+ showEmptyState : true ,
38+ showAll : [ ] ,
39+ newPost : { }
40+ }
3441 this . onThreadSelect = this . onThreadSelect . bind ( this )
3542 this . onShowAllComments = this . onShowAllComments . bind ( this )
3643 this . onAddNewMessage = this . onAddNewMessage . bind ( this )
3744 this . onNewMessageChange = this . onNewMessageChange . bind ( this )
3845 this . onNewThread = this . onNewThread . bind ( this )
46+ this . onLeave = this . onLeave . bind ( this )
47+ this . isChanged = this . isChanged . bind ( this )
48+ this . onNewPostChange = this . onNewPostChange . bind ( this )
49+ this . changeThread = this . changeThread . bind ( this )
50+ this . onNewThreadClick = this . onNewThreadClick . bind ( this )
51+ this . showNewThreadForm = this . showNewThreadForm . bind ( this )
52+ }
53+
54+ componentDidMount ( ) {
55+ const routeLeaveHook = this . props . router . setRouteLeaveHook ( this . props . route , this . onLeave )
56+ window . addEventListener ( 'beforeunload' , this . onLeave )
57+ this . setState ( { routeLeaveHook } )
3958 }
4059
4160 componentWillMount ( ) {
@@ -46,6 +65,27 @@ class MessagesView extends React.Component {
4665 this . init ( nextProps )
4766 }
4867
68+ componentWillUnmount ( ) {
69+ window . removeEventListener ( 'beforeunload' , this . onLeave )
70+ if ( this . state . routeLeaveHook ) {
71+ this . state . routeLeaveHook ( )
72+ }
73+ }
74+
75+ // Notify user if they navigate away while the form is modified.
76+ onLeave ( e ) {
77+ if ( this . isChanged ( ) ) {
78+ return e . returnValue = 'You have uposted content. Are you sure you want to leave?'
79+ }
80+ }
81+
82+ isChanged ( ) {
83+ const { newPost } = this . state
84+ const hasMessage = ! _ . isUndefined ( _ . find ( this . state . threads , ( thread ) => thread . newMessage && thread . newMessage . length ) )
85+ const hasThread = ( newPost . title && ! ! newPost . title . trim ( ) . length ) || ( newPost . content && ! ! newPost . content . trim ( ) . length )
86+ return hasThread || hasMessage
87+ }
88+
4989 mapFeed ( feed , isActive , showAll = false ) {
5090 const { allMembers } = this . props
5191 const item = _ . pick ( feed , [ 'id' , 'date' , 'read' , 'tag' , 'title' , 'totalPosts' , 'userId' , 'reference' , 'referenceId' , 'postIds' , 'isAddingComment' , 'isLoadingComments' , 'error' ] )
@@ -137,15 +177,28 @@ class MessagesView extends React.Component {
137177 }
138178
139179 onThreadSelect ( thread ) {
180+ const unsavedContentMsg = this . onLeave ( { } )
181+ if ( unsavedContentMsg ) {
182+ const changeConfirmed = confirm ( unsavedContentMsg )
183+ if ( changeConfirmed ) {
184+ this . changeThread ( thread )
185+ }
186+ } else {
187+ this . changeThread ( thread )
188+ }
189+ }
190+
191+ changeThread ( thread ) {
140192 this . setState ( {
141193 isCreateNewMessage : false ,
194+ newPost : { } ,
142195 activeThreadId : thread . id ,
143196 threads : this . state . threads . map ( ( item ) => {
144197 if ( item . isActive ) {
145198 if ( item . id === thread . id ) {
146199 return item
147200 }
148- return { ...item , isActive : false , messages : item . messages . map ( ( msg ) => ( { ...msg , unread : false } ) ) }
201+ return { ...item , isActive : false , newMessage : '' , messages : item . messages . map ( ( msg ) => ( { ...msg , unread : false } ) ) }
149202 }
150203 if ( item . id === thread . id ) {
151204 return { ...item , isActive : true , unreadCount : 0 }
@@ -155,6 +208,36 @@ class MessagesView extends React.Component {
155208 } )
156209 }
157210
211+ onNewPostChange ( title , content ) {
212+ this . setState ( {
213+ newPost : { title, content}
214+ } )
215+ }
216+
217+ onNewThreadClick ( ) {
218+ const unsavedContentMsg = this . onLeave ( { } )
219+ if ( unsavedContentMsg ) {
220+ const changeConfirmed = confirm ( unsavedContentMsg )
221+ if ( changeConfirmed ) {
222+ this . showNewThreadForm ( )
223+ }
224+ } else {
225+ this . showNewThreadForm ( )
226+ }
227+ }
228+
229+ showNewThreadForm ( ) {
230+ this . setState ( {
231+ isCreateNewMessage : true ,
232+ threads : this . state . threads . map ( ( item ) => {
233+ if ( item . isActive ) {
234+ return { ...item , newMessage : '' }
235+ }
236+ return item
237+ } )
238+ } )
239+ }
240+
158241 onNewMessageChange ( content ) {
159242 this . setState ( {
160243 threads : this . state . threads . map ( ( item ) => {
@@ -200,6 +283,7 @@ class MessagesView extends React.Component {
200283 < NewPost
201284 currentUser = { currentUser }
202285 onPost = { this . onNewThread }
286+ onNewPostChange = { this . onNewPostChange }
203287 isCreating = { isCreatingFeed }
204288 hasError = { error }
205289 heading = "New Discussion Post"
@@ -227,7 +311,7 @@ class MessagesView extends React.Component {
227311 < div className = "messages-container" >
228312 < div className = "left-area" >
229313 < MessageList
230- onAdd = { ( ) => this . setState ( { isCreateNewMessage : true } ) }
314+ onAdd = { this . onNewThreadClick }
231315 threads = { threads }
232316 onSelect = { this . onThreadSelect }
233317 showAddButton = { ! ! currentMemberRole }
@@ -251,7 +335,7 @@ class MessagesView extends React.Component {
251335}
252336
253337const enhance = spinnerWhileLoading ( props => ! props . isLoading )
254- const EnhancedMessagesView = enhance ( MessagesView )
338+ const EnhancedMessagesView = withRouter ( enhance ( MessagesView ) )
255339
256340class MessagesContainer extends React . Component {
257341 constructor ( props ) {
0 commit comments