mirror of
https://github.com/element-hq/element-web
synced 2024-11-23 17:56:01 +03:00
Merge pull request #4741 from matrix-org/travis/room-list/resize-handle
Update resize handle for new designs in new room list
This commit is contained in:
commit
78e1db9d30
4 changed files with 132 additions and 37 deletions
|
@ -16,10 +16,6 @@ limitations under the License.
|
|||
|
||||
// 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 {
|
||||
// The sublist is a column of rows, essentially
|
||||
display: flex;
|
||||
|
@ -63,18 +59,83 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_RoomSublist2_resizeBox {
|
||||
margin-bottom: 4px; // for the resize handle
|
||||
position: relative;
|
||||
|
||||
// Create another flexbox column for the tiles
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.mx_RoomSublist2_showMoreButton {
|
||||
height: 44px; // 1 room tile high
|
||||
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
|
||||
display: flex;
|
||||
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;
|
||||
if (tiles.length > 0) {
|
||||
const layout = this.props.layout; // to shorten calls
|
||||
|
||||
// TODO: Lazy list rendering
|
||||
// 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 maxTilesPx = layout.tilesToPixels(tiles.length);
|
||||
const tilesPx = layout.tilesToPixels(Math.min(tiles.length, layout.visibleTiles));
|
||||
|
||||
const nVisible = Math.floor(layout.visibleTiles);
|
||||
const visibleTiles = tiles.slice(0, nVisible);
|
||||
|
||||
// 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'];
|
||||
if (layout.visibleTiles >= tiles.length && tiles.length <= layout.minVisibleTiles) {
|
||||
handles = []; // no handles, we're at a minimum
|
||||
}
|
||||
|
||||
// TODO: This might need adjustment, however for now it is fine as a round.
|
||||
const nVisible = Math.round(layout.visibleTiles);
|
||||
const visibleTiles = tiles.slice(0, nVisible);
|
||||
// We have to account for padding so we can accommodate a 'show more' button and
|
||||
// the resize handle, which are pinned to the bottom of the container. This is the
|
||||
// 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
|
||||
// replaces the last visible tile, so will always show 2+ rooms. We do this
|
||||
// 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
|
||||
const showMoreHeight = 32; // As defined by CSS
|
||||
const resizeHandleHeight = 4; // As defined by CSS
|
||||
|
||||
// we +1 to account for the room we're about to hide with our 'show more' button
|
||||
// this results in the button always being 1+, and not needing an i18n `count`.
|
||||
const numMissing = (tiles.length - visibleTiles.length) + 1;
|
||||
// The padding is variable though, so figure out what we need padding for.
|
||||
let padding = 0;
|
||||
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 = (
|
||||
<ResizableBox
|
||||
width={-1}
|
||||
|
@ -230,6 +245,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
|||
className="mx_RoomSublist2_resizeBox"
|
||||
>
|
||||
{visibleTiles}
|
||||
{showMoreButton}
|
||||
</ResizableBox>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1135,7 +1135,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>",
|
||||
"Not now": "Not now",
|
||||
"Don't ask me again": "Don't ask me again",
|
||||
"Show %(n)s more": "Show %(n)s more",
|
||||
"Show %(count)s more|other": "Show %(count)s more",
|
||||
"Show %(count)s more|one": "Show %(count)s more",
|
||||
"Options": "Options",
|
||||
"%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.",
|
||||
"%(count)s unread messages including mentions.|one": "1 unread mention.",
|
||||
|
|
|
@ -52,7 +52,24 @@ export class ListLayout {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue