mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
Merge pull request #239 from Monadical-SAS/fix-scroll-to-bottom
fix scroll to bottom
This commit is contained in:
@@ -53,7 +53,7 @@ export const metadata: Metadata = {
|
||||
maximumScale: 1,
|
||||
},
|
||||
|
||||
robots: { index: false, follow: false, noarchive: true, noimageindex: true }
|
||||
robots: { index: false, follow: false, noarchive: true, noimageindex: true },
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
body {
|
||||
background: white;
|
||||
scrollbar-color: rgb(96 165 250) transparent;
|
||||
scrollbar-color: rgb(132, 186, 251) transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
@@ -26,12 +26,11 @@ body {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
visibility: visible;
|
||||
width: 5px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background-color: rgb(96 165 250);
|
||||
background-color: rgb(132, 186, 251);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ export default function TranscriptDetails(details: TranscriptDetails) {
|
||||
<TopicList
|
||||
topics={topics?.topics || []}
|
||||
useActiveTopic={useActiveTopic}
|
||||
autoscroll={false}
|
||||
/>
|
||||
<section className="relative w-full h-auto max-h-full bg-blue-400/20 rounded-lg md:rounded-xl px-2 md:px-4 flex flex-col justify-center align-center">
|
||||
<div className="py-2 h-full">
|
||||
|
||||
@@ -65,6 +65,7 @@ const TranscriptCreate = () => {
|
||||
<TopicList
|
||||
topics={webSockets.topics}
|
||||
useActiveTopic={useActiveTopic}
|
||||
autoscroll={true}
|
||||
/>
|
||||
<section className="w-full h-full bg-blue-400/20 rounded-lg md:rounded-xl px-2 md:px-4 flex flex-col justify-center align-center">
|
||||
{!hasRecorded ? (
|
||||
|
||||
@@ -9,15 +9,15 @@ type ScrollToBottomProps = {
|
||||
export default function ScrollToBottom(props: ScrollToBottomProps) {
|
||||
return (
|
||||
<div
|
||||
className={`absolute left-0 w-10 h-10 ${
|
||||
className={`absolute bottom-0 right-[0.15rem] md:right-[0.65rem] ${
|
||||
props.visible ? "flex" : "hidden"
|
||||
} top-[49%] text-2xl cursor-pointer opacity-70 hover:opacity-100 transition-opacity duration-200 animate-bounce rounded-xl text-blue-400`}
|
||||
} text-2xl cursor-pointer opacity-70 hover:opacity-100 transition-opacity duration-200 text-blue-400`}
|
||||
onClick={() => {
|
||||
props.handleScrollBottom();
|
||||
return false;
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon icon={faArrowDown} />
|
||||
<FontAwesomeIcon icon={faArrowDown} className="animate-bounce" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,43 +14,62 @@ type TopicListProps = {
|
||||
Topic | null,
|
||||
React.Dispatch<React.SetStateAction<Topic | null>>,
|
||||
];
|
||||
autoscroll: boolean;
|
||||
};
|
||||
|
||||
export function TopicList({ topics, useActiveTopic }: TopicListProps) {
|
||||
export function TopicList({
|
||||
topics,
|
||||
useActiveTopic,
|
||||
autoscroll,
|
||||
}: TopicListProps) {
|
||||
const [activeTopic, setActiveTopic] = useActiveTopic;
|
||||
const [autoscrollEnabled, setAutoscrollEnabled] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (autoscrollEnabled) scrollToBottom();
|
||||
console.log(topics);
|
||||
if (autoscroll && autoscrollEnabled) scrollToBottom();
|
||||
}, [topics.length]);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
const topicsDiv = document.getElementById("topics-div");
|
||||
|
||||
if (!topicsDiv)
|
||||
console.error("Could not find topics div to scroll to bottom");
|
||||
else topicsDiv.scrollTop = topicsDiv.scrollHeight;
|
||||
if (topicsDiv) topicsDiv.scrollTop = topicsDiv.scrollHeight;
|
||||
};
|
||||
|
||||
const handleScroll = (e) => {
|
||||
// scroll top is not rounded, heights are, so exact match won't work.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#determine_if_an_element_has_been_totally_scrolled
|
||||
const toggleScroll = (element) => {
|
||||
const bottom =
|
||||
e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
|
||||
Math.abs(
|
||||
element.scrollHeight - element.clientHeight - element.scrollTop,
|
||||
) < 2 || element.scrollHeight == element.clientHeight;
|
||||
if (!bottom && autoscrollEnabled) {
|
||||
setAutoscrollEnabled(false);
|
||||
} else if (bottom && !autoscrollEnabled) {
|
||||
setAutoscrollEnabled(true);
|
||||
}
|
||||
};
|
||||
const handleScroll = (e) => {
|
||||
toggleScroll(e.target);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (autoscroll) {
|
||||
const topicsDiv = document.getElementById("topics-div");
|
||||
|
||||
topicsDiv && toggleScroll(topicsDiv);
|
||||
}
|
||||
}, [activeTopic, autoscroll]);
|
||||
|
||||
return (
|
||||
<section className="relative w-full h-full bg-blue-400/20 rounded-lg md:rounded-xl px-2 md:px-4 flex flex-col justify-center align-center">
|
||||
{topics.length > 0 ? (
|
||||
<>
|
||||
<ScrollToBottom
|
||||
visible={!autoscrollEnabled}
|
||||
handleScrollBottom={scrollToBottom}
|
||||
/>
|
||||
{autoscroll && (
|
||||
<ScrollToBottom
|
||||
visible={!autoscrollEnabled}
|
||||
handleScrollBottom={scrollToBottom}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div
|
||||
id="topics-div"
|
||||
@@ -60,7 +79,7 @@ export function TopicList({ topics, useActiveTopic }: TopicListProps) {
|
||||
{topics.map((topic, index) => (
|
||||
<button
|
||||
key={index}
|
||||
className="rounded-none border-solid border-0 border-b-blue-300 border-b last:border-none p-2 hover:bg-blue-400/20 focus-visible:bg-blue-400/20 text-left block w-full"
|
||||
className="rounded-none border-solid border-0 border-b-blue-300 border-b last:border-none last:rounded-b-lg p-2 hover:bg-blue-400/20 focus-visible:bg-blue-400/20 text-left block w-full"
|
||||
onClick={() =>
|
||||
setActiveTopic(activeTopic?.id == topic.id ? null : topic)
|
||||
}
|
||||
|
||||
@@ -65,6 +65,58 @@ export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
|
||||
},
|
||||
]);
|
||||
|
||||
setFinalSummary({ summary: "This is the final summary" });
|
||||
}
|
||||
if (e.key === "z" && process.env.NEXT_PUBLIC_ENV === "development") {
|
||||
setTranscriptText(
|
||||
"This text is in English, and it is a pretty long sentence to test the limits",
|
||||
);
|
||||
setTopics([
|
||||
{
|
||||
id: "1",
|
||||
timestamp: 10,
|
||||
summary: "This is test topic 1",
|
||||
title:
|
||||
"Topic 1: Introduction to Quantum Mechanics, a brief overview of quantum mechanics and its principles.",
|
||||
transcript:
|
||||
"A brief overview of quantum mechanics and its principles.",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
timestamp: 20,
|
||||
summary: "This is test topic 2",
|
||||
title:
|
||||
"Topic 2: Machine Learning Algorithms, understanding the different types of machine learning algorithms.",
|
||||
transcript:
|
||||
"Understanding the different types of machine learning algorithms.",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
timestamp: 30,
|
||||
summary: "This is test topic 3",
|
||||
title:
|
||||
"Topic 3: Mental Health Awareness, ways to improve mental health and reduce stigma.",
|
||||
transcript: "Ways to improve mental health and reduce stigma.",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
timestamp: 40,
|
||||
summary: "This is test topic 4",
|
||||
title:
|
||||
"Topic 4: Basics of Productivity, tips and tricks to increase daily productivity.",
|
||||
transcript: "Tips and tricks to increase daily productivity.",
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
timestamp: 50,
|
||||
summary: "This is test topic 5",
|
||||
title:
|
||||
"Topic 5: Future of Aviation, exploring the advancements and possibilities in aviation.",
|
||||
transcript:
|
||||
"Exploring the advancements and possibilities in aviation.",
|
||||
},
|
||||
]);
|
||||
|
||||
setFinalSummary({ summary: "This is the final summary" });
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user