| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-09 20:36:32 +08:00
										 |  |  | var moment = require('moment'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  | module.exports = function (ngApp, events) { | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ngApp.controller('ImageManagerController', ['$scope', '$attrs', '$http', '$timeout', 'imageManagerService', | 
					
						
							|  |  |  |         function ($scope, $attrs, $http, $timeout, imageManagerService) { | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.images = []; | 
					
						
							|  |  |  |             $scope.imageType = $attrs.imageType; | 
					
						
							|  |  |  |             $scope.selectedImage = false; | 
					
						
							|  |  |  |             $scope.dependantPages = false; | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  |             $scope.showing = false; | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.hasMore = false; | 
					
						
							|  |  |  |             $scope.imageUpdateSuccess = false; | 
					
						
							|  |  |  |             $scope.imageDeleteSuccess = false; | 
					
						
							| 
									
										
										
										
											2016-03-13 21:30:47 +08:00
										 |  |  |             $scope.uploadedTo = $attrs.uploadedTo; | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |             $scope.view = 'all'; | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             $scope.searching = false; | 
					
						
							|  |  |  |             $scope.searchTerm = ''; | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             var page = 0; | 
					
						
							|  |  |  |             var previousClickTime = 0; | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |             var previousClickImage = 0; | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             var dataLoaded = false; | 
					
						
							|  |  |  |             var callback = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |             var preSearchImages = []; | 
					
						
							|  |  |  |             var preSearchHasMore = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |              * Used by dropzone to get the endpoint to upload to. | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |              * @returns {string} | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.getUploadUrl = function () { | 
					
						
							|  |  |  |                 return '/images/' + $scope.imageType + '/upload'; | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Cancel the current search operation. | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  |             function cancelSearch() { | 
					
						
							|  |  |  |                 $scope.searching = false; | 
					
						
							|  |  |  |                 $scope.searchTerm = ''; | 
					
						
							|  |  |  |                 $scope.images = preSearchImages; | 
					
						
							|  |  |  |                 $scope.hasMore = preSearchHasMore; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $scope.cancelSearch = cancelSearch; | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Runs on image upload, Adds an image to local list of images | 
					
						
							|  |  |  |              * and shows a success message to the user. | 
					
						
							|  |  |  |              * @param file | 
					
						
							|  |  |  |              * @param data | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.uploadSuccess = function (file, data) { | 
					
						
							|  |  |  |                 $scope.$apply(() => { | 
					
						
							|  |  |  |                     $scope.images.unshift(data); | 
					
						
							|  |  |  |                 }); | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |                 events.emit('success', 'Image uploaded'); | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             }; | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Runs the callback and hides the image manager. | 
					
						
							|  |  |  |              * @param returnData | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             function callbackAndHide(returnData) { | 
					
						
							|  |  |  |                 if (callback) callback(returnData); | 
					
						
							|  |  |  |                 $scope.showing = false; | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Image select action. Checks if a double-click was fired. | 
					
						
							|  |  |  |              * @param image | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.imageSelect = function (image) { | 
					
						
							|  |  |  |                 var dblClickTime = 300; | 
					
						
							|  |  |  |                 var currentTime = Date.now(); | 
					
						
							|  |  |  |                 var timeDiff = currentTime - previousClickTime; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |                 if (timeDiff < dblClickTime && image.id === previousClickImage) { | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |                     // If double click
 | 
					
						
							|  |  |  |                     callbackAndHide(image); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     // If single
 | 
					
						
							|  |  |  |                     $scope.selectedImage = image; | 
					
						
							|  |  |  |                     $scope.dependantPages = false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 previousClickTime = currentTime; | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |                 previousClickImage = image.id; | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Action that runs when the 'Select image' button is clicked. | 
					
						
							|  |  |  |              * Runs the callback and hides the image manager. | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.selectButtonClick = function () { | 
					
						
							|  |  |  |                 callbackAndHide($scope.selectedImage); | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Show the image manager. | 
					
						
							|  |  |  |              * Takes a callback to execute later on. | 
					
						
							|  |  |  |              * @param doneCallback | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             function show(doneCallback) { | 
					
						
							|  |  |  |                 callback = doneCallback; | 
					
						
							|  |  |  |                 $scope.showing = true; | 
					
						
							|  |  |  |                 // Get initial images if they have not yet been loaded in.
 | 
					
						
							|  |  |  |                 if (!dataLoaded) { | 
					
						
							|  |  |  |                     fetchData(); | 
					
						
							|  |  |  |                     dataLoaded = true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             // Connects up the image manger so it can be used externally
 | 
					
						
							|  |  |  |             // such as from TinyMCE.
 | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             imageManagerService.show = show; | 
					
						
							|  |  |  |             imageManagerService.showExternal = function (doneCallback) { | 
					
						
							|  |  |  |                 $scope.$apply(() => { | 
					
						
							|  |  |  |                     show(doneCallback); | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  |                 }); | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             }; | 
					
						
							|  |  |  |             window.ImageManager = imageManagerService; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Hide the image manager | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.hide = function () { | 
					
						
							|  |  |  |                 $scope.showing = false; | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |             var baseUrl = '/images/' + $scope.imageType + '/all/' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Fetch the list image data from the server. | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             function fetchData() { | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |                 var url = baseUrl + page + '?'; | 
					
						
							|  |  |  |                 var components = {}; | 
					
						
							|  |  |  |                 if ($scope.uploadedTo) components['page_id'] = $scope.uploadedTo; | 
					
						
							|  |  |  |                 if ($scope.searching) components['term'] = $scope.searchTerm; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 var urlQueryString = Object.keys(components).map((key) => { | 
					
						
							|  |  |  |                     return key + '=' + encodeURIComponent(components[key]); | 
					
						
							|  |  |  |                 }).join('&'); | 
					
						
							|  |  |  |                 url += urlQueryString; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |                 $http.get(url).then((response) => { | 
					
						
							|  |  |  |                     $scope.images = $scope.images.concat(response.data.images); | 
					
						
							|  |  |  |                     $scope.hasMore = response.data.hasMore; | 
					
						
							|  |  |  |                     page++; | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             $scope.fetchData = fetchData; | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-03 21:59:54 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Start a search operation | 
					
						
							|  |  |  |              * @param searchTerm | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  |             $scope.searchImages = function() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if ($scope.searchTerm === '') { | 
					
						
							|  |  |  |                     cancelSearch(); | 
					
						
							|  |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (!$scope.searching) { | 
					
						
							|  |  |  |                     preSearchImages = $scope.images; | 
					
						
							|  |  |  |                     preSearchHasMore = $scope.hasMore; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 $scope.searching = true; | 
					
						
							|  |  |  |                 $scope.images = []; | 
					
						
							|  |  |  |                 $scope.hasMore = false; | 
					
						
							|  |  |  |                 page = 0; | 
					
						
							|  |  |  |                 baseUrl = '/images/' + $scope.imageType + '/search/'; | 
					
						
							|  |  |  |                 fetchData(); | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             /** | 
					
						
							|  |  |  |              * Set the current image listing view. | 
					
						
							|  |  |  |              * @param viewName | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  |             $scope.setView = function(viewName) { | 
					
						
							|  |  |  |                 cancelSearch(); | 
					
						
							|  |  |  |                 $scope.images = []; | 
					
						
							|  |  |  |                 $scope.hasMore = false; | 
					
						
							|  |  |  |                 page = 0; | 
					
						
							|  |  |  |                 $scope.view = viewName; | 
					
						
							|  |  |  |                 baseUrl = '/images/' + $scope.imageType  + '/' + viewName + '/'; | 
					
						
							|  |  |  |                 fetchData(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Save the details of an image. | 
					
						
							|  |  |  |              * @param event | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.saveImageDetails = function (event) { | 
					
						
							|  |  |  |                 event.preventDefault(); | 
					
						
							|  |  |  |                 var url = '/images/update/' + $scope.selectedImage.id; | 
					
						
							|  |  |  |                 $http.put(url, this.selectedImage).then((response) => { | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |                     events.emit('success', 'Image details updated'); | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |                 }, (response) => { | 
					
						
							| 
									
										
										
										
											2016-02-28 04:52:46 +08:00
										 |  |  |                     if (response.status === 422) { | 
					
						
							|  |  |  |                         var errors = response.data; | 
					
						
							|  |  |  |                         var message = ''; | 
					
						
							|  |  |  |                         Object.keys(errors).forEach((key) => { | 
					
						
							|  |  |  |                             message += errors[key].join('\n'); | 
					
						
							|  |  |  |                         }); | 
					
						
							|  |  |  |                         events.emit('error', message); | 
					
						
							|  |  |  |                     } else if (response.status === 403) { | 
					
						
							|  |  |  |                         events.emit('error', response.data.error); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |                 }); | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Delete an image from system and notify of success. | 
					
						
							|  |  |  |              * Checks if it should force delete when an image | 
					
						
							|  |  |  |              * has dependant pages. | 
					
						
							|  |  |  |              * @param event | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |             $scope.deleteImage = function (event) { | 
					
						
							|  |  |  |                 event.preventDefault(); | 
					
						
							|  |  |  |                 var force = $scope.dependantPages !== false; | 
					
						
							|  |  |  |                 var url = '/images/' + $scope.selectedImage.id; | 
					
						
							|  |  |  |                 if (force) url += '?force=true'; | 
					
						
							|  |  |  |                 $http.delete(url).then((response) => { | 
					
						
							|  |  |  |                     $scope.images.splice($scope.images.indexOf($scope.selectedImage), 1); | 
					
						
							|  |  |  |                     $scope.selectedImage = false; | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |                     events.emit('success', 'Image successfully deleted'); | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |                 }, (response) => { | 
					
						
							|  |  |  |                     // Pages failure
 | 
					
						
							|  |  |  |                     if (response.status === 400) { | 
					
						
							|  |  |  |                         $scope.dependantPages = response.data; | 
					
						
							| 
									
										
										
										
											2016-02-28 04:52:46 +08:00
										 |  |  |                     } else if (response.status === 403) { | 
					
						
							|  |  |  |                         events.emit('error', response.data.error); | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             }; | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Simple date creator used to properly format dates. | 
					
						
							|  |  |  |              * @param stringDate | 
					
						
							|  |  |  |              * @returns {Date} | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2016-02-28 04:52:46 +08:00
										 |  |  |             $scope.getDate = function (stringDate) { | 
					
						
							| 
									
										
										
										
											2016-02-07 18:14:11 +08:00
										 |  |  |                 return new Date(stringDate); | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |         }]); | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-02 22:48:35 +08:00
										 |  |  |     ngApp.controller('BookShowController', ['$scope', '$http', '$attrs', '$sce', function ($scope, $http, $attrs, $sce) { | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  |         $scope.searching = false; | 
					
						
							|  |  |  |         $scope.searchTerm = ''; | 
					
						
							|  |  |  |         $scope.searchResults = ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $scope.searchBook = function (e) { | 
					
						
							|  |  |  |             e.preventDefault(); | 
					
						
							|  |  |  |             var term = $scope.searchTerm; | 
					
						
							|  |  |  |             if (term.length == 0) return; | 
					
						
							|  |  |  |             $scope.searching = true; | 
					
						
							|  |  |  |             $scope.searchResults = ''; | 
					
						
							|  |  |  |             var searchUrl = '/search/book/' + $attrs.bookId; | 
					
						
							|  |  |  |             searchUrl += '?term=' + encodeURIComponent(term); | 
					
						
							|  |  |  |             $http.get(searchUrl).then((response) => { | 
					
						
							| 
									
										
										
										
											2016-01-02 22:48:35 +08:00
										 |  |  |                 $scope.searchResults = $sce.trustAsHtml(response.data); | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  |             }); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $scope.checkSearchForm = function () { | 
					
						
							|  |  |  |             if ($scope.searchTerm.length < 1) { | 
					
						
							|  |  |  |                 $scope.searching = false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-31 03:57:17 +08:00
										 |  |  |         $scope.clearSearch = function () { | 
					
						
							| 
									
										
										
										
											2015-12-31 02:38:18 +08:00
										 |  |  |             $scope.searching = false; | 
					
						
							|  |  |  |             $scope.searchTerm = ''; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |     ngApp.controller('PageEditController', ['$scope', '$http', '$attrs', '$interval', '$timeout', '$sce', | 
					
						
							|  |  |  |         function ($scope, $http, $attrs, $interval, $timeout, $sce) { | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $scope.editorOptions = require('./pages/page-form'); | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |         $scope.editContent = ''; | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  |         $scope.draftText = ''; | 
					
						
							|  |  |  |         var pageId = Number($attrs.pageId); | 
					
						
							|  |  |  |         var isEdit = pageId !== 0; | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |         var autosaveFrequency = 30; // AutoSave interval in seconds.
 | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |         var isMarkdown = $attrs.editorType === 'markdown'; | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  |         $scope.isUpdateDraft = Number($attrs.pageUpdateDraft) === 1; | 
					
						
							|  |  |  |         $scope.isNewPageDraft = Number($attrs.pageNewDraft) === 1; | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Set inital header draft text
 | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  |         if ($scope.isUpdateDraft || $scope.isNewPageDraft) { | 
					
						
							|  |  |  |             $scope.draftText = 'Editing Draft' | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $scope.draftText = 'Editing Page' | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var autoSave = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var currentContent = { | 
					
						
							|  |  |  |             title: false, | 
					
						
							|  |  |  |             html: false | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (isEdit) { | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |             setTimeout(() => { | 
					
						
							|  |  |  |                 startAutoSave(); | 
					
						
							|  |  |  |             }, 1000); | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |         // Actions specifically for the markdown editor
 | 
					
						
							|  |  |  |         if (isMarkdown) { | 
					
						
							|  |  |  |             $scope.displayContent = ''; | 
					
						
							|  |  |  |             // Editor change event
 | 
					
						
							|  |  |  |             $scope.editorChange = function (content) { | 
					
						
							|  |  |  |                 $scope.displayContent = $sce.trustAsHtml(content); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-30 02:26:13 +08:00
										 |  |  |         if (!isMarkdown) { | 
					
						
							|  |  |  |             $scope.editorChange = function() {}; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |         /** | 
					
						
							|  |  |  |          * Start the AutoSave loop, Checks for content change | 
					
						
							|  |  |  |          * before performing the costly AJAX request. | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  |         function startAutoSave() { | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |             currentContent.title = $('#name').val(); | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |             currentContent.html = $scope.editContent; | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |             autoSave = $interval(() => { | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  |                 var newTitle = $('#name').val(); | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |                 var newHtml = $scope.editContent; | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |                 if (newTitle !== currentContent.title || newHtml !== currentContent.html) { | 
					
						
							|  |  |  |                     currentContent.html = newHtml; | 
					
						
							|  |  |  |                     currentContent.title = newTitle; | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |                     saveDraft(); | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |             }, 1000 * autosaveFrequency); | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |         /** | 
					
						
							|  |  |  |          * Save a draft update into the system via an AJAX request. | 
					
						
							|  |  |  |          * @param title | 
					
						
							|  |  |  |          * @param html | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |         function saveDraft() { | 
					
						
							|  |  |  |             var data = { | 
					
						
							|  |  |  |                 name: $('#name').val(), | 
					
						
							|  |  |  |                 html: isMarkdown ? $sce.getTrustedHtml($scope.displayContent) : $scope.editContent | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (isMarkdown) data.markdown = $scope.editContent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $http.put('/ajax/page/' + pageId + '/save-draft', data).then((responseData) => { | 
					
						
							| 
									
										
										
										
											2016-04-09 20:36:32 +08:00
										 |  |  |                 var updateTime = moment.utc(moment.unix(responseData.data.timestamp)).toDate(); | 
					
						
							| 
									
										
										
										
											2016-04-09 21:26:42 +08:00
										 |  |  |                 $scope.draftText = responseData.data.message + moment(updateTime).format('HH:mm'); | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  |                 if (!$scope.isNewPageDraft) $scope.isUpdateDraft = true; | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  |         $scope.forceDraftSave = function() { | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |             saveDraft(); | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-28 20:51:07 +08:00
										 |  |  |         // Listen to shortcuts coming via events
 | 
					
						
							|  |  |  |         $scope.$on('editor-keydown', (event, data) => { | 
					
						
							|  |  |  |             // Save shortcut (ctrl+s)
 | 
					
						
							|  |  |  |             if (data.keyCode == 83 && (navigator.platform.match("Mac") ? data.metaKey : data.ctrlKey)) { | 
					
						
							|  |  |  |                 data.preventDefault(); | 
					
						
							|  |  |  |                 saveDraft(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |         /** | 
					
						
							|  |  |  |          * Discard the current draft and grab the current page | 
					
						
							|  |  |  |          * content from the system via an AJAX request. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         $scope.discardDraft = function () { | 
					
						
							|  |  |  |             $http.get('/ajax/page/' + pageId).then((responseData) => { | 
					
						
							|  |  |  |                 if (autoSave) $interval.cancel(autoSave); | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  |                 $scope.draftText = 'Editing Page'; | 
					
						
							|  |  |  |                 $scope.isUpdateDraft = false; | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |                 $scope.$broadcast('html-update', responseData.data.html); | 
					
						
							| 
									
										
										
										
											2016-03-25 22:41:15 +08:00
										 |  |  |                 $scope.$broadcast('markdown-update', responseData.data.markdown || responseData.data.html); | 
					
						
							| 
									
										
										
										
											2016-03-13 20:04:08 +08:00
										 |  |  |                 $('#name').val(responseData.data.name); | 
					
						
							| 
									
										
										
										
											2016-03-12 23:52:19 +08:00
										 |  |  |                 $timeout(() => { | 
					
						
							|  |  |  |                     startAutoSave(); | 
					
						
							|  |  |  |                 }, 1000); | 
					
						
							|  |  |  |                 events.emit('success', 'Draft discarded, The editor has been updated with the current page content'); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-10 06:32:07 +08:00
										 |  |  |     }]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |     ngApp.controller('PageTagController', ['$scope', '$http', '$attrs', | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |         function ($scope, $http, $attrs) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const pageId = Number($attrs.pageId); | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |             $scope.tags = []; | 
					
						
							| 
									
										
										
										
											2016-05-15 03:02:00 +08:00
										 |  |  |              | 
					
						
							|  |  |  |             $scope.sortOptions = { | 
					
						
							|  |  |  |                 handle: '.handle', | 
					
						
							|  |  |  |                 items: '> tr', | 
					
						
							|  |  |  |                 containment: "parent", | 
					
						
							|  |  |  |                 axis: "y" | 
					
						
							|  |  |  |             }; | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             /** | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |              * Push an empty tag to the end of the scope tags. | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |              */ | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |             function addEmptyTag() { | 
					
						
							|  |  |  |                 $scope.tags.push({ | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |                     name: '', | 
					
						
							|  |  |  |                     value: '' | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-05-15 03:02:00 +08:00
										 |  |  |             $scope.addEmptyTag = addEmptyTag; | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             /** | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |              * Get all tags for the current book and add into scope. | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |              */ | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |             function getTags() { | 
					
						
							|  |  |  |                 $http.get('/ajax/tags/get/page/' + pageId).then((responseData) => { | 
					
						
							|  |  |  |                     $scope.tags = responseData.data; | 
					
						
							|  |  |  |                     addEmptyTag(); | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |                 }); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |             getTags(); | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             /** | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |              * Set the order property on all tags. | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |              */ | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |             function setTagOrder() { | 
					
						
							|  |  |  |                 for (let i = 0; i < $scope.tags.length; i++) { | 
					
						
							|  |  |  |                     $scope.tags[i].order = i; | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             /** | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |              * When an tag changes check if another empty editable | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |              * field needs to be added onto the end. | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |              * @param tag | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |              */ | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |             $scope.tagChange = function(tag) { | 
					
						
							|  |  |  |                 let cPos = $scope.tags.indexOf(tag); | 
					
						
							|  |  |  |                 if (cPos !== $scope.tags.length-1) return; | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |                 if (tag.name !== '' || tag.value !== '') { | 
					
						
							|  |  |  |                     addEmptyTag(); | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             /** | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |              * When an tag field loses focus check the tag to see if its | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |              * empty and therefore could be removed from the list. | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |              * @param tag | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |              */ | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |             $scope.tagBlur = function(tag) { | 
					
						
							|  |  |  |                 let isLast = $scope.tags.length - 1 === $scope.tags.indexOf(tag); | 
					
						
							|  |  |  |                 if (tag.name === '' && tag.value === '' && !isLast) { | 
					
						
							|  |  |  |                     let cPos = $scope.tags.indexOf(tag); | 
					
						
							|  |  |  |                     $scope.tags.splice(cPos, 1); | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-15 03:02:00 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Save the tags to the current page. | 
					
						
							|  |  |  |              */ | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |             $scope.saveTags = function() { | 
					
						
							|  |  |  |                 setTagOrder(); | 
					
						
							|  |  |  |                 let postData = {tags: $scope.tags}; | 
					
						
							|  |  |  |                 $http.post('/ajax/tags/update/page/' + pageId, postData).then((responseData) => { | 
					
						
							|  |  |  |                     $scope.tags = responseData.data.tags; | 
					
						
							|  |  |  |                     addEmptyTag(); | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |                     events.emit('success', responseData.data.message); | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-15 03:02:00 +08:00
										 |  |  |             /** | 
					
						
							|  |  |  |              * Remove a tag from the current list. | 
					
						
							|  |  |  |              * @param tag | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  |             $scope.removeTag = function(tag) { | 
					
						
							|  |  |  |                 let cIndex = $scope.tags.indexOf(tag); | 
					
						
							|  |  |  |                 $scope.tags.splice(cIndex, 1); | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 06:12:05 +08:00
										 |  |  |         }]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |