Skip to content

Commit

Permalink
change fullscreen hook implementation to use native fullscreen api in…
Browse files Browse the repository at this point in the history
…stead of screenfull package

full screenD

remove data-id

add null check for fullscreen

fix overflow for logs

make requested changes

support older browser using prefixes

make requesteddd changes

changes

small fix
  • Loading branch information
sahil143 committed Apr 9, 2020
1 parent 988a22c commit 45744f7
Show file tree
Hide file tree
Showing 8 changed files with 787 additions and 118 deletions.
115 changes: 90 additions & 25 deletions frontend/packages/console-shared/src/hooks/fullscreen.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,100 @@
import * as React from 'react';
import * as screenfull from 'screenfull';

export const useFullscreen = (id: string): [boolean, (node) => void] => {
const [isFullScreen, setIsFullScreen] = React.useState<boolean>(false);
type FullScreenAPI = {
requestFullscreen: string;
exitFullscreen: string;
fullscreenElement: string;
fullscreenEnabled: string;
fullscreenchange: string;
fullscreenerror: string;
};

const fullScreenToggleCallback = React.useCallback((node) => {
if (node && screenfull.enabled) {
screenfull.toggle(node);
}
const spec: FullScreenAPI = {
requestFullscreen: 'requestFullscreen',
exitFullscreen: 'exitFullscreen',
fullscreenElement: 'fullscreenElement',
fullscreenEnabled: 'fullscreenEnabled',
fullscreenchange: 'fullscreenchange',
fullscreenerror: 'fullscreenerror',
};

const moz: FullScreenAPI = {
requestFullscreen: 'mozRequestFullscreen',
exitFullscreen: 'mozExitFullscreen',
fullscreenElement: 'mozFullscreenElement',
fullscreenEnabled: 'mozFullscreenEnabled',
fullscreenchange: 'mozfullscreenchange',
fullscreenerror: 'mozfullscreenerror',
};

const webkit: FullScreenAPI = {
requestFullscreen: 'webkitRequestFullscreen',
exitFullscreen: 'webkitExitFullscreen',
fullscreenElement: 'webkitFullscreenElement',
fullscreenEnabled: 'webkitFullscreenEnabled',
fullscreenchange: 'webkitfullscreenchange',
fullscreenerror: 'webkitfullscreenerror',
};

const ms: FullScreenAPI = {
requestFullscreen: 'msRequestFullscreen',
exitFullscreen: 'msExitFullscreen',
fullscreenElement: 'msFullscreenElement',
fullscreenEnabled: 'msFullscreenEnabled',
fullscreenchange: 'msfullscreenchange',
fullscreenerror: 'msfullscreenerror',
};

const allPrefixes: FullScreenAPI[] = [spec, moz, webkit, ms];

const nativeAPI: FullScreenAPI = (function(doc) {
return allPrefixes.find((x: FullScreenAPI) => !!doc[x.fullscreenEnabled]);
})(document);

export const useFullscreen = <T extends HTMLElement>(): [
boolean,
(node: T) => void,
() => void,
boolean,
] => {
const [isFullscreen, setIsFullscreen] = React.useState<boolean>(false);
const fullscreenRef = React.useRef<boolean>(isFullscreen);
fullscreenRef.current = isFullscreen;
const elementRef = React.useRef<any>();

const listener = React.useCallback((event) => {
setIsFullscreen(document[nativeAPI.fullscreenElement] === event.target);
}, []);

React.useEffect(() => {
if (screenfull.enabled) {
screenfull.on('change', (event) => {
if (event.target.getAttribute('data-fullscreen-id') === id) {
setIsFullScreen(screenfull.isFullscreen);
const targetCallbackRef = React.useCallback(
(node: T) => {
if (document[nativeAPI.fullscreenEnabled]) {
if (elementRef.current && elementRef.current !== node) {
elementRef.current.removeEventListener(nativeAPI.fullscreenchange, listener);
elementRef.current.removeEventListener(nativeAPI.fullscreenerror, listener);
}
});
screenfull.on('error', (event) => {
if (event.target.getAttribute('data-fullscreen-id') === id) {
setIsFullScreen(false);
if (node != null) {
elementRef.current = node;
node.addEventListener(nativeAPI.fullscreenchange, listener);
node.addEventListener(nativeAPI.fullscreenerror, listener);
}
});
}
return () => {
if (screenfull.enabled) {
screenfull.off('change');
screenfull.off('error');
}
};
}, [id]);
},
[listener],
);

const fullscreenToggleCallback = React.useCallback(() => {
if (elementRef.current && document[nativeAPI.fullscreenEnabled]) {
fullscreenRef.current
? document[nativeAPI.exitFullscreen]()
: elementRef.current[nativeAPI.requestFullscreen]();
}
}, []);

return [isFullScreen, fullScreenToggleCallback];
return [
isFullscreen,
targetCallbackRef,
fullscreenToggleCallback,
document[nativeAPI.fullscreenEnabled],
];
};
7 changes: 2 additions & 5 deletions frontend/packages/console-shared/src/hooks/scroll.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { throttle } from 'lodash';

export enum ScrollDirection {
scrollingUp = 'scrolling-up',
Expand Down Expand Up @@ -27,7 +26,7 @@ export const getScrollDirection = (
return direction;
};

export const useScrollDirection = (): [ScrollDirection, (event: Event) => void] => {
export const useScrollDirection = (): [ScrollDirection, (event) => void] => {
const scrollPosition = React.useRef<number>(null);
const [scrollDirection, setScrollDirection] = React.useState<ScrollDirection>(null);
const handleScroll = React.useCallback(
Expand All @@ -47,7 +46,5 @@ export const useScrollDirection = (): [ScrollDirection, (event: Event) => void]
[scrollDirection],
);

const callback = throttle(handleScroll, 100, { leading: true, trailing: false });

return [scrollDirection, callback];
return [scrollDirection, handleScroll];
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Firehose, resourcePathFromModel } from '@console/internal/components/ut
import { pipelineRunFilterReducer } from '../../../utils/pipeline-filter-reducer';
import { PipelineRun } from '../../../utils/pipeline-augment';
import { PipelineRunModel } from '../../../models';
import { LogsWrapperComponent } from '../logs/MultiStreamLogs';
import LogsWrapperComponent from '../logs/LogsWrapperComponent';
import './PipelineRunLogs.scss';

interface PipelineRunLogsProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const Logs: React.FC<LogsProps> = ({
const { name: resName, namespace: resNamespace } = metadata;
const contentRef = React.useRef<HTMLDivElement>(null);
const [error, setError] = React.useState<boolean>(false);
const fetching = React.useRef<boolean>(false);
const resourceStatusRef = React.useRef<string>(resourceStatus);
const onCompleteRef = React.useRef<(name) => void>();
onCompleteRef.current = onComplete;
Expand Down Expand Up @@ -71,42 +70,39 @@ const Logs: React.FC<LogsProps> = ({
follow: 'true',
},
};
if (!fetching.current) {
const watchURL = resourceURL(modelFor(kind), urlOpts);
if (resourceStatusRef.current === LOG_SOURCE_TERMINATED) {
coFetchText(watchURL)
.then((res) => {
if (loaded) return;
appendMessage.current(res);
onCompleteRef.current(name);
})
.catch(() => {
if (loaded) return;
setError(true);
onCompleteRef.current(name);
});
} else {
const wsOpts = {
host: 'auto',
path: watchURL,
subprotocols: ['base64.binary.k8s.io'],
};
ws = new WSFactory(watchURL, wsOpts);
ws.onmessage((msg) => {
const watchURL = resourceURL(modelFor(kind), urlOpts);
if (resourceStatusRef.current === LOG_SOURCE_TERMINATED) {
coFetchText(watchURL)
.then((res) => {
if (loaded) return;
const message = Base64.decode(msg);
appendMessage.current(message);
appendMessage.current(res);
onCompleteRef.current(name);
})
.onclose(() => {
onCompleteRef.current(name);
})
.onerror(() => {
if (loaded) return;
setError(true);
onCompleteRef.current(name);
});
}
fetching.current = true;
.catch(() => {
if (loaded) return;
setError(true);
onCompleteRef.current(name);
});
} else {
const wsOpts = {
host: 'auto',
path: watchURL,
subprotocols: ['base64.binary.k8s.io'],
};
ws = new WSFactory(watchURL, wsOpts);
ws.onmessage((msg) => {
if (loaded) return;
const message = Base64.decode(msg);
appendMessage.current(message);
})
.onclose(() => {
onCompleteRef.current(name);
})
.onerror(() => {
if (loaded) return;
setError(true);
onCompleteRef.current(name);
});
}
return () => {
loaded = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from 'react';
import * as _ from 'lodash';
import { MultiStreamLogs } from './MultiStreamLogs';
import { FirehoseResult } from '@console/internal/components/utils';
import { PodKind } from '@console/internal/module/k8s';

type LogsWrapperComponentProps = {
obj?: FirehoseResult<PodKind>;
taskName: string;
};

const LogsWrapperComponent: React.FC<LogsWrapperComponentProps> = ({ obj, taskName }) => {
const ref = React.useRef(obj?.data);
if (!_.isEmpty(obj?.data)) {
ref.current = obj.data;
}
return obj ? <MultiStreamLogs taskName={taskName} resource={ref.current} /> : null;
};

export default LogsWrapperComponent;
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
color: var(--pf-global--BackgroundColor--100);
font-family: Menlo, Monaco, 'Courier New', monospace;
overflow-y: scroll;
position: relative;
&--pos {
position: absolute;
width: 100%;
}
}
&__taskName {
background-color: var(--pf-global--BackgroundColor--dark-300);
padding: var(--pf-global--spacer--sm) var(--pf-global--spacer--md);
position: sticky;
z-index: 99;
top: 0;
}
&__taskName--loading {
Expand Down

0 comments on commit 45744f7

Please sign in to comment.