lduarte1991 / hxat

Contains the currently-in-development project by HarvardX to bring the annotation tool currently living in the edX platform to a more accessible LTI implementation.
12 stars 7 forks source link

Django2.0 hxighlighter #107

Closed lduarte1991 closed 5 years ago

lduarte1991 commented 5 years ago

Introducing new UI (Hxighlighter) to the HxAT. Already-made assignments will by default still use the old versions, but can choose to change to the new version. Annotations made in the new version cannot be seen in the old version (and vice versa).

New feature added: Display name for all instructor staff. If left empty, the display name will be each individual's username. Otherwise, the name chosen will be used for ALL people set as "admin" in course settings. Note: all admins are instructors, but not all instructors are admin.

Here are the updated/new features you should expect:

  1. Annotator.JS is 100% gone (well it’s still in the codebase, but not being used and I’ll remove the actual code soon). I went through the process of recreating a Range library from scratch that uses backup methods for selection/drawing of annotations.For example, it defaults to exact XPath + offset matching. This will be the quickest and most accurate. If that fails, it will look at global text offset (i.e. the instructor changed an html tag and while nothing has changed words-wise, the structure has changed). If that fails, it will look at the quote along with a prefix and suffix to find the location (i.e. the instructor added text at the beginning).This won’t solve if there has been content inside that has been changed, but I left a spot open in case someone wants to tackle some fuzzy-search, or other, algorithm.
  2. The look of the editor has changed. It’s a little bit more square and minimalist, but bigger to leave more room. Same with the viewer.
  3. I’ve increased the timer for the viewer to disappear when hovering over a highlighted region, this was one of the more common complaints.
  4. When the learner clicks on the highlight, the viewer will be “pinned” and will remain even when not hovering. The learner then is able to move the viewer window around by clicking and dragging on the top bar.
  5. When the viewer is pinned, the learner is able to increase the height of the window by clicking and dragging the bottom border.
  6. The learner is able to reply directly on the viewer.
  7. The learner is able to reply in the sidebar without going to the previous modal view.
  8. Clicking anywhere on the annotation in the sidebar will scroll the screen to selected text and an animation will emphasize the selected highlight.
  9. (optional) Instructor can select a common display name for all annotations made by a set of instructors for a course. (i.e. in a ChinaX course, the professor, project lead, and TFs all make annotations for the learners, but instead of seeing their individual names, all annotations will be seen as “ChinaX Staff” or whatever the instructor desire).
  10. Instructors will have a little badge next to them to differentiate them from other annotations.
  11. “Tabs” are now filters that can be turned on simultaneously.For example, before if you made annotations and wanted to compare with the instructor’s annotations you’d have to go to “My Notes” and view your own and then view “Instructor” separately. Now, you are able to turn both on at once.
  12. Names of tabs have been changed to “Mine” “Peer” and “instructor”
  13. Turning off all tabs will result in a message telling the user that they need to pick at least one of the filters. This allows for self-exploration with guidance.
  14. The tab headers are now fixed to the top and won’t scroll off screen when scrolling annotations
  15. Search tab has been made its own tab that will display a field and options only when needed
  16. Instructor can choose “top tags” to display at the top that will automatically filter annotations with a given tag (eventually there should be a catchpy api call that will determine what are the most common tags and build this dynamically)
  17. Clicking on a username will flip open the search tab and search for that person’s annotations
  18. Clicking on a tag will flip open the search tab and search for annotations containing that tag
  19. Keyboard annotations have been updated to meet the new range library and should match EXACTLY with mouse annotations (unlike before).
  20. Deleting an annotation always triggers a confirmation dialog box before deleting.
  21. When you create an annotation and you don’t have “Mine” selected, a little badge will appear.
  22. Catchpy alerts show up with better messages given the status code returned
arthurian commented 5 years ago

Annotations made in the new version cannot be seen in the old version (and vice versa).

@lduarte1991 How are the annotations being kept separate between the two versions? Is there additional context added to the annotations that is being used to filter out the old ones?

For new courses, this behavior should be completely fine, but I'm thinking of a few long-running/ongoing tool instances where we may want to upgrade to hxighlighter and carry over the annotations. Will that require updating annotations on the catchpy backend?

