FileTreeManager.coffee 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. define [
  2. "ide/file-tree/directives/fileEntity"
  3. "ide/file-tree/directives/draggable"
  4. "ide/file-tree/directives/droppable"
  5. "ide/file-tree/controllers/FileTreeController"
  6. "ide/file-tree/controllers/FileTreeEntityController"
  7. "ide/file-tree/controllers/FileTreeFolderController"
  8. ], () ->
  9. class FileTreeManager
  10. constructor: (@ide, @$scope) ->
  11. @$scope.$on "project:joined", =>
  12. @loadRootFolder()
  13. @loadDeletedDocs()
  14. @$scope.$emit "file-tree:initialized"
  15. @_bindToSocketEvents()
  16. _bindToSocketEvents: () ->
  17. @ide.socket.on "reciveNewDoc", (parent_folder_id, doc) =>
  18. parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder
  19. @$scope.$apply () ->
  20. parent_folder.children.push {
  21. name: doc.name
  22. id: doc._id
  23. type: "doc"
  24. }
  25. @ide.socket.on "reciveNewFile", (parent_folder_id, file) =>
  26. parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder
  27. @$scope.$apply () ->
  28. parent_folder.children.push {
  29. name: file.name
  30. id: file._id
  31. type: "file"
  32. }
  33. @ide.socket.on "reciveNewFolder", (parent_folder_id, folder) =>
  34. parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder
  35. @$scope.$apply () ->
  36. parent_folder.children.push {
  37. name: folder.name
  38. id: folder._id
  39. type: "folder"
  40. children: []
  41. }
  42. @ide.socket.on "reciveEntityRename", (entity_id, name) =>
  43. entity = @findEntityById(entity_id)
  44. return if !entity?
  45. @$scope.$apply () ->
  46. entity.name = name
  47. @ide.socket.on "removeEntity", (entity_id) =>
  48. entity = @findEntityById(entity_id)
  49. return if !entity?
  50. @$scope.$apply () =>
  51. @_deleteEntityFromScope entity
  52. @ide.socket.on "reciveEntityMove", (entity_id, folder_id) =>
  53. entity = @findEntityById(entity_id)
  54. folder = @findEntityById(folder_id)
  55. @$scope.$apply () =>
  56. @_moveEntityInScope(entity, folder)
  57. selectEntity: (entity) ->
  58. @selected_entity_id = entity.id # For reselecting after a reconnect
  59. @ide.fileTreeManager.forEachEntity (entity) ->
  60. entity.selected = false
  61. entity.selected = true
  62. findEntityById: (id, options = {}) ->
  63. entity = @_findEntityByIdInFolder @$scope.rootFolder, id
  64. return entity if entity?
  65. if options.includeDeleted
  66. for entity in @$scope.deletedDocs
  67. return entity if entity.id == id
  68. return null
  69. _findEntityByIdInFolder: (folder, id) ->
  70. for entity in folder.children or []
  71. if entity.id == id
  72. return entity
  73. else if entity.children?
  74. result = @_findEntityByIdInFolder(entity, id)
  75. return result if result?
  76. return null
  77. findEntityByPath: (path) ->
  78. @_findEntityByPathInFolder @$scope.rootFolder, path
  79. _findEntityByPathInFolder: (folder, path) ->
  80. parts = path.split("/")
  81. name = parts.shift()
  82. rest = parts.join("/")
  83. if name == "."
  84. return @_findEntityByPathInFolder(folder, rest)
  85. for entity in folder.children
  86. if entity.name == name
  87. if rest == ""
  88. return entity
  89. else if entity.type == "folder"
  90. return @_findEntityByPathInFolder(entity, rest)
  91. return null
  92. forEachEntity: (callback = (entity, parent_folder) ->) ->
  93. @_forEachEntityInFolder(@$scope.rootFolder, callback)
  94. for entity in @$scope.deletedDocs or []
  95. callback(entity)
  96. _forEachEntityInFolder: (folder, callback) ->
  97. for entity in folder.children or []
  98. callback(entity, folder)
  99. if entity.children?
  100. @_forEachEntityInFolder(entity, callback)
  101. getEntityPath: (entity) ->
  102. @_getEntityPathInFolder @$scope.rootFolder, entity
  103. _getEntityPathInFolder: (folder, entity) ->
  104. for child in folder.children or []
  105. if child == entity
  106. return entity.name
  107. else if child.type == "folder"
  108. path = @_getEntityPathInFolder(child, entity)
  109. if path?
  110. return child.name + "/" + path
  111. return null
  112. getRootDocDirname: () ->
  113. rootDoc = @findEntityById @$scope.project.rootDoc_id
  114. return if !rootDoc?
  115. path = @getEntityPath(rootDoc)
  116. return if !path?
  117. return path.split("/").slice(0, -1).join("/")
  118. # forEachFolder: (callback) ->
  119. # @forEachEntity (entity) ->
  120. # if entity.type == "folder"
  121. # callback(entity)
  122. loadRootFolder: () ->
  123. @$scope.rootFolder = @_parseFolder(@$scope.project.rootFolder[0])
  124. _parseFolder: (rawFolder) ->
  125. folder = {
  126. name: rawFolder.name
  127. id: rawFolder._id
  128. type: "folder"
  129. children: []
  130. selected: (rawFolder._id == @selected_entity_id)
  131. }
  132. for doc in rawFolder.docs or []
  133. folder.children.push {
  134. name: doc.name
  135. id: doc._id
  136. type: "doc"
  137. selected: (doc._id == @selected_entity_id)
  138. }
  139. for file in rawFolder.fileRefs or []
  140. folder.children.push {
  141. name: file.name
  142. id: file._id
  143. type: "file"
  144. selected: (file._id == @selected_entity_id)
  145. }
  146. for childFolder in rawFolder.folders or []
  147. folder.children.push @_parseFolder(childFolder)
  148. return folder
  149. loadDeletedDocs: () ->
  150. @$scope.deletedDocs = []
  151. for doc in @$scope.project.deletedDocs
  152. @$scope.deletedDocs.push {
  153. name: doc.name
  154. id: doc._id
  155. type: "doc"
  156. deleted: true
  157. }
  158. getCurrentFolder: () ->
  159. # Return the root folder if nothing is selected
  160. @_getCurrentFolder(@$scope.rootFolder) or @$scope.rootFolder
  161. _getCurrentFolder: (startFolder = @$scope.rootFolder) ->
  162. for entity in startFolder.children or []
  163. # The 'current' folder is either the one selected, or
  164. # the one containing the selected doc/file
  165. if entity.selected
  166. if entity.type == "folder"
  167. return entity
  168. else
  169. return startFolder
  170. if entity.type == "folder"
  171. result = @_getCurrentFolder(entity)
  172. return result if result?
  173. return null
  174. createDoc: (name, parent_folder = @getCurrentFolder()) ->
  175. # We'll wait for the socket.io notification to actually
  176. # add the doc for us.
  177. @ide.$http.post "/project/#{@ide.project_id}/doc", {
  178. name: name,
  179. parent_folder_id: parent_folder?.id
  180. _csrf: window.csrfToken
  181. }
  182. createFolder: (name, parent_folder = @getCurrentFolder()) ->
  183. # We'll wait for the socket.io notification to actually
  184. # add the folder for us.
  185. return @ide.$http.post "/project/#{@ide.project_id}/folder", {
  186. name: name,
  187. parent_folder_id: parent_folder?.id
  188. _csrf: window.csrfToken
  189. }
  190. renameEntity: (entity, name, callback = (error) ->) ->
  191. return if entity.name == name
  192. entity.name = name
  193. return @ide.$http.post "/project/#{@ide.project_id}/#{entity.type}/#{entity.id}/rename", {
  194. name: name,
  195. _csrf: window.csrfToken
  196. }
  197. deleteEntity: (entity, callback = (error) ->) ->
  198. # We'll wait for the socket.io notification to
  199. # delete from scope.
  200. return @ide.$http {
  201. method: "DELETE"
  202. url: "/project/#{@ide.project_id}/#{entity.type}/#{entity.id}"
  203. headers:
  204. "X-Csrf-Token": window.csrfToken
  205. }
  206. moveEntity: (entity, parent_folder, callback = (error) ->) ->
  207. @_moveEntityInScope(entity, parent_folder)
  208. return @ide.$http.post "/project/#{@ide.project_id}/#{entity.type}/#{entity.id}/move", {
  209. folder_id: parent_folder.id
  210. _csrf: window.csrfToken
  211. }
  212. _deleteEntityFromScope: (entity) ->
  213. parent_folder = null
  214. @forEachEntity (possible_entity, folder) ->
  215. if possible_entity == entity
  216. parent_folder = folder
  217. if parent_folder?
  218. index = parent_folder.children.indexOf(entity)
  219. if index > -1
  220. parent_folder.children.splice(index, 1)
  221. if entity.type == "doc"
  222. entity.deleted = true
  223. @$scope.deletedDocs.push entity
  224. _moveEntityInScope: (entity, parent_folder) ->
  225. return if entity in parent_folder.children
  226. @_deleteEntityFromScope(entity)
  227. parent_folder.children.push(entity)