mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-11 08:55:23 +03:00
chat-fe: reflow profile overlay near edges of screen
Polls for the distance between the top of the container and reflows the overlay accordingly.
This commit is contained in:
parent
188a1e8dcf
commit
1bca495d8a
@ -279,7 +279,7 @@ export class ChatScreen extends Component {
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="overflow-y-scroll bg-white bg-gray0-d pt3 pb2 flex flex-column-reverse"
|
||||
className="overflow-y-scroll bg-white bg-gray0-d pt3 pb2 flex flex-column-reverse relative"
|
||||
style={{ height: "100%", resize: "vertical" }}
|
||||
onScroll={this.onScroll}>
|
||||
<div
|
||||
|
@ -16,10 +16,26 @@ export class Message extends Component {
|
||||
unfold: false,
|
||||
copied: false,
|
||||
profileClicked: false,
|
||||
profileCaptured: false
|
||||
profileCaptured: false,
|
||||
containerOffset: 0,
|
||||
containerHeight: 0,
|
||||
};
|
||||
this.unFoldEmbed = this.unFoldEmbed.bind(this);
|
||||
this.profileToggle = this.profileToggle.bind(this);
|
||||
this.containerRef = React.createRef();
|
||||
this.profileCaptured = this.profileCaptured.bind(this);
|
||||
this.updateContainerInterval = setInterval(this.updateContainerOffset.bind(this), 1000);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.updateContainerOffset();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if(this.updateContainerInterval) {
|
||||
clearInterval(this.updateContainerInterval);
|
||||
this.updateContainerInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
unFoldEmbed(id) {
|
||||
@ -47,6 +63,18 @@ export class Message extends Component {
|
||||
this.setState({ profileCaptured })
|
||||
}
|
||||
|
||||
updateContainerOffset() {
|
||||
if(this.containerRef && this.containerRef.current) {
|
||||
const { scrollHeight, clientHeight, scrollTop } = this.containerRef.current.offsetParent;
|
||||
const offset = scrollHeight - clientHeight;
|
||||
const { offsetTop, offsetHeight } = this.containerRef.current;
|
||||
const normalized = offset + (offsetTop );
|
||||
|
||||
|
||||
this.setState({ containerOffset: normalized, containerHeight: clientHeight });
|
||||
}
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
const { props } = this;
|
||||
let letter = props.msg.letter;
|
||||
@ -183,22 +211,26 @@ export class Message extends Component {
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={this.containerRef}
|
||||
className={
|
||||
"relative w-100 f8 pl3 pt4 pr3 cf flex lh-copy " + " " + pending
|
||||
"w-100 f8 pl3 pt4 pr3 cf flex lh-copy " + " " + pending
|
||||
}
|
||||
style={{
|
||||
minHeight: "min-content"
|
||||
}}>
|
||||
{ (state.profileClicked || state.profileCaptured) && (
|
||||
<ProfileOverlay
|
||||
ship={props.msg.author}
|
||||
name={contact.nickname}
|
||||
color={color}
|
||||
onMouseEnter={() => this.profileCaptured(true)}
|
||||
onMouseLeave={() => this.profileCaptured(false)}
|
||||
/>
|
||||
)}
|
||||
<div onClick={this.profileToggle} className="fl pr3 v-top bg-white bg-gray0-d pointer">
|
||||
|
||||
<div onClick={this.profileToggle} className="fl pr3 v-top bg-white bg-gray0-d pointer relative">
|
||||
{ (state.profileClicked || state.profileCaptured) && (
|
||||
<ProfileOverlay
|
||||
ship={props.msg.author}
|
||||
name={contact.nickname}
|
||||
color={color}
|
||||
offset={state.containerOffset}
|
||||
height={state.containerHeight}
|
||||
onMouseEnter={() => this.profileCaptured(true)}
|
||||
onMouseLeave={() => this.profileCaptured(false)}
|
||||
/>
|
||||
)}
|
||||
<Sigil
|
||||
ship={props.msg.author}
|
||||
size={24}
|
||||
|
@ -1,18 +1,33 @@
|
||||
import React, { Component } from "react";
|
||||
import { Sigil } from "/components/lib/icons/sigil";
|
||||
|
||||
const HEIGHT = 250;
|
||||
|
||||
export class ProfileOverlay extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { name, ship, color } = this.props;
|
||||
const { name, ship, color, offset, height } = this.props;
|
||||
|
||||
let top, bottom;
|
||||
if (offset < HEIGHT / 2) {
|
||||
top = `0px`;
|
||||
}
|
||||
if (height - offset < HEIGHT / 1.5) {
|
||||
bottom = `0px`;
|
||||
}
|
||||
if (!(top || bottom)) {
|
||||
bottom = `-${Math.round(HEIGHT / 2) - 20}px`;
|
||||
}
|
||||
const containerStyle = { top, bottom, left: "100%" };
|
||||
|
||||
return (
|
||||
<div
|
||||
onMouseLeave={this.props.onMouseLeave}
|
||||
onMouseEnter={this.props.onMouseEnter}
|
||||
style={{ top: "-250px" }}
|
||||
style={containerStyle}
|
||||
className="flex-col shadow-6 br2 bg-white inter absolute z-1 f9 lh-solid"
|
||||
>
|
||||
<div style={{ height: "160px" }}>
|
||||
|
Loading…
Reference in New Issue
Block a user