diff --git a/ui/src/components/HarEntriesList.tsx b/ui/src/components/HarEntriesList.tsx index cea3c2cef..9ba52450f 100644 --- a/ui/src/components/HarEntriesList.tsx +++ b/ui/src/components/HarEntriesList.tsx @@ -5,6 +5,7 @@ import spinner from './assets/spinner.svg'; import ScrollableFeed from "react-scrollable-feed"; import {StatusType} from "./HarFilters"; import Api from "../helpers/api"; +import uninon from "./assets/union.svg"; interface HarEntriesListProps { entries: any[]; @@ -19,6 +20,9 @@ interface HarEntriesListProps { methodsFilter: Array; statusFilter: Array; pathFilter: string + listEntryREF: any; + onScrollEvent: (isAtBottom:boolean) => void; + scrollableList: boolean; } enum FetchOperator { @@ -28,7 +32,7 @@ enum FetchOperator { const api = new Api(); -export const HarEntriesList: React.FC = ({entries, setEntries, focusedEntryId, setFocusedEntryId, connectionOpen, noMoreDataTop, setNoMoreDataTop, noMoreDataBottom, setNoMoreDataBottom, methodsFilter, statusFilter, pathFilter}) => { +export const HarEntriesList: React.FC = ({entries, setEntries, focusedEntryId, setFocusedEntryId, connectionOpen, noMoreDataTop, setNoMoreDataTop, noMoreDataBottom, setNoMoreDataBottom, methodsFilter, statusFilter, pathFilter, listEntryREF, onScrollEvent, scrollableList}) => { const [loadMoreTop, setLoadMoreTop] = useState(false); const [isLoadingTop, setIsLoadingTop] = useState(false); @@ -106,11 +110,11 @@ export const HarEntriesList: React.FC = ({entries, setEntri return <>
-
+
{isLoadingTop &&
spinner
} - + onScrollEvent(isAtBottom)}> {noMoreDataTop && !connectionOpen &&
No more data available
} {filteredEntries.map(entry => = ({entries, setEntri
getNewEntries()}>Fetch more entries
} +
{entries?.length > 0 &&
diff --git a/ui/src/components/HarPage.tsx b/ui/src/components/HarPage.tsx index bfa7dbfb3..3cf42d5ca 100644 --- a/ui/src/components/HarPage.tsx +++ b/ui/src/components/HarPage.tsx @@ -60,8 +60,12 @@ export const HarPage: React.FC = ({setAnalyzeStatus, onTLSDetected const [tappingStatus, setTappingStatus] = useState(null); + const [disableScrollList, setDisableScrollList] = useState(false); + const ws = useRef(null); + const listEntry = useRef(null); + const openWebSocket = () => { ws.current = new WebSocket(MizuWebsocketURL); ws.current.onopen = () => setConnection(ConnectionStatus.Connected); @@ -86,6 +90,11 @@ export const HarPage: React.FC = ({setAnalyzeStatus, onTLSDetected setNoMoreDataTop(false); } setEntries([...newEntries, entry]) + if(listEntry.current) { + if(isScrollable(listEntry.current.firstChild)) { + setDisableScrollList(true) + } + } break case "status": setTappingStatus(message.tappingStatus); @@ -158,6 +167,14 @@ export const HarPage: React.FC = ({setAnalyzeStatus, onTLSDetected } } + const onScrollEvent = (isAtBottom) => { + isAtBottom ? setDisableScrollList(false) : setDisableScrollList(true) + } + + const isScrollable = (element) => { + return element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight; + }; + return (
@@ -192,6 +209,9 @@ export const HarPage: React.FC = ({setAnalyzeStatus, onTLSDetected methodsFilter={methodsFilter} statusFilter={statusFilter} pathFilter={pathFilter} + listEntryREF={listEntry} + onScrollEvent={onScrollEvent} + scrollableList={disableScrollList} />
diff --git a/ui/src/components/assets/union.svg b/ui/src/components/assets/union.svg new file mode 100644 index 000000000..f37699d88 --- /dev/null +++ b/ui/src/components/assets/union.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/src/components/style/HarEntriesList.module.sass b/ui/src/components/style/HarEntriesList.module.sass index 97006b86f..54d31f359 100644 --- a/ui/src/components/style/HarEntriesList.module.sass +++ b/ui/src/components/style/HarEntriesList.module.sass @@ -6,6 +6,7 @@ flex-grow: 1 flex-direction: column justify-content: space-between + position: relative .container position: relative @@ -53,4 +54,21 @@ justify-content: center margin-top: 12px font-weight: 600 - color: rgba(255,255,255,0.75) \ No newline at end of file + color: rgba(255,255,255,0.75) + +.btnLive + position: absolute + bottom: 10px + right: 10px + background: #205CF5 + border-radius: 50% + height: 35px + width: 35px + border: none + cursor: pointer + img + height: 10px +.hideButton + display: none +.showButton + display: block