HR/CryptoSync

View on GitHub
static/menubar.html

Summary

Maintainability
Test Coverage
<!doctype html>
<html>

  <head>
    <meta charset="utf-8">
    <title>Crypto.Sync</title>
    <link rel="stylesheet" href="style/menubar.css">
  </head>

  <body>
    <section id="menubar">
      <div class="head">
        <a class="left navigationLink" data-target="openSyncFolder" id="openSyncFolder">
          <img class="icon" src="images/icons/folder.svg" alt=""/>
        </a>
        <a class="right navigationLink" data-target="openVault">
          <img class="icon" src="images/icons/CryptoSyncVault_sl.svg" alt=""/>
        </a>
      </div>
      <header>RECENTLY CHANGED</header>
      <div class="fileList" id="filesList"></div>
      <footer>
        <div class="status" id="status"></div>
        <a class="right navigationLink" data-target="openSettings">
          <img class="icon" src="images/icons/settings.svg"/>
        </a>
        <a class="left navigationLink" data-target="quitApp">
          <img class="icon" src="images/icons/quit.svg" alt=""/>
        </a>
      </footer>
    </section>
    <script id="file-template" type="text/x-handlebars-template">
      <div class="item">
        <div class="type">
          <img class="fileType" src="images/icons/filetypes/{{fileType}}.svg">
          <div class="cloudType">
            <img src="images/icons/{{type}}.svg"></img>
          </div>
        </div>
        <div class="content">
          <div class="name">{{name}}</div>
          <div class="lastSynced">{{synced}}
            <span data-moment="{{lastMoment}}">{{lastSyncedText}}</span>
          </div>
        </div>
      </div>
    </script>
    <script id="status-template" type="text/x-handlebars-template">
      <img class="icon left {{spin}}" src="images/icons/status/{{status}}.svg"/>
      <span>{{text}}</span>
    </script>
    <script type="text/javascript" src="./js/menubar.js"></script>
    <script type="text/javascript">
      window.$ = window.jQuery = require('jquery')
      // load core modules first
      var remote = require('electron').remote
      var ipcRenderer = require('electron').ipcRenderer
      var Handlebars = require('handlebars')
      var _ = require('lodash')
      var moment = require('moment')
      var logger = require('../script/logger.js')
      var MAX_LIST_LENGTH = 10
      var state = remote.getGlobal("state")
      var recents = []

      var statusTexts = {
        getting: 'Fetching...',
        syncing: 'Syncing...',
        putting: 'Uploading...',
        encrypting: 'Encrypting...',
        encrypted: 'Encrypted!',
        synced: 'Synced!',
        notsynced: 'Not synced!'
      }

      $(window).on('online', updateOnlineStatus)
      $(window).on('offline', updateOnlineStatus)
      updateOnlineStatus()

      $(window).load(function() {
        // attach click listners
        $('.navigationLink').each(function(index) {
          $(this).click(function() {
            if (this.hasAttribute('data-target')) {
              emittEvent(this.getAttribute('data-target'))
            }
          })
        })
        if (!_.isEmpty(status)) {
          // TODO: render
          updateStatus('synced')
        }

        if (!_.isEmpty(state.recents)) {
          // restore recents list
          _(state.recents).forEach(function(file) {
            updateList(file)
          })
        }
        // TODO: restore last synced file list
      })

      /* Helper functions */
      function updateStatus(status) {
        var sobj = {}
        sobj.status = (status === 'getting' || status === 'putting')
          ? 'syncing'
          : status
        sobj.text = statusTexts[status]
        sobj.spin = (sobj.status === 'syncing')
          ? 'spin'
          : ''
        var template = Handlebars.compile($('#status-template').html())
        var statusHTML = template(sobj)
        $('#status').html(statusHTML)
      }

      function updateList(file) {
        file.lastSyncedText = moment(file.lastSynced).fromNow()
        var fileList = $('#filesList')
        var fListItem = fileList.children()
        var template = Handlebars.compile($('#file-template').html())
        recents.push(_.cloneDeep(file))
        var fileHTML = template(file)
        fileList.prepend(fileHTML)
        if (fListItem.length > MAX_LIST_LENGTH) {
          while (fListItem.length > MAX_LIST_LENGTH) {
            fListItem.last().remove()
            recents.pop()
            fListItem = $('#filesList').children()
          }
        }
      }

      // TODO: account for 'encryted text'
      function updateMoments() {
        $("span[data-moment]").each(function(index) {
          var $this = $(this)
          var tmoment = $this.data('moment')
          var nmoment = moment(tmoment)
          $this.data(moment(tmoment).format())
          $this.text(nmoment.fromNow())
        })
      }

      /* Event emitters  */
      function emittEvent(event) {
        // send event to main
        if (event === 'quitApp') {
          state.recents = recents
        }
        logger.verbose(`RENDER: ${event} event emitted`)
        ipcRenderer.send(event)
      }

      // Network change event
      function updateOnlineStatus() {
        ipcRenderer.send('online-status-changed', navigator.onLine
          ? 'online'
          : 'offline')
      }

      /* Event listeners */
      ipcRenderer.on('statusChange', function(event, status) {
        logger.verbose('IPCRENDER: statusChange emitted')
        updateStatus(status)
      })

      ipcRenderer.on('updateMoments', function(event) {
        logger.verbose('IPCRENDER: updateMoment emitted')
        updateMoments()
      })

      ipcRenderer.on('synced', function(event, file) {
        logger.verbose('IPCRENDER: synced emitted')
        file.fileType = resolveFileType(file.fileType)
        updateList(file)
      })
    </script>
  </body>

</html>