Closed Bug 756272 Opened 12 years ago Closed 12 years ago

Prototype Accordion Drawer

Categories

(Pancake Graveyard :: Front-end, enhancement)

x86
macOS
enhancement
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: gbrander, Assigned: gbrander)

References

Details

Attachments

(3 files)

Build an HTML prototype for the accordion drawer shown below. This drawer attempts to address usability issues that came up during initial testing.

Goals for the prototype:

* Keep it simple -- this is meant to be the equivalent of a greybox wireframe
* Focus on animation and interaction
* Attempt to write JavaScript, structural styles that can be re-used in the actual app.
Concept 2 received the most applause during call, so going forward with prototyping that one.
Another goal: get a good feel for how this kind of drawer would feel in real life. To that end, use real search terms and page titles.
Repository for prototype can be found here: https://bitbucket.org/gordonbrander/accordion-drawer-prototypes/overview
At this point the prototype renders from real views, models and collections.

    StackCollection
      StackModel
        eras() -> EraCollection
          EraModel
            places() -> PlaceCollection
              Place

drawerviews.js contains view rendering code for all three layers (Stack, Era, Place).

ListView has been updated and now keeps an semi-private array of sub-views. You can get a copy via the `views()` method. This allows us to determine where a view is in the list, and how to render it in conjunction with it's siblings.

With this change to ListView, I've begun to work on animating item moves in the list view. This essentially consists of:

* Measuring the total height of `PlaceView`s and fixing the height of the parent element.
* Absolutely positioning `PlaceView`s and giving them a `top` offset equal to the sum of the heights of their preceding siblings.
* Setting a CSS transition on `top`

Moving a place, then, simply consists of changing the value of the `top` property.

Still TODO:

* parse method for eras
* sync code for eras
Backbone collections don't have the concept of `move`ing a model. I think we're going to want to introduce it. Currently we approximate this by removing the model and view, and then immediately adding the model to the new location (which automatically spins off a new view object for the model).

This approximation is ok, but limits what we can do with animation. One usually wishes to transition, rather than add/remove a movement.

I plan on adding a `move` event to collections, along with a corresponding `move` method.

Views will also have a `move` method, in addition to their standard `render` and `remove` methods.
TODO: When moving a stack to the top era, we need to create a "now" era if none exists yet.
We still need to re-calculate the height of the StackView when a place is added or removed.

The StackModel is getting a change event whenever the active place is changed. This is because selectPlace changes the active place_id on the stack, and StackModel `render()` is bound to change events on the StackModel.

How do we want events to be republished? Backbone refuses to republish add and remove events for other collections on collections, and that's probably smart -- otherwise one would have to check for the event origin before doing anything in a handler. What a hassle.

It might make more sense to republish events with a prefix. Something like:

    `add:place`
    `remove:place`
    `change:place.title`

This probably means creating some kind of sub-collection provisioning function.
https://bitbucket.org/gordonbrander/accordion-drawer-prototypes/changeset/7ff5f840e5e6

Changed `PlaceCollection.stack` from a property to a method. This allows:

1. PlaceCollection to be backwards-compatible
2. PlaceCollection to be a child of Era
3. calculation of stack at run-time (you don't need a stack to instantiate a PlaceCollection). The default implementation crawls up the parent()
chain. Additionally, if you pass in a `stack` option, a function will be created that returns the value.

Unfortunately, changing from a prop to a method means we have to touch a lot of files, since this reference was used in quite a few places.

Searching 126 files for "collection.stack"

/Users/gordonb/Dev/pancake/repo/accordion-drawer-prototypes/static/js/controllers/homecontroller.js:
   64        // back up to the stack and grab its URL, just in case.
   65        // 
   66:       // SiteModel.PlaceCollection.StackModel.StackCollection
   67:       url: model.collection.stack.collection.url(),
   68  
   69        success: function (model) {

/Users/gordonb/Dev/pancake/repo/accordion-drawer-prototypes/static/js/controllers/searchcontroller.js:
   49        // `lattice/:username/stack/search`. Instead of hard-coding, crawl
   50        // back up to the stack and grab its URL, just in case.
   51:       url: model.collection.stack.collection.url(),
   52        success: function (model) {
   53          var data = util.extend(model.toJSON(), { origin: config.appName });

/Users/gordonb/Dev/pancake/repo/accordion-drawer-prototypes/static/js/views/drawerviews.js:
   51        var prevPlaceCollection = model.collection;
   52        // Capture the stack reference from the placeCollection.
   53:       var stack = prevPlaceCollection.stack;
   54        var nextPlaceCollection = stack.eras().at(0).places();
   55  

/Users/gordonb/Dev/pancake/repo/accordion-drawer-prototypes/static/js/views/stackplacesview.js:
   93  
   94          // Issue a warp request to Lattice.
   95:         collection.stack.warp(place_id);
   96        }, this);
   97      },

5 matches across 4 files
We now republish subcollection events on their parent model (with a prefix). Events will continue to bubble up through parent collections and models provided that they have a key prefix (e.g. `place add`).

With this addition, the drawer now reacts appropriately to place add and remove.

https://bitbucket.org/gordonbrander/accordion-drawer-prototypes/changeset/2421bec97591
The prototype at http://people.mozilla.com/~gbrander/accordion-drawer-prototypes/ is fairly complete.

Per conversation with Stuart, I'm going to hold off on fixing the top and bottom of a stack to the screen edges when open. This is a nice UI feature, but will be difficult to implement. It makes strategic sense to begin merging this with the actual app, since the UX is a drastic improvement.

(In reply to Gordon Brander :gbrander from comment #11)
> TODO: When moving a stack to the top era, we need to create a "now" era if
> none exists yet.

This can be taken care of in a click handler while integrating with the app.

Closing.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Blocks: 758019
Blocks: 760606
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: