mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-11 10:23:54 +00:00
style: recompose layout
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
export function debounce(callback: () => void, wait: number) {
|
||||
let timeout: NodeJS.Timeout | null;
|
||||
return () => {
|
||||
if (timeout) {
|
||||
return;
|
||||
}
|
||||
timeout = setTimeout(() => {
|
||||
timeout = null;
|
||||
callback();
|
||||
}, wait);
|
||||
};
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
.operatorEvents {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
padding-top: 0.25rem;
|
||||
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
@@ -19,7 +20,7 @@
|
||||
}
|
||||
|
||||
.spacer {
|
||||
min-height: 80vh;
|
||||
min-height: 95vh;
|
||||
}
|
||||
|
||||
@mixin block() {
|
||||
|
||||
@@ -65,8 +65,10 @@ export default function Operator() {
|
||||
const handleScroll = () => {
|
||||
if (selectedRef && scrollRef) {
|
||||
const selectedRect = selectedRef.current?.getBoundingClientRect();
|
||||
if (selectedRect) {
|
||||
const hasScrolledOutOfThreshold = selectedRect.top < 0 || selectedRect.top > selectedOffset;
|
||||
const scrollerRect = scrollRef.current?.getBoundingClientRect();
|
||||
if (selectedRect && scrollerRect) {
|
||||
const distanceFromTop = selectedRect.top - scrollerRect.top;
|
||||
const hasScrolledOutOfThreshold = distanceFromTop < -8 || distanceFromTop > selectedOffset;
|
||||
setLockAutoScroll(hasScrolledOutOfThreshold);
|
||||
}
|
||||
}
|
||||
@@ -100,6 +102,16 @@ export default function Operator() {
|
||||
<NavigationMenu />
|
||||
<ViewParamsEditor paramFields={operatorOptions} />
|
||||
|
||||
<StatusBar
|
||||
projectTitle={projectData.title}
|
||||
playback={featureData.playback}
|
||||
selectedEventId={featureData.selectedEventId}
|
||||
firstStart={firstEvent?.timeStart}
|
||||
firstId={firstEvent?.id}
|
||||
lastEnd={lastEvent?.timeEnd}
|
||||
lastId={lastEvent?.id}
|
||||
/>
|
||||
|
||||
<div className={style.operatorEvents} onScroll={handleScroll} ref={scrollRef}>
|
||||
{data.map((entry) => {
|
||||
if (entry.type === SupportedEvent.Event) {
|
||||
@@ -136,15 +148,6 @@ export default function Operator() {
|
||||
<div className={style.spacer} />
|
||||
</div>
|
||||
<FollowButton isVisible={lockAutoScroll} onClickHandler={handleOffset} />
|
||||
<StatusBar
|
||||
projectTitle={projectData.title}
|
||||
playback={featureData.playback}
|
||||
selectedEventId={featureData.selectedEventId}
|
||||
firstStart={firstEvent?.timeStart}
|
||||
firstId={firstEvent?.id}
|
||||
lastEnd={lastEvent?.timeEnd}
|
||||
lastId={lastEvent?.id}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
.followButton {
|
||||
position: relative;
|
||||
bottom: 100px;
|
||||
bottom: 10rem;
|
||||
margin: 0 auto;
|
||||
z-index: 1;
|
||||
|
||||
@@ -25,12 +25,5 @@
|
||||
|
||||
.hidden {
|
||||
transition: bottom 1s;
|
||||
bottom: -0;
|
||||
}
|
||||
|
||||
// tablet
|
||||
@media (min-width: $min-tablet) {
|
||||
.followButton {
|
||||
bottom: 150px;
|
||||
}
|
||||
bottom: -50px;
|
||||
}
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
}
|
||||
|
||||
.statusBar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
background-color: $gray-1350;
|
||||
z-index: 2;
|
||||
|
||||
padding: 0.5rem 1rem;
|
||||
border-top: 1px solid $white-10;
|
||||
box-shadow: $large-bottom-drawer-shadow;
|
||||
border-bottom: 1px solid $white-10;
|
||||
box-shadow: $large-top-drawer-shadow;
|
||||
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
@@ -50,9 +50,10 @@
|
||||
|
||||
.title {
|
||||
grid-area: title;
|
||||
font-size: 1.5rem;
|
||||
padding-left: 0.5rem;
|
||||
font-size: 1rem;
|
||||
padding-left: 0.25rem;
|
||||
display: none;
|
||||
line-height: 1.25em;
|
||||
}
|
||||
|
||||
.startTime {
|
||||
@@ -80,8 +81,8 @@
|
||||
@media (min-width: $min-tablet) {
|
||||
.statusBar {
|
||||
grid-template-areas:
|
||||
"playback timer1B timer2B timer3B"
|
||||
"title timer1A timer2A timer3A";
|
||||
"playback timer1B timer2A timer3A"
|
||||
"title title timer2B timer3B";
|
||||
row-gap: 0.25rem;
|
||||
column-gap: 2rem;
|
||||
}
|
||||
|
||||
@@ -63,16 +63,6 @@ export default function StatusBar(props: StatusBarProps) {
|
||||
|
||||
return (
|
||||
<div className={styles.statusBar}>
|
||||
<span className={styles.title}>{projectTitle}</span>
|
||||
<div className={styles.startTime}>
|
||||
<span className={styles.label}>Scheduled start</span>
|
||||
<span className={styles.timer}>{getTimeStart()}</span>
|
||||
</div>
|
||||
<div className={styles.endTime}>
|
||||
<span className={styles.label}>Scheduled end</span>
|
||||
<span className={styles.timer}>{getTimeEnd()}</span>
|
||||
</div>
|
||||
|
||||
{PlaybackIconComponent}
|
||||
<div className={styles.timeNow}>
|
||||
<span className={styles.label}>Time now</span>
|
||||
@@ -86,6 +76,16 @@ export default function StatusBar(props: StatusBarProps) {
|
||||
<span className={styles.label}>Running timer</span>
|
||||
<span className={styles.timer}>{runningTime}</span>
|
||||
</div>
|
||||
|
||||
<span className={styles.title}>{projectTitle}</span>
|
||||
<div className={styles.startTime}>
|
||||
<span className={styles.label}>Scheduled start</span>
|
||||
<span className={styles.timer}>{getTimeStart()}</span>
|
||||
</div>
|
||||
<div className={styles.endTime}>
|
||||
<span className={styles.label}>Scheduled end</span>
|
||||
<span className={styles.timer}>{getTimeEnd()}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ $bg-container-onlight: $gray-100;
|
||||
$box-shadow-l1: rgba(0, 0, 0, 0.15) 0 3px 3px 0;
|
||||
$box-shadow-l2: rgba(0, 0, 0, 0.15) 0 3px 3px 0;
|
||||
$large-bottom-drawer-shadow: rgba(0, 0, 0, 0.35) 0 3px 6px 6px;
|
||||
$large-top-drawer-shadow: rgba(0, 0, 0, 0.35) 0 1px 6px 3px;
|
||||
|
||||
$modal-note-color: $gray-700;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user