Technical description of the File Manager
The File Manager looks after all the images owned by users of the website. Each user has their own private area in which to upload files.
We start as usual, by naming the script and declaring all its variables. This script does not import any variables; it is pretty well independent of anything else.
script FileManager div Mask div Panel div FileListing div FileRow div Scroller div Uploader div Buttons span UploadStatus progress UploadProgress input UploadFile button CloseButton button NewFolderButton button ShowURLButton button UploadButton button DeleteButton a FileName img Icon img Image variable Alpha variable FileCount variable File variable FileList variable Name variable Type variable Source variable Content variable CurrentPath variable FullPath variable Separator variable Path variable N variable Even variable Progress variable Status variable User variable URL variable Home variable Local variable Email variable ID
The File Manager display does not hang on a DIV from its parent script; instead it attaches itself to the screen itself. It starts by creating a black mask DIV, initially set to fully transparent. Then it creates a panel for all of its fields. The styling of the panel differs on a smartphone from that on a PC; on the phone it's full screen but on a PC it only occupies half the screen and has wide margins.
create Mask in body set the style of Mask to `display:none;position:fixed;top:0;left:0;right:0;bottom:0;` cat `width:100%;height:100%;z-index:5;background-color:rgba(0,0,0,0.0);text-align:center` create Panel in Mask if mobile set the style of Panel to `width:100%;height:100%;background:#ffe` else set the style of Panel to `width:50%;height:90%;margin-top:5%;margin-left:25%;background:#ffe;border:3px solid black` create Uploader in Panel set the style of Uploader to `position:relative;top:0;width:100%;padding:0.5em 0;border:1px solid gray;font-size:80%` set the content of Uploader to `Select a file: ` create UploadFile in Uploader set attribute `type` of UploadFile to `file` set attribute `name` of UploadFile to `Source` create UploadStatus in Uploader create UploadProgress in Uploader set style `margin-left` of UploadProgress to `0.5em` set attribute `value` of UploadProgress to 0 set attribute `max` of UploadProgress to 100 create Buttons in Panel set the style of Buttons to `position:relative;top:10px` create CloseButton in Buttons set the style of CloseButton to `width:120px;height:40px` set the text of CloseButton to `Close` create DeleteButton in Buttons set the style of DeleteButton to `width:120px;height:40px` set the text of DeleteButton to `Delete` on click CloseButton history back create NewFolderButton in Buttons set the style of NewFolderButton to `width:120px;height:40px` set the text of NewFolderButton to `New Folder` create ShowURLButton in Buttons set the style of ShowURLButton to `display:none;width:120px;height:40px` set the text of ShowURLButton to `Show URL` create UploadButton in Buttons set the style of UploadButton to `width:120px;height:40px` set the text of UploadButton to `Upload` on click UploadButton go to Upload create FileListing in Panel set the style of FileListing to `position:relative;top:40px;width:100%;height:80%;text-align:center` create Scroller in FileListing set the style of Scroller to `position:absolute;top:0;left:0;bottom:0;right:0;text-align:left;overflow-y:scroll` create Image in FileListing set the style of Image to `display:none;display: block;margin: 0 auto;max-width:100%;max-height:100%`
Because the File Manager will only ever be seen by a logged-in user we can get the email address from storage and use it to retrieve the user record. The id of the record is used to set the base path in the file hierarchy, that makes every user's files private to them.
get Email from storage as `email` rest get User from `_/ec_users/get/` cat Email put property `id` of User into ID put property `home` of User cat `/` cat ID into Home put `/home/easycoder/hotm.easycoder.software/resources/` cat Home into Local put `http://hotm.easycoder.software/resources/` into URL
When we close File Manager we animate the disappearance of the Mask, by successively decreasing the alpha component of its background color.
on close begin set style `display` of Panel to `none` put 8 into Alpha while Alpha is greater than 0 begin take 1 from Alpha set style `background-color` of Mask to `rgba(0,0,0,0.` cat Alpha cat `)` wait 4 ticks end set style `display` of Mask to `none` end
Here we create a new folder:
on click NewFolderButton begin put prompt `Name of folder:` with `new` into Path if Path is empty stop replace ` ` with `-` in Path put Local cat CurrentPath cat `/` cat Path into Path rest post Path to `_mkdir` goto Browser end
That's the setup done, so let's wait for a trigger and allow the caller to continue.
on trigger go to Show set ready stop
Here we animate the Mask by successively increasing the alpha value of its background.
Show: set style `display` of Mask to `block` set style `display` of Panel to `block` put 0 into Alpha while Alpha is less than 8 begin set style `background-color` of Mask to `rgba(0,0,0,0.` cat Alpha cat `)` wait 4 ticks add 1 to Alpha end wait 10 ticks set style `display` of FileListing to `block`
The current path is remembered from the last time we used File Manager. If this is the first time the retrieved value will be empty.
get CurrentPath from storage as `fm-path`
We arrive here regularly while using File Manager, so save the current path. Then ask the server for a listing of all the files at this level. We have to translate forward slashes into tildes to avoid confusing the REST engine. Then we set up some arrays and initialize the scroller panel.
If the current path isn't empty we show a 'back' arrow to return to the previous level.
Browser: put CurrentPath into storage as `fm-path` put Home cat CurrentPath into FullPath replace `/` with `~` in FullPath rest get Content from `_list/` cat FullPath put empty into FileList put the json count of Content into FileCount set the elements of File to FileCount set the elements of FileName to FileCount ! Add a row for each file set the content of Scroller to `` set Even if CurrentPath is not empty begin create FileRow in Scroller set the style of FileRow to `width:90%;padding:0.5em 1em;text-align:left` create Icon in FileRow set the style of Icon to `float:left;margin-right:0.5em;width:20px` set attribute `src` of Icon to URL cat `system/arrow-back.png` create FileName in FileRow set the content of FileName to `(back to previous folder)` on click FileName begin put the position of the last `~` in CurrentPath into N if N is less than 0 put the position of the last `/` in CurrentPath into N put left N of CurrentPath into CurrentPath go to Browser end end
For each of the items in the current directory, we create a line with the name of the item and an appropriate icon.
set the elements of FileName to FileCount put 0 into N while N is less than FileCount begin index File to N json get element N of Content as File put property `name` of File into Name put property `type` of File into Type create FileRow in Scroller set the style of FileRow to `clear:both;padding:0.5em 1em;text-align:left` if Even set style `background` of FileRow to `#eee` create Icon in FileRow set the style of Icon to `float:left;margin-right:0.5em;width:20px` if Type is `dir` put `folder.png` into Source else if Type is `img` put `image.png` into Source else if Type is `txt` put `text.png` into Source else if Type is `doc` put `document.png` into Source else put `unknown.png` into Source set attribute `src` of Icon to URL cat `system/` cat Source index FileName to N create FileName in FileRow set the content of FileName to Name on click FileName go to SelectFile toggle Even add 1 to N end
When the Delete button is clicked we check the current directory is empty. If so, we delete it and back up to the previous level.
on click DeleteButton begin if FileCount is 0 begin rest post Local cat CurrentPath to `_delete` put the position of the last `~` in CurrentPath into N if N is less than 0 put the position of the last `/` in CurrentPath into N put left N of CurrentPath into CurrentPath go to Browser end else begin alert `Folder is not empty` end end stop
When an item is clicked, if it's a directory we move into it. Otherwise, if it's an image we display it. Any other file type is ignored, though there shouldn't be any.
SelectFile: index File to the index of FileName put property `type` of File into Type if Type is `dir` begin if CurrentPath is empty put `/` into Separator else put `~` into Separator put CurrentPath cat Separator cat the content of FileName into CurrentPath goto Browser end if Type is `img` begin set style `display` of Uploader to `none` set style `display` of UploadButton to `none` set style `display` of NewFolderButton to `none` set style `display` of Scroller to `none` set style `display` of Image to `block` put CurrentPath cat `/` cat property `name` of File into Path replace `~` with `/` in Path put URL cat Home cat Path into FullPath set attribute `src` of Image to FullPath on click CloseButton go to CloseMedia set style `display` of ShowURLButton to `inline-block` on click ShowURLButton begin prompt `URL of this image:` with URL cat Home cat Path end on click DeleteButton begin rest post Local cat Path to `_delete` go to CloseViewer end end stop
Here we close the viewer by hiding and revealing the relevant elements and reassigning the click handler for the Close button.
CloseViewer: set style `display` of Image to `none` set style `display` of Scroller to `block` set style `display` of Uploader to `inline-block` set style `display` of UploadButton to `inline-block` set style `display` of NewFolderButton to `inline-block` set style `display` of ShowURLButton to `none` on click CloseButton history back go to Browser
The uploader only works if a file is selected.
Upload: if UploadFile is empty alert `Please choose a file to upload` else begin put Local cat CurrentPath into Path upload UploadFile to Path with UploadProgress and UploadStatus goto Browser end stop