arthurian commented 5 years ago

When the learner clicks on the highlight, the viewer will be “pinned” and will remain even when not hovering. The learner then is able to move the viewer window around by clicking and dragging on the top bar.

This is a great feature! Just an FYI - one minor thing I noticed while playing with this feature is that when I pinned one annotation and then clicked on another annotation, the first annotation stayed pinned and nothing happened with the second annotation. I was surprised because I thought maybe clicking on the second annotation would either replace the pinned annotation with that one or open a new pin. It worked well, however, when I closed that first pin, and then clicked on the second annotation. Is that the expected behavior currently?

nmaekawa commented 5 years ago

Annotations made in the new version cannot be seen in the old version (and vice versa).

@lduarte1991 How are the annotations being kept separate between the two versions? Is there additional context added to the annotations that is being used to filter out the old ones?

For new courses, this behavior should be completely fine, but I'm thinking of a few long-running/ongoing tool instances where we may want to upgrade to hxighlighter and carry over the annotations. Will that require updating annotations on the catchpy backend?

catchpy converts annotatorjs into webannotation and stores everything as webannotation. The main difference is that, for annotatorjs, catchpy forces the annotation id to be an integer (while in webannotation it's a uuid). If an annotation is created as webannotation it cannot be read as annotatorjs mainly because the annotatorjs client expects the id to be an integer and i'm not sure what the behavior is when an uuid is sent (maybe it just ignores the annotation, i don't remember!). Anyway, annotations created via annotatorjs api can be read/searched/updated/etc via webannotator api, but the opposite is not possible. So, once you update to hxighlighter, it will use the webannotator api and you cannot go back to the old UI client (because it uses annotatorjs api), but annotations already created are still fine and don't require any update.

lduarte1991 commented 5 years ago

How are the annotations being kept separate between the two versions? Is there additional context added to the annotations that is being used to filter out the old ones?

@arthurian To add to @nmaekawa above: From the HxAT's perspective (following the Swagger spec here), annotations made via Hxighlighter is expecting webannotations and thus uses the api methods under "catchpy" which means that everything points to "/annos" with POST/PUT/DELETE/GET method, whereas annotations made via the soon-to-be-legacy annotator-js version uses the set of api calls under the "old catch annotator" section. These urls send with "annos/search" and "annos/update". So you should see some changes to annotation_store included here.

In reality, in either case they get stored together. Because of inconsistency in the models, like the string/int ids mentioned above, errors (or worse, successes with data loss) might occur when trying to retrieve annotations made in a different model than the one they were created. I think I've made changes to Hxighlighter to be able to work with the xpath range that annotatorjs was looking to create, but I cannot guarantee that it will work 100% or if I missed some usecases.

When the learner clicks on the highlight, the viewer will be “pinned” and will remain even when not hovering. The learner then is able to move the viewer window around by clicking and dragging on the top bar.

This is a great feature! Just an FYI - one minor thing I noticed while playing with this feature is that when I pinned one annotation and then clicked on another annotation, the first annotation stayed pinned and nothing happened with the second annotation. I was surprised because I thought maybe clicking on the second annotation would either replace the pinned annotation with that one or open a new pin. It worked well, however, when I closed that first pin, and then clicked on the second annotation. Is that the expected behavior currently?

It is the expected behavior, if you click on something the assumption is made you want it around until you explicitly send it away. If you try to click on something else and nothing happens we hope to get across the fact that you cannot have multiple windows open at the same time. That being said, I totally get where you are coming from, so let me ask around and see what other people who have QA-ed the tool think.

arthurian commented 5 years ago

@lduarte1991 @nmaekawa Thanks for clarifying the point about the two different versions. I definitely see the changes to the annotation_store that point to the "/annos" interface. It makes sense now that once the upgrade has happened, it's not feasible to go back due to the incompatibilities/inconsistencies in the two models (annotatorjs vs webannotation).

@lduarte1991 Thanks for confirming that behavior was intended -- I figured only one annotation could be pinned at a time, I just wasn't sure what was expected when you tried to pin another one with one already open. Requiring the user to explicitly close the open pin is very reasonable (especially so they don't accidentally close a pin they didn't mean to).