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/hereonthemap/hereonthemap.com/resources/` cat Home into Local
  put `https://hereonthemap.com/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