1. 06 Jan, 2016 4 commits
    • Robert Knight's avatar
      Truncated excerpt design tweaks · c7687b68
      Robert Knight authored
       * Increase the expansion speed
      
       * Make the drop-shadow at the bottom of collapsed annotation bodies
         expand to the full width of the annotation card and be clickable
         to provide an easier-to-hit target for expanding collapsed
         annotations
      
       * Make the shadow non-clickable when hidden after expansion
      c7687b68
    • Robert Knight's avatar
      Update the truncated state of the annotation when the feature flag changes · deeab8b2
      Robert Knight authored
      If the enabled state of the annotation changes after the view
      loaded, the truncation state did not update.
      
      With the current feature flag implementation this typically happens
      if the feature flags load after the session data has been received.
      In future the intention is to make feature flags part of the session
      data payload so this won't happen.
      deeab8b2
    • Robert Knight's avatar
      Fix expand/collapse controls not being shown when embedded media loads · 8839b89a
      Robert Knight authored
      When embedded media in an annotation loads, this may trigger
      a resize of the element's content and result in a change of whether
      expand/collapse controls need to be shown, outside of Angular's
      knowledge.
      
      The DOM doesn't provide a nice way to monitor for resizing
      of a specific elements (although hacks involving scroll events,
      hidden <iframes> etc. exist) so here we just monitor for 'load'
      events and trigger a digest in that case, as well as notifying
      the containing directive whenever the collapsible state changes.
      8839b89a
    • Robert Knight's avatar
      Implement new annotation card truncation design · 9e117768
      Robert Knight authored
      This implements the new annotation card truncation design
      from https://trello.com/c/Jg0NWyF3/
      
      The main consequence of the change is to make the annotation
      cards more compact when truncation is enabled by:
      
       * Reducing the number of quote lines shown from 3 to 2
      
       * Showing the link to expand truncated quotes at the end
         of the second line of the quote, instead of on its own
         line
      
       * Moving the link to expand truncated annotation bodies
         outside of the annotation body and into a control
         inline with the tags list.
      
         This has been implemented by giving the <excerpt> control
         two modes, one that shows inline expand/collapse controls
         and a second that allows the containing directive to
         implement its own controls.
      9e117768
  2. 22 Dec, 2015 4 commits
    • Sean Hammond's avatar
      Merge pull request #2825 from hypothesis/gh2819-new-annot-timestamp · b8140413
      Sean Hammond authored
      Update annotation timestamp when creating and editing annotations
      b8140413
    • Robert Knight's avatar
      Refactor duplicated function call · f123a91a
      Robert Knight authored
      f123a91a
    • Robert Knight's avatar
      Refresh the view model when a new highlight is saved · fdbd4277
      Robert Knight authored
      When a new highlight is saved, updateViewModel() was called
      immediately after making the request to the server to save
      the highlight, but not after the response from the server
      is received, when additional properties such as the last-updated
      timestamp for the highlight, will have been set.
      fdbd4277
    • Robert Knight's avatar
      Update the displayed annotation timestamp immediately after creation/update · 37e2407a
      Robert Knight authored
      There were two problems here:
      
       1. The periodic interval for updating the timestamp was never started
          for new annotations because the initial call to updateTimestamp()
          was a no-op for annotations that had no timestamp yet.
      
       2. domainModel.updated was never updated after an annotation
          was saved to the server and hence the call to
          updateTimestamp() re-used the old timestamp.
      
      (1) is fixed now by restarting the interval using the current
      last-updated timestamp whenever the view model is updated.
      
      (2) is fixed indirectly now by moving the logic to update
      the timestamp into updateViewModel(), so that all updates
      to it happen in one place. When an annotation is updated,
      the updated domain model returned by the server is the one
      passed into updateViewModel() to update it.
      
       * Separate out the logic for creating a decaying interval
         whose frequency depends on the age of some input timestamp,
         and updating the timestamp string on each interval.
      
         The decaying interval is now handled by 'time.decayingInterval'
      
       * Trigger a restart of the interval whenever the view model is
         updated in response to a change to the annotation
      
      Fixes #2819
      Fixes #2822
      37e2407a
  3. 18 Dec, 2015 15 commits
  4. 17 Dec, 2015 5 commits
    • Robert Knight's avatar
      Merge pull request #2805 from hypothesis/TPUsXCk4-add-media-embeds-feature · 1a3d7e0d
      Robert Knight authored
      Add media embeds feature
      1a3d7e0d
    • Sean Hammond's avatar
      Render YouTube and Vimeo links as video embeds · e5beb610
      Sean Hammond authored
      Client-side, replace any links to YouTube or Vimeo videos in annotation
      body texts with <iframe> video embeds for those same videos.
      
      Behind a new feature flag.
      
      markdown.coffee: after rendering the user's markdown text to HTML and
      sanitizing it, compile the HTML string into a DOM element and insert it into
      the DOM using innerHTML from JavaScript, instead of using Angular's
      ng-bind-html to insert the HTML string into the DOM.
      
      This means that our CoffeeScript code in markdown.coffee has the rendered
      annotation body as a DOM element, and can use the DOM API to modify it before
      inserting it into the DOM.
      
      Take advantage of this to find video links in the HTML and replace them with
      embeds. This is done by a standalone media-embedder.js module that
      markdown.coffee calls.
      
      This module is designed to allow functions for generating embeds for different
      kinds of URLs to be plugged in. So far functions for a few different kinds of
      YouTube and Vimeo URLs are implemented, but further functions for more
      media types can be added.
      e5beb610
    • Robert Knight's avatar
      Remove Moment.js · a07d0f77
      Robert Knight authored
      Moment.js is only used in a single place, for converting ISO8601 date-time strings
      from the annotation's 'updated' field to user-friendly
      date strings (eg. 'Wednesday 17 Dec, 18:59') for the tooltips
      for the last-updated link in the annotation card.
      
      Replacing this with functions from the built-in Date object saves
      167KB from the generated bundle size (see
      moment/min/moment-with-locales.min.js) and also speeds up the digest
      cycle. For 20 annotation cards in the /stream view, generating the
      date string used to take 6-7ms with Moment. It takes <2ms with
      the built in functions in a current build of Chrome.
      
      This still shows up as the most expensive watch expression, so
      we might want to add caching as well.
      a07d0f77
    • Robert Knight's avatar
      Merge pull request #2804 from hypothesis/jscs-require-spaces-after-function · 22aa37eb
      Robert Knight authored
      jscs: Require `function () {}`
      22aa37eb
    • Sean Hammond's avatar
      jscs: Require `function () {}` · 5a514035
      Sean Hammond authored
      Change jscs's required style from `function()` to `function ()`.
      
      We always require a space after the `function` keyword, and before {}
      braces, but we do not allow a space between a function name and its ()
      braces:
      
          var foo1 = function () {};  // Right.
          var foo2 = function() {};  // Wrong.
          var foo3 = function (){};  // Wrong.
      
          var foo4 = function foo4() {};  // Right.
          var foo5 = function foo5 () {};  // Wrong.
          var foo6 = function foo6(){};  // Wrong.
      
          function foo7() {}  // Right.
          function foo8 () {}  // Wrong.
          function foo9(){}  // Wrong.
      
      This deviates from the Google style guide and jscs presets that we use.
      5a514035
  5. 16 Dec, 2015 1 commit
  6. 15 Dec, 2015 3 commits
  7. 14 Dec, 2015 8 commits
    • Robert Knight's avatar
      Merge pull request #2800 from hypothesis/2799-dont-update-wrong-annotations · d1c0b894
      Robert Knight authored
      Don't update annotations with contents of others
      d1c0b894
    • Sean Hammond's avatar
      Don't update annotations with contents of others · b96d1749
      Sean Hammond authored
      When listening to the 'annotationUpdated' event, AnnotationController
      needs to check that it's this annotation that the event refers to before
      acting on it.
      
      Fixes #2799.
      b96d1749
    • Robert Knight's avatar
      Merge pull request #2781 from hypothesis/AnnotationController-domain-model-view-model-refactor · 9b3ef75c
      Robert Knight authored
      Annotation controller domain model view model refactor
      9b3ef75c
    • Sean Hammond's avatar
      Delete an out-of-date comment · 2874e51a
      Sean Hammond authored
      2874e51a
    • Sean Hammond's avatar
      Don't document @returns undefined · 8183f821
      Sean Hammond authored
      8183f821
    • Sean Hammond's avatar
      Fix annotating while signed out · 5d198168
      Sean Hammond authored
      If the user creates annotations while signed out and then signs in, we
      want those annotations to still be present in the sidebar after sign in,
      rather than being lost.
      
      Commit 7a1b5ca8d99252d3a086a8a8103fca4702521d06 had inadvertently broken
      this.
      
      The problem is that app.coffee destroys all AnnotationController
      instances on sign in, and only creates new instances for those
      annotations that have drafts.
      
      7a1b5ca8d99252d3a086a8a8103fca4702521d06 removed a spurious call to
      saveToDrafts() in vm.edit() but it turns out that this call was
      (apparently inadvertently) the only thing that was causing drafts of
      annotations created while signed out to be saved, and hence the only
      thing causing these annotations to persist across sign ins.
      
      So add a listener for the USER_CHANGED event and save drafts of
      annotations on sign in, just before the AnnotationControllers get
      destroyed.
      5d198168
    • Sean Hammond's avatar
      Remove a couple of duplicate comments · 67e127e0
      Sean Hammond authored
      67e127e0
    • Sean Hammond's avatar
      Update AnnotationController on annotationUpdated · 56e99757
      Sean Hammond authored
      Update AnnotationController's view model on the "annotationUpdated" event.
      
      This fixes an issue that "live updates" were not being shown on annotation
      cards.
      
      The "annotationUpdated" event is fired by AnnotationController itself after
      successfully saving updates to an already-saved annotation. It's also fired by
      annotationMapper after received an updated annotation from the server (that was
      updated by a different client - the "live updates" feature).
      
      Subscribing to this event allows one function in AnnotationController to handle
      updating the view model in both cases.
      56e99757