Error box, download button, editor save and more.
Former-commit-id: c14972384cc8afad28d49388b0b4545669e20b7d [formerly 0af2e5f9aff2aac576044ca9590045f656fbffda] [formerly 02248a86b7063e1c9d6779c3574a848708ff86f2 [formerly efaa8439a9dbbf9b829cf9fc32ca789c2a16df7d]] Former-commit-id: 4ce0a81ea04b56cef11d62107d692502e266a16e [formerly 2c46db9398c267351c10f06c089ed08dc3625232] Former-commit-id: 1c93a0643217ab69668600b41e2d8263266d7e23
This commit is contained in:
		
							parent
							
								
									7def1b2325
								
							
						
					
					
						commit
						0012601652
					
				
							
								
								
									
										4
									
								
								api.go
								
								
								
								
							
							
						
						
									
										4
									
								
								api.go
								
								
								
								
							|  | @ -59,8 +59,6 @@ func serveAPI(c *requestContext, w http.ResponseWriter, r *http.Request) (int, e | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fmt.Println(c.us) |  | ||||||
| 
 |  | ||||||
| 	switch router { | 	switch router { | ||||||
| 	case "download": | 	case "download": | ||||||
| 		return downloadHandler(c, w, r) | 		return downloadHandler(c, w, r) | ||||||
|  | @ -524,14 +522,12 @@ func usersPutHandler(c *requestContext, w http.ResponseWriter, r *http.Request) | ||||||
| 
 | 
 | ||||||
| 		pw, err := hashPassword(u.Password) | 		pw, err := hashPassword(u.Password) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			fmt.Println(err) |  | ||||||
| 			return http.StatusInternalServerError, err | 			return http.StatusInternalServerError, err | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		c.us.Password = pw | 		c.us.Password = pw | ||||||
| 		err = c.fm.db.UpdateField(&User{ID: c.us.ID}, "Password", pw) | 		err = c.fm.db.UpdateField(&User{ID: c.us.ID}, "Password", pw) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			fmt.Println(err) |  | ||||||
| 			return http.StatusInternalServerError, err | 			return http.StatusInternalServerError, err | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,16 +1,18 @@ | ||||||
| <template> | <template> | ||||||
|     <form id="editor" :class="req.language"> |     <form id="editor" :class="req.language"> | ||||||
|         <h2 v-if="hasMetadata">Metadata</h2> |         <div v-if="hasMetadata" id="metadata"> | ||||||
|         <textarea v-model="req.metadata" v-if="hasMetadata" id="metadata"></textarea> |           <h2>Metadata</h2> | ||||||
|  |         </div> | ||||||
| 
 | 
 | ||||||
|         <h2 v-if="hasMetadata">Body</h2> |         <h2 v-if="hasMetadata">Body</h2> | ||||||
|         <textarea v-model="req.content" id="content"></textarea> |  | ||||||
|     </form> |     </form> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script> | <script> | ||||||
| import { mapState } from 'vuex' | import { mapState } from 'vuex' | ||||||
| import CodeMirror from '@/utils/codemirror' | import CodeMirror from '@/utils/codemirror' | ||||||
|  | import api from '@/utils/api' | ||||||
|  | import buttons from '@/utils/buttons' | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   name: 'editor', |   name: 'editor', | ||||||
|  | @ -23,11 +25,22 @@ export default { | ||||||
|   data: function () { |   data: function () { | ||||||
|     return { |     return { | ||||||
|       metadata: null, |       metadata: null, | ||||||
|  |       metalang: null, | ||||||
|       content: null |       content: null | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  |   created () { | ||||||
|  |     window.addEventListener('keydown', this.keyEvent) | ||||||
|  |     document.getElementById('save-button').addEventListener('click', this.save) | ||||||
|  |   }, | ||||||
|  |   beforeDestroy () { | ||||||
|  |     window.removeEventListener('keydown', this.keyEvent) | ||||||
|  |     document.getElementById('save-button').removeEventListener('click', this.save) | ||||||
|  |   }, | ||||||
|   mounted: function () { |   mounted: function () { | ||||||
|     this.content = CodeMirror.fromTextArea(document.getElementById('content'), { |     // Set up the main content editor. | ||||||
|  |     this.content = CodeMirror(document.getElementById('editor'), { | ||||||
|  |       value: this.req.content, | ||||||
|       lineNumbers: (this.req.language !== 'markdown'), |       lineNumbers: (this.req.language !== 'markdown'), | ||||||
|       viewportMargin: Infinity, |       viewportMargin: Infinity, | ||||||
|       autofocus: true, |       autofocus: true, | ||||||
|  | @ -42,25 +55,66 @@ export default { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     this.metadata = CodeMirror.fromTextArea(document.getElementById('metadata'), { |     this.parseMetadata() | ||||||
|  | 
 | ||||||
|  |     // Set up metadata editor. | ||||||
|  |     this.metadata = CodeMirror(document.getElementById('metadata'), { | ||||||
|  |       value: this.req.metadata, | ||||||
|       viewportMargin: Infinity, |       viewportMargin: Infinity, | ||||||
|       lineWrapping: true, |       lineWrapping: true, | ||||||
|       theme: 'markdown' |       theme: 'markdown' | ||||||
|     }) |     }) | ||||||
| 
 | 
 | ||||||
|     if (this.req.metadata.startsWith('{')) { |     CodeMirror.autoLoadMode(this.metadata, this.metalang) | ||||||
|       CodeMirror.autoLoadMode(this.metadata, 'json') |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (this.req.metadata.startsWith('---')) { |  | ||||||
|       CodeMirror.autoLoadMode(this.metadata, 'yaml') |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (this.req.metadata.startsWith('+++')) { |  | ||||||
|       CodeMirror.autoLoadMode(this.metadata, 'toml') |  | ||||||
|     } |  | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|  |     // Saves the content when the user presses CTRL-S. | ||||||
|  |     keyEvent (event) { | ||||||
|  |       if (!event.ctrlKey && !event.metaKey) { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (String.fromCharCode(event.which).toLowerCase() !== 's') { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       event.preventDefault() | ||||||
|  |       this.save() | ||||||
|  |     }, | ||||||
|  |     // Parses the metadata and gets the language in which | ||||||
|  |     // it is written. | ||||||
|  |     parseMetadata () { | ||||||
|  |       if (this.req.metadata.startsWith('{')) { | ||||||
|  |         this.metalang = 'json' | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (this.req.metadata.startsWith('---')) { | ||||||
|  |         this.metalang = 'yaml' | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (this.req.metadata.startsWith('+++')) { | ||||||
|  |         this.metalang = 'toml' | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     // Saves the file. | ||||||
|  |     save () { | ||||||
|  |       buttons.loading('save') | ||||||
|  |       let content = this.content.getValue() | ||||||
|  | 
 | ||||||
|  |       if (this.hasMetadata) { | ||||||
|  |         content = this.metadata.getValue() + '\n\n' + content | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       api.put(this.$route.path, content) | ||||||
|  |         .then(() => { | ||||||
|  |           buttons.done('save') | ||||||
|  |           console.log('Saved!') | ||||||
|  |         }) | ||||||
|  |         .catch(error => { | ||||||
|  |           buttons.done('save') | ||||||
|  |           console.log(error) | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | @ -172,10 +172,9 @@ export default { | ||||||
|           buttons.done('upload') |           buttons.done('upload') | ||||||
|           this.$store.commit('setReload', true) |           this.$store.commit('setReload', true) | ||||||
|         }) |         }) | ||||||
|         .catch(e => { |         .catch(error => { | ||||||
|           buttons.done('upload') |           buttons.done('upload') | ||||||
|           // TODO: show error in box |           this.$store.commit('showError', error) | ||||||
|           console.log(e) |  | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|       return false |       return false | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ | ||||||
|           <i class="material-icons">search</i> |           <i class="material-icons">search</i> | ||||||
|         </button> |         </button> | ||||||
| 
 | 
 | ||||||
|         <button v-show="isEditor" aria-label="Save" class="action" id="save"> |         <button v-show="isEditor" aria-label="Save" class="action" id="save-button"> | ||||||
|           <i class="material-icons" title="Save">save</i> |           <i class="material-icons" title="Save">save</i> | ||||||
|         </button> |         </button> | ||||||
|         <rename-button v-show="!loading && showRenameButton"></rename-button> |         <rename-button v-show="!loading && showRenameButton"></rename-button> | ||||||
|  | @ -171,8 +171,6 @@ export default { | ||||||
|   }, |   }, | ||||||
|   created () { |   created () { | ||||||
|     this.fetchData() |     this.fetchData() | ||||||
|     // TODO: finish this box |  | ||||||
|     // this.$store.commit('showHover', 'error') |  | ||||||
|   }, |   }, | ||||||
|   watch: { |   watch: { | ||||||
|     '$route': 'fetchData', |     '$route': 'fetchData', | ||||||
|  | @ -184,59 +182,7 @@ export default { | ||||||
|   mounted () { |   mounted () { | ||||||
|     updateColumnSizes() |     updateColumnSizes() | ||||||
|     window.addEventListener('resize', updateColumnSizes) |     window.addEventListener('resize', updateColumnSizes) | ||||||
|     window.addEventListener('keydown', (event) => { |     window.addEventListener('keydown', this.keyEvent) | ||||||
|       // Esc! |  | ||||||
|       if (event.keyCode === 27) { |  | ||||||
|         this.$store.commit('closeHovers') |  | ||||||
| 
 |  | ||||||
|         // Unselect all files and folders. |  | ||||||
|         if (this.req.kind === 'listing') { |  | ||||||
|           let items = document.getElementsByClassName('item') |  | ||||||
|           Array.from(items).forEach(link => { |  | ||||||
|             link.setAttribute('aria-selected', false) |  | ||||||
|           }) |  | ||||||
| 
 |  | ||||||
|           this.$store.commit('resetSelected') |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       // Del! |  | ||||||
|       if (event.keyCode === 46) { |  | ||||||
|         if (this.showDeleteButton) { |  | ||||||
|           this.$store.commit('showHover', 'delete') |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       // F1! |  | ||||||
|       if (event.keyCode === 112) { |  | ||||||
|         event.preventDefault() |  | ||||||
|         this.$store.commit('showHover', 'help') |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       // F2! |  | ||||||
|       if (event.keyCode === 113) { |  | ||||||
|         if (this.showRenameButton) { |  | ||||||
|           this.$store.commit('showHover', 'rename') |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       // CTRL + S |  | ||||||
|       if (event.ctrlKey || event.metaKey) { |  | ||||||
|         switch (String.fromCharCode(event.which).toLowerCase()) { |  | ||||||
|           case 's': |  | ||||||
|             event.preventDefault() |  | ||||||
| 
 |  | ||||||
|             if (this.req.kind !== 'editor') { |  | ||||||
|               window.location = '?download=true' |  | ||||||
|               return |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // TODO: save file on editor! |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     }) |  | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|     fetchData () { |     fetchData () { | ||||||
|  | @ -262,12 +208,61 @@ export default { | ||||||
|         this.loading = false |         this.loading = false | ||||||
|       }) |       }) | ||||||
|       .catch(error => { |       .catch(error => { | ||||||
|         // TODO: 404, 403 and 500! |  | ||||||
|         console.log(error) |         console.log(error) | ||||||
|         this.error = error |         this.error = error | ||||||
|         this.loading = false |         this.loading = false | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|  |     keyEvent (event) { | ||||||
|  |       // Esc! | ||||||
|  |       if (event.keyCode === 27) { | ||||||
|  |         this.$store.commit('closeHovers') | ||||||
|  | 
 | ||||||
|  |         if (this.req.kind !== 'listing') { | ||||||
|  |           return | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // If we're on a listing, unselect all files and folders. | ||||||
|  |         let items = document.getElementsByClassName('item') | ||||||
|  |         Array.from(items).forEach(link => { | ||||||
|  |           link.setAttribute('aria-selected', false) | ||||||
|  |         }) | ||||||
|  | 
 | ||||||
|  |         this.$store.commit('resetSelected') | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Del! | ||||||
|  |       if (event.keyCode === 46) { | ||||||
|  |         if (this.showDeleteButton && this.req.kind !== 'editor') { | ||||||
|  |           this.$store.commit('showHover', 'delete') | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // F1! | ||||||
|  |       if (event.keyCode === 112) { | ||||||
|  |         event.preventDefault() | ||||||
|  |         this.$store.commit('showHover', 'help') | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // F2! | ||||||
|  |       if (event.keyCode === 113) { | ||||||
|  |         if (this.showRenameButton) { | ||||||
|  |           this.$store.commit('showHover', 'rename') | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // CTRL + S | ||||||
|  |       if (event.ctrlKey || event.metaKey) { | ||||||
|  |         if (String.fromCharCode(event.which).toLowerCase() === 's') { | ||||||
|  |           event.preventDefault() | ||||||
|  | 
 | ||||||
|  |           if (this.req.kind !== 'editor') { | ||||||
|  |             document.getElementById('download-button').click() | ||||||
|  |             return | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     openSidebar () { |     openSidebar () { | ||||||
|       this.$store.commit('showHover', 'sidebar') |       this.$store.commit('showHover', 'sidebar') | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <template> | <template> | ||||||
|   <button @click="download" aria-label="Download" title="Download" class="action"> |   <button @click="download" aria-label="Download" title="Download" id="download-button" class="action"> | ||||||
|     <i class="material-icons">file_download</i> |     <i class="material-icons">file_download</i> | ||||||
|     <span>Download</span> |     <span>Download</span> | ||||||
|     <span v-if="selectedCount > 0" class="counter">{{ selectedCount }}</span> |     <span v-if="selectedCount > 0" class="counter">{{ selectedCount }}</span> | ||||||
|  |  | ||||||
|  | @ -36,8 +36,7 @@ export default { | ||||||
|           }) |           }) | ||||||
|           .catch(error => { |           .catch(error => { | ||||||
|             buttons.done('delete') |             buttons.done('delete') | ||||||
|             // TODO: show error in prompt |             this.$store.commit('showError', error) | ||||||
|             console.log(error) |  | ||||||
|           }) |           }) | ||||||
| 
 | 
 | ||||||
|         return |         return | ||||||
|  | @ -63,7 +62,7 @@ export default { | ||||||
|           console.log(error) |           console.log(error) | ||||||
|           this.$store.commit('setReload', true) |           this.$store.commit('setReload', true) | ||||||
|           buttons.done('delete') |           buttons.done('delete') | ||||||
|           // TODO: show error in prompt |           this.$store.commit('showError', error) | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -2,9 +2,9 @@ | ||||||
|   <div class="prompt error"> |   <div class="prompt error"> | ||||||
|     <i class="material-icons">error_outline</i> |     <i class="material-icons">error_outline</i> | ||||||
|     <h3>Something went wrong</h3> |     <h3>Something went wrong</h3> | ||||||
|     <pre>{{ error }}</pre> |     <pre>{{ $store.state.showMessage }}</pre> | ||||||
|     <div> |     <div> | ||||||
|       <button @click="$store.commit('closeHovers')" autofocus>Close</button> |       <button @click="close" autofocus>Close</button> | ||||||
|       <button @click="reportIssue" class="cancel">Report Issue</button> |       <button @click="reportIssue" class="cancel">Report Issue</button> | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
|  | @ -13,10 +13,12 @@ | ||||||
| <script> | <script> | ||||||
| export default { | export default { | ||||||
|   name: 'error', |   name: 'error', | ||||||
|   props: ['error'], |  | ||||||
|   methods: { |   methods: { | ||||||
|     reportIssue () { |     reportIssue () { | ||||||
|       window.open('https://github.com/hacdias/filemanager/issues/new') |       window.open('https://github.com/hacdias/filemanager/issues/new') | ||||||
|  |     }, | ||||||
|  |     close () { | ||||||
|  |       this.$store.commit('closeHovers') | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -81,10 +81,9 @@ export default { | ||||||
|           buttons.done('move') |           buttons.done('move') | ||||||
|           this.$router.push({page: dest}) |           this.$router.push({page: dest}) | ||||||
|         }) |         }) | ||||||
|         .catch(e => { |         .catch(error => { | ||||||
|           buttons.done('move') |           buttons.done('move') | ||||||
|           // TODO: show error in prompt |           this.$store.commit('showError', error) | ||||||
|           console.log(e) |  | ||||||
|         }) |         }) | ||||||
|     }, |     }, | ||||||
|     next: function (event) { |     next: function (event) { | ||||||
|  |  | ||||||
|  | @ -39,8 +39,7 @@ export default { | ||||||
|           this.$router.push({ path: uri }) |           this.$router.push({ path: uri }) | ||||||
|         }) |         }) | ||||||
|         .catch(error => { |         .catch(error => { | ||||||
|           // TODO: Show error message! |           this.$store.commit('showError', error) | ||||||
|           console.log(error) |  | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|       this.$store.commit('closeHovers') |       this.$store.commit('closeHovers') | ||||||
|  |  | ||||||
|  | @ -39,8 +39,7 @@ export default { | ||||||
|           this.$router.push({ path: uri }) |           this.$router.push({ path: uri }) | ||||||
|         }) |         }) | ||||||
|         .catch(error => { |         .catch(error => { | ||||||
|           // TODO: show error message in a box |           this.$store.commit('showError', error) | ||||||
|           console.log(error) |  | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|       this.$store.commit('closeHovers') |       this.$store.commit('closeHovers') | ||||||
|  |  | ||||||
|  | @ -61,8 +61,7 @@ export default { | ||||||
|           // TODO: keep selected after reload? |           // TODO: keep selected after reload? | ||||||
|           this.$store.commit('setReload', true) |           this.$store.commit('setReload', true) | ||||||
|         }).catch(error => { |         }).catch(error => { | ||||||
|           // TODO: show error message |           this.$store.commit('showError', error) | ||||||
|           console.log(error) |  | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|       this.$store.commit('closeHovers') |       this.$store.commit('closeHovers') | ||||||
|  |  | ||||||
|  | @ -13,7 +13,8 @@ const state = { | ||||||
|   reload: false, |   reload: false, | ||||||
|   selected: [], |   selected: [], | ||||||
|   multiple: false, |   multiple: false, | ||||||
|   show: null |   show: null, | ||||||
|  |   showMessage: null | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default new Vuex.Store({ | export default new Vuex.Store({ | ||||||
|  |  | ||||||
|  | @ -1,6 +1,21 @@ | ||||||
| const mutations = { | const mutations = { | ||||||
|   closeHovers: state => { state.show = null }, |   closeHovers: state => { | ||||||
|   showHover: (state, value) => { state.show = value }, |     state.show = null | ||||||
|  |     state.showMessage = null | ||||||
|  |   }, | ||||||
|  |   showHover: (state, value) => { | ||||||
|  |     if (typeof value !== 'object') { | ||||||
|  |       state.show = value | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     state.show = value.prompt | ||||||
|  |     state.showMessage = value.message | ||||||
|  |   }, | ||||||
|  |   showError: (state, value) => { | ||||||
|  |     state.show = 'error' | ||||||
|  |     state.showMessage = value | ||||||
|  |   }, | ||||||
|   setReload: (state, value) => { state.reload = value }, |   setReload: (state, value) => { state.reload = value }, | ||||||
|   setUser: (state, value) => (state.user = value), |   setUser: (state, value) => (state.user = value), | ||||||
|   setJWT: (state, value) => (state.jwt = value), |   setJWT: (state, value) => (state.jwt = value), | ||||||
|  |  | ||||||
|  | @ -19,9 +19,15 @@ var ( | ||||||
| // FileManager is a file manager instance. It should be creating using the
 | // FileManager is a file manager instance. It should be creating using the
 | ||||||
| // 'New' function and not directly.
 | // 'New' function and not directly.
 | ||||||
| type FileManager struct { | type FileManager struct { | ||||||
| 	db  *storm.DB | 	// The BoltDB database for this instance.
 | ||||||
|  | 	db *storm.DB | ||||||
|  | 
 | ||||||
|  | 	// The key used to sign the JWT tokens.
 | ||||||
| 	key []byte | 	key []byte | ||||||
| 
 | 
 | ||||||
|  | 	// The static assets.
 | ||||||
|  | 	assets *rice.Box | ||||||
|  | 
 | ||||||
| 	// PrefixURL is a part of the URL that is already trimmed from the request URL before it
 | 	// PrefixURL is a part of the URL that is already trimmed from the request URL before it
 | ||||||
| 	// arrives to our handlers. It may be useful when using File Manager as a middleware
 | 	// arrives to our handlers. It may be useful when using File Manager as a middleware
 | ||||||
| 	// such as in caddy-filemanager plugin. It is only useful in certain situations.
 | 	// such as in caddy-filemanager plugin. It is only useful in certain situations.
 | ||||||
|  | @ -35,7 +41,8 @@ type FileManager struct { | ||||||
| 	// Users is a map with the different configurations for each user.
 | 	// Users is a map with the different configurations for each user.
 | ||||||
| 	Users map[string]*User | 	Users map[string]*User | ||||||
| 
 | 
 | ||||||
| 	assets *rice.Box | 	// The plugins that have been plugged in.
 | ||||||
|  | 	Plugins []*Plugin | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Command is a command function.
 | // Command is a command function.
 | ||||||
|  | @ -96,6 +103,12 @@ type Regexp struct { | ||||||
| 	regexp *regexp.Regexp | 	regexp *regexp.Regexp | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Plugin is a File Manager plugin.
 | ||||||
|  | type Plugin struct { | ||||||
|  | 	// The JavaScript that will be injected into the main page.
 | ||||||
|  | 	JavaScript string | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // DefaultUser is used on New, when no 'base' user is provided.
 | // DefaultUser is used on New, when no 'base' user is provided.
 | ||||||
| var DefaultUser = User{ | var DefaultUser = User{ | ||||||
| 	Username:      "admin", | 	Username:      "admin", | ||||||
|  | @ -208,11 +221,19 @@ func (m *FileManager) SetBaseURL(url string) { | ||||||
| // ServeHTTP determines if the request is for this plugin, and if all prerequisites are met.
 | // ServeHTTP determines if the request is for this plugin, and if all prerequisites are met.
 | ||||||
| func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { | func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { | ||||||
| 	// TODO: Handle errors here and make it compatible with http.Handler
 | 	// TODO: Handle errors here and make it compatible with http.Handler
 | ||||||
| 	return serveHTTP(&requestContext{ | 	code, err := serveHTTP(&requestContext{ | ||||||
| 		fm: m, | 		fm: m, | ||||||
| 		us: nil, | 		us: nil, | ||||||
| 		fi: nil, | 		fi: nil, | ||||||
| 	}, w, r) | 	}, w, r) | ||||||
|  | 
 | ||||||
|  | 	if code != 0 && err != nil { | ||||||
|  | 		w.WriteHeader(code) | ||||||
|  | 		w.Write([]byte(err.Error())) | ||||||
|  | 		return 0, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return code, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Allowed checks if the user has permission to access a directory/file.
 | // Allowed checks if the user has permission to access a directory/file.
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue