Update resize handle for new designs
The diff should have information on what this does and how it is supposed to work.pull/21833/head
parent
7549d7d98a
commit
5f8b7187cf
|
@ -16,10 +16,6 @@ limitations under the License.
|
||||||
|
|
||||||
// TODO: Rename to mx_RoomSublist during replacement of old component
|
// TODO: Rename to mx_RoomSublist during replacement of old component
|
||||||
|
|
||||||
// TODO: Just use the 3 selectors we need from this instead of importing it.
|
|
||||||
// We're going to end up with heavy modifications anyways.
|
|
||||||
@import "../../../../node_modules/react-resizable/css/styles.css";
|
|
||||||
|
|
||||||
.mx_RoomSublist2 {
|
.mx_RoomSublist2 {
|
||||||
// The sublist is a column of rows, essentially
|
// The sublist is a column of rows, essentially
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -63,18 +59,83 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomSublist2_resizeBox {
|
.mx_RoomSublist2_resizeBox {
|
||||||
|
margin-bottom: 4px; // for the resize handle
|
||||||
|
position: relative;
|
||||||
|
|
||||||
// Create another flexbox column for the tiles
|
// Create another flexbox column for the tiles
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.mx_RoomSublist2_showMoreButton {
|
.mx_RoomSublist2_showMoreButton {
|
||||||
height: 44px; // 1 room tile high
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
font-size: $font-13px;
|
||||||
|
line-height: $font-18px;
|
||||||
|
color: $roomtile2-preview-color;
|
||||||
|
|
||||||
|
// This is the same color as the left panel background because it needs
|
||||||
|
// to occlude the lastmost tile in the list.
|
||||||
|
background-color: $header-panel-bg-color;
|
||||||
|
|
||||||
|
// Update the render() function for RoomSublist2 if these change
|
||||||
|
// Update the ListLayout class for minVisibleTiles if these change.
|
||||||
|
//
|
||||||
|
// At 24px high and 8px padding on the top this equates to 0.65 of
|
||||||
|
// a tile due to how the padding calculations work.
|
||||||
|
height: 24px;
|
||||||
|
padding-top: 8px;
|
||||||
|
|
||||||
|
// We force this to the bottom so it will overlap rooms as needed.
|
||||||
|
// We account for the space it takes up (24px) in the code through padding.
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4px; // the height of the resize handle
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
// We create a flexbox to cheat at alignment
|
// We create a flexbox to cheat at alignment
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
.mx_RoomSublist2_showMoreButtonChevron {
|
||||||
|
position: relative;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: 12px;
|
||||||
|
margin-right: 18px;
|
||||||
|
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||||
|
mask-position: center;
|
||||||
|
mask-size: contain;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
background: $roomtile2-preview-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class name comes from the ResizableBox component
|
||||||
|
// The hover state needs to use the whole sublist, not just the resizable box,
|
||||||
|
// so that selector is below and one level higher.
|
||||||
|
.react-resizable-handle {
|
||||||
|
cursor: ns-resize;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
// This is positioned directly below the 'show more' button.
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
// This is to visually align the bar in the list. Should be 12px from
|
||||||
|
// either side of the list. We define this after the positioning to
|
||||||
|
// trick the browser.
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The aforementioned selector for the hover state.
|
||||||
|
&:hover .react-resizable-handle {
|
||||||
|
opacity: 0.2;
|
||||||
|
|
||||||
|
// Update the render() function for RoomSublist2 if this changes
|
||||||
|
border: 2px solid $primary-fg-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,46 +178,61 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
let content = null;
|
let content = null;
|
||||||
if (tiles.length > 0) {
|
if (tiles.length > 0) {
|
||||||
|
const layout = this.props.layout; // to shorten calls
|
||||||
|
|
||||||
// TODO: Lazy list rendering
|
// TODO: Lazy list rendering
|
||||||
// TODO: Whatever scrolling magic needs to happen here
|
// TODO: Whatever scrolling magic needs to happen here
|
||||||
const layout = this.props.layout; // to shorten calls
|
|
||||||
const minTilesPx = layout.tilesToPixels(Math.min(tiles.length, layout.minVisibleTiles));
|
const nVisible = Math.floor(layout.visibleTiles);
|
||||||
const maxTilesPx = layout.tilesToPixels(tiles.length);
|
const visibleTiles = tiles.slice(0, nVisible);
|
||||||
const tilesPx = layout.tilesToPixels(Math.min(tiles.length, layout.visibleTiles));
|
|
||||||
|
// If we're hiding rooms, show a 'show more' button to the user. This button
|
||||||
|
// floats above the resize handle, if we have one present
|
||||||
|
let showMoreButton = null;
|
||||||
|
if (tiles.length > nVisible) {
|
||||||
|
// we have a cutoff condition - add the button to show all
|
||||||
|
const numMissing = tiles.length - visibleTiles.length;
|
||||||
|
showMoreButton = (
|
||||||
|
<div onClick={this.onShowAllClick} className='mx_RoomSublist2_showMoreButton'>
|
||||||
|
<span className='mx_RoomSublist2_showMoreButtonChevron'>
|
||||||
|
{/* set by CSS masking */}
|
||||||
|
</span>
|
||||||
|
<span className='mx_RoomSublist2_showMoreButtonText'>
|
||||||
|
{_t("Show %(count)s more", {count: numMissing})}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out if we need a handle
|
||||||
let handles = ['s'];
|
let handles = ['s'];
|
||||||
if (layout.visibleTiles >= tiles.length && tiles.length <= layout.minVisibleTiles) {
|
if (layout.visibleTiles >= tiles.length && tiles.length <= layout.minVisibleTiles) {
|
||||||
handles = []; // no handles, we're at a minimum
|
handles = []; // no handles, we're at a minimum
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This might need adjustment, however for now it is fine as a round.
|
// We have to account for padding so we can accommodate a 'show more' button and
|
||||||
const nVisible = Math.round(layout.visibleTiles);
|
// the resize handle, which are pinned to the bottom of the container. This is the
|
||||||
const visibleTiles = tiles.slice(0, nVisible);
|
// easiest way to have a resize handle below the button as otherwise we're writing
|
||||||
|
// our own resize handling and that doesn't sound fun.
|
||||||
|
//
|
||||||
|
// The layout class has some helpers for dealing with padding, as we don't want to
|
||||||
|
// apply it in all cases. If we apply it in all cases, the resizing feels like it
|
||||||
|
// goes backwards and can become wildly incorrect (visibleTiles says 18 when there's
|
||||||
|
// only mathematically 7 possible).
|
||||||
|
|
||||||
// If we're hiding rooms, show a 'show more' button to the user. This button
|
const showMoreHeight = 32; // As defined by CSS
|
||||||
// replaces the last visible tile, so will always show 2+ rooms. We do this
|
const resizeHandleHeight = 4; // As defined by CSS
|
||||||
// because if it said "show 1 more room" we had might as well show that room
|
|
||||||
// instead. We also replace the last item so we don't have to adjust our math
|
|
||||||
// on pixel heights, etc. It's much easier to pretend the button is a tile.
|
|
||||||
if (tiles.length > nVisible) {
|
|
||||||
// we have a cutoff condition - add the button to show all
|
|
||||||
|
|
||||||
// we +1 to account for the room we're about to hide with our 'show more' button
|
// The padding is variable though, so figure out what we need padding for.
|
||||||
// this results in the button always being 1+, and not needing an i18n `count`.
|
let padding = 0;
|
||||||
const numMissing = (tiles.length - visibleTiles.length) + 1;
|
if (showMoreButton) padding += showMoreHeight;
|
||||||
|
if (handles.length > 0) padding += resizeHandleHeight;
|
||||||
|
|
||||||
|
const minTilesPx = layout.calculateTilesToPixelsMin(tiles.length, layout.minVisibleTiles, padding);
|
||||||
|
const maxTilesPx = layout.tilesToPixelsWithPadding(tiles.length, padding);
|
||||||
|
const tilesWithoutPadding = Math.min(tiles.length, layout.visibleTiles);
|
||||||
|
const tilesPx = layout.calculateTilesToPixelsMin(tiles.length, tilesWithoutPadding, padding);
|
||||||
|
|
||||||
// TODO: CSS TBD
|
|
||||||
// TODO: Make this an actual tile
|
|
||||||
// TODO: This is likely to pop out of the list, consider that.
|
|
||||||
visibleTiles.splice(visibleTiles.length - 1, 1, (
|
|
||||||
<div
|
|
||||||
onClick={this.onShowAllClick}
|
|
||||||
className='mx_RoomSublist2_showMoreButton'
|
|
||||||
key='showall'
|
|
||||||
>
|
|
||||||
{_t("Show %(n)s more", {n: numMissing})}
|
|
||||||
</div>
|
|
||||||
));
|
|
||||||
}
|
|
||||||
content = (
|
content = (
|
||||||
<ResizableBox
|
<ResizableBox
|
||||||
width={-1}
|
width={-1}
|
||||||
|
@ -230,6 +245,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
className="mx_RoomSublist2_resizeBox"
|
className="mx_RoomSublist2_resizeBox"
|
||||||
>
|
>
|
||||||
{visibleTiles}
|
{visibleTiles}
|
||||||
|
{showMoreButton}
|
||||||
</ResizableBox>
|
</ResizableBox>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1134,7 +1134,8 @@
|
||||||
"Securely back up your keys to avoid losing them. <a>Learn more.</a>": "Securely back up your keys to avoid losing them. <a>Learn more.</a>",
|
"Securely back up your keys to avoid losing them. <a>Learn more.</a>": "Securely back up your keys to avoid losing them. <a>Learn more.</a>",
|
||||||
"Not now": "Not now",
|
"Not now": "Not now",
|
||||||
"Don't ask me again": "Don't ask me again",
|
"Don't ask me again": "Don't ask me again",
|
||||||
"Show %(n)s more": "Show %(n)s more",
|
"Show %(count)s more|one": "Show %(count)s more",
|
||||||
|
"Show %(count)s more|other": "Show %(count)s more",
|
||||||
"Options": "Options",
|
"Options": "Options",
|
||||||
"%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.",
|
"%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.",
|
||||||
"%(count)s unread messages including mentions.|one": "1 unread mention.",
|
"%(count)s unread messages including mentions.|one": "1 unread mention.",
|
||||||
|
|
|
@ -52,7 +52,24 @@ export class ListLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
public get minVisibleTiles(): number {
|
public get minVisibleTiles(): number {
|
||||||
return 3;
|
// the .65 comes from the CSS where the show more button is
|
||||||
|
// mathematically 65% of a tile when floating.
|
||||||
|
return 4.65;
|
||||||
|
}
|
||||||
|
|
||||||
|
public calculateTilesToPixelsMin(maxTiles: number, n: number, possiblePadding: number): number {
|
||||||
|
// Only apply the padding if we're about to use maxTiles as we need to
|
||||||
|
// plan for the padding. If we're using n, the padding is already accounted
|
||||||
|
// for by the resizing stuff.
|
||||||
|
let padding = 0;
|
||||||
|
if (maxTiles < n) {
|
||||||
|
padding = possiblePadding;
|
||||||
|
}
|
||||||
|
return this.tilesToPixels(Math.min(maxTiles, n)) + padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public tilesToPixelsWithPadding(n: number, padding: number): number {
|
||||||
|
return this.tilesToPixels(n) + padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public tilesToPixels(n: number): number {
|
public tilesToPixels(n: number): number {
|
||||||
|
|
Loading…
Reference in New Issue