web-library icon indicating copy to clipboard operation
web-library copied to clipboard

Implement touch header navigation

Open flachware opened this issue 8 years ago • 11 comments

To-do:

  • [x] 1. Render titles, set title classes
  • [ ] 2. Set current title offset
  • [ ] 3. Truncate next title

@tnajdek I added the scaffold for the touch header implementation to library.jsx.

It is based on the mobile nav POC you have already seen. But unlike the POC, it does not work with a combination of a global 'current' class with individual 'title' classes, but with 4 generic states: .forelast, .previous, .current, and .next. These classes have to be set dynamically and simultaneously on the respective titles.

It makes probably sense to dynamically add new .next elements at the end of the list and take away old .forelast elements, so the list would never have more than 4 list items (from the visual point of view, more elements would not matter, only the ones with the 4 classes get displayed).

If you think it would be too cumbersome this way, I can imagine to go back to the POC approach and we only set a class with the current state on the list, I could pregenerate all needed styles for .title-1, .title-2, .title-3, etc. with loops in Sass too (with an arbitrary limit). In any case you will have to insert and take away the correct titles based on the user’s decisions.

Re 2.: At the moment titles are truncated with CSS when they are longer than a third of the viewport width. This should be optimized. We can remove the hard width limit and check the width (of the <span> inside) of title pairs that show up at once. So if e.g. 'My Libray' and 'Collection 1' do fit on the screen but only if the current title has a position slightly right to the 50% center, then we can calculate the overlap and target the transition to e.g. left: calc(50% + 17px).

Re 3.: Sometimes this won’t be enough, so we have to truncate a title. As far as I have seen, native apps usually only truncate titles that come next into the view but do not truncate the current title while it moves to the previous position on the left. In this case the apps either fade out the current title entirely or cross-fade it with a generic 'Back' text. The next title can be full, truncated, and with offset then.

flachware avatar Feb 22 '17 13:02 flachware

Didn't mean to close it with a commit just yet.

So far I've implemented current and previous, including the ability to return to the root of the collection tree. There is still some refactoring to be done.

@johanneskrtek what should go into .next? And into .forelast for that matter?

tnajdek avatar Mar 08 '17 13:03 tnajdek

@tnajdek if we want the mobile header to behave like in the POC, then we cannot just change the texts in .current and .previous, but we have to switch classes and add elements at the end of the list and remove elements at the start of the list. we also have to update all four classes with each step. note that each switch of a class triggers a css transition.

E.g. / is .current. when you click, collection-1 is inserted in .next and the .current class has to switch to .previous and the .next class to .current. a new .next element has to be created at the end of the list.

Next click, collection-1-1 is inserted in .next, the .previous class has to switch to .forelast, the .current class has to switch to .previous and the .next class to .current. the .forelast element has to be removed and a new .next element has to be created and so on.

Of course this has to work in both directions – if the classes are set correctly (and the elements are added/removed accordingly) it already should.

Maybe the easiest way to get the idea is by simply changing the .current elements class to .previous and the .previous elements class to .forelast in the dev tools. You will see the texts moving to the left – that’s what they should do.

Now that I am writing about it I guess forelast should rather be called first or before-previous.

flachware avatar Mar 08 '17 19:03 flachware

yepp, will do, thanks for clarifying

tnajdek avatar Mar 09 '17 14:03 tnajdek

@johanneskrtek I believe I've got it to work nicely with animations with the above commit. Could you please have a look and confirm it works as expected?

If you're happy with it, I'm going to try address 2) on your list but again some clarification would be useful.

Finally I think we probably want a home icon (or similar) instead of / to get back to the "root" folder.

tnajdek avatar Mar 11 '17 18:03 tnajdek

@tnajdek looks good to me!

The logic works as expected now. Also the CSS transitions – but they are not as smooth as they could be (I think this has to do with the simultaneous transition of the left and transform properties. I would like to rework the structure and styles and use 3d transforms only. A quick test looked promising. So, I would suggest you wait until I commit this change until you proceed.

Re 2) In iOS it is a common pattern to optimize those headers in the following way: the titles are not truncated (unless it is inevitable) but the current title just moves a bit to the right so both previous and current find enough space without overlap. The easist way I can imagine to achieve this (but if you find a better way, go for it) would be to calculate the overlap and move the current title a little to the right. Calculating the overlap should not be too hard, as you can get the widths of the two spans in question and we also know the end position of both (left and center).

E.g. (let’s ignore paddings for now) the viewport has 320px width, previous has 100px width and current 150px width. 100 + 150 / 2 - 320 / 2 = 15. In this case we could position current 15px to the right (with inline styles using transform: translate3d(calc(-50% + 15px), 0, 0); Of course there will be some more details to take in account (paddings, chevron icon back, some spacing between the two titles, option icon on the right side), but you get the idea. In this step 2 we would remove the CSS truncation and tweak the header for longer titles that barely fit and in step 3 we would add a mechanism that deals with situations where step 2 is not enough anymore. If you have further questions on 2, please let me know.

We definitely shouldn’t use / for the root, how about 'Library' (in the drafts I had 'My Library', but 'Library' makes more sense actually as it also includes the Group Libraries)?

flachware avatar Mar 14 '17 18:03 flachware

@tnajdek I reimplemented the touch header with 3d transforms only (there has been some stuttering at the end of the transitions before). I also removed the CSS truncation for now. So we should be good for step 2.

One remark: When I click on .previous the .current title disappears immediately instead of getting .next and translating out of the viewport. I don’t know what exactly is wrong there, but that’s how it looks like.

flachware avatar Mar 17 '17 13:03 flachware

@tnajdek I realized that the touch header is missing the last step currently: so when I choose an item in the item-list, the touch header has to update a last time. In the example below collection-1-1 should have the .before-last class (I renamed that one) and collection-1-1-1 should have .previous

screen shot 2017-04-11 at 18 02 05

flachware avatar Apr 11 '17 16:04 flachware

@tnajdek in order to complete #84 we will need some enhancements in the touch header:

On touch devices we have an edit mode, which can be entered by clicking 'edit' in the touch header. While the user is in edit mode, the touch header should show 'cancel', 'save' and temporarily a spinner in the processing state.

Now, in Tropy we have a very similar situation in the editor toolbar: if you click on the 'link' icon, the toolbar temporarily shows different tools (in this case an input field and a button to enter the link target). We implemented this in Tropy with multiple, context-specific containers in the toolbar. Those 'context containers' can have 3 states: default, .active and .has-active. I chose that approach because it makes it easier to think about the tools currently being visible on the one hand, on the other hand this is a generic way to have an arbitrary amount of toolbars that can have sub-toolbars and the switch can be animated. If you click on the 'link' icon, all the currently visible tools slide out of sight upwards while simultaneously the 'sub-toolbar' slides in from the bottom edge of the toolbar. This is done by switching the .active class of the main context toolbar to .has-active (so it slides up) and setting the class .active to the sub-toolbar (so it slides in).

I think this approach could work for the different states of our touch header too, which has to show different elements in different contexts. We do not necessarily have to use slide in/out, could also be a cross-fade but with those additional context containers we would be flexible to do what we want.

What do you think?

flachware avatar Apr 15 '17 15:04 flachware

@flachware I believe touch headers are in quite decent state now, can this be closed?

tnajdek avatar Dec 19 '18 12:12 tnajdek

Actually I believe #149 supersedes this, hence closing.

tnajdek avatar Dec 19 '18 12:12 tnajdek

This issue is also about how to handle the space in the touch header in a better way, therefore I’m reopening it, but I made it a post 1.0 issue.

flachware avatar Dec 20 '18 08:12 flachware