Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions locales/en-US/app.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,14 @@ BottomBox--assembly-code-not-available-title = Assembly code not available
BottomBox--assembly-code-not-available-text =
See <a>issue #4520</a> for supported scenarios and planned improvements.

# The toggle button for making the bottom box fullscreen.
BottomBox--hide-fullscreen =
.title = Exit fullscreen

# The toggle button for making the bottom box fullscreen.
BottomBox--show-fullscreen =
.title = Show fullscreen

SourceView--close-button =
.title = Close the source view

Expand Down
6 changes: 6 additions & 0 deletions res/img/svg/fullscreen-exit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions res/img/svg/fullscreen.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/actions/profile-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1959,6 +1959,14 @@ export function closeBottomBox(): ThunkAction<void> {
};
}

export function toggleBottomBoxFullscreen(): ThunkAction<void> {
return (dispatch) => {
dispatch({
type: 'TOGGLE_BOTTOM_BOX_FULLSCREEN',
});
};
}

export function handleCallNodeTransformShortcut(
event: React.KeyboardEvent<HTMLElement>,
threadsKey: ThreadsKey,
Expand Down
13 changes: 11 additions & 2 deletions src/app-logic/url-handling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ type Query = BaseQuery & {
transforms?: string;
sourceViewIndex?: number;
assemblyView?: string;
bottomFullscreen?: boolean;

// StackChart specific
showUserTimings?: null | undefined;
Expand Down Expand Up @@ -346,8 +347,12 @@ export function getQueryStringFromUrlState(urlState: UrlState): string {
'timing'
? undefined
: urlState.profileSpecific.lastSelectedCallTreeSummaryStrategy;
const { sourceView, assemblyView, isBottomBoxOpenPerPanel } =
urlState.profileSpecific;
const {
sourceView,
assemblyView,
isBottomBoxOpenPerPanel,
isBottomBoxFullscreen,
} = urlState.profileSpecific;

if (isBottomBoxOpenPerPanel[selectedTab]) {
if (sourceView.sourceIndex !== null) {
Expand All @@ -358,6 +363,9 @@ export function getQueryStringFromUrlState(urlState: UrlState): string {
assemblyView.nativeSymbol
);
}
if (isBottomBoxFullscreen) {
query.bottomFullscreen = true;
}
}
break;
}
Expand Down Expand Up @@ -564,6 +572,7 @@ export function stateFromLocation(
sourceView,
assemblyView,
isBottomBoxOpenPerPanel,
isBottomBoxFullscreen: query.bottomFullscreen || false,
timelineType: validateTimelineType(query.timelineType),
showJsTracerSummary: query.summary === undefined ? false : true,
globalTrackOrder: convertGlobalTrackOrderFromString(
Expand Down
21 changes: 20 additions & 1 deletion src/components/app/BottomBox.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

.bottom-box-fullscreen {
position: fixed;
z-index: 100;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

.bottom-box-pane {
display: flex;
height: 100%; /* direct child of SplitterLayout */
Expand Down Expand Up @@ -62,7 +71,9 @@
}

.bottom-close-button,
.bottom-assembly-button {
.bottom-assembly-button,
.bottom-fullscreen-hide-button,
.bottom-fullscreen-show-button {
width: 24px;
height: 24px;
flex-shrink: 0;
Expand All @@ -79,6 +90,14 @@
background-image: url(../../../res/img/svg/asm-icon.svg);
}

.bottom-fullscreen-show-button {
background-image: url(firefox-profiler-res/img/svg/fullscreen.svg);
}

.bottom-fullscreen-hide-button {
background-image: url(firefox-profiler-res/img/svg/fullscreen-exit.svg);
}

.codeLoadingOverlay,
.sourceCodeErrorOverlay,
.assemblyCodeErrorOverlay {
Expand Down
40 changes: 37 additions & 3 deletions src/components/app/BottomBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import classNames from 'classnames';

import { SourceView } from '../shared/SourceView';
import { AssemblyView } from '../shared/AssemblyView';
import { FullscreenToggleButton } from './FullscreenToggleButton';
import { AssemblyViewToggleButton } from './AssemblyViewToggleButton';
import { IonGraphView } from '../shared/IonGraphView';
import { CodeLoadingOverlay } from './CodeLoadingOverlay';
Expand All @@ -18,12 +19,16 @@ import {
getAssemblyViewIsOpen,
getAssemblyViewNativeSymbol,
getAssemblyViewScrollGeneration,
getIsBottomBoxFullscreen,
} from 'firefox-profiler/selectors/url-state';
import {
selectedThreadSelectors,
selectedNodeSelectors,
} from 'firefox-profiler/selectors/per-thread';
import { closeBottomBox } from 'firefox-profiler/actions/profile-view';
import {
closeBottomBox,
toggleBottomBoxFullscreen,
} from 'firefox-profiler/actions/profile-view';
import { parseFileNameFromSymbolication } from 'firefox-profiler/utils/special-paths';
import {
getSourceViewCode,
Expand Down Expand Up @@ -52,6 +57,7 @@ import { Localized } from '@fluent/react';
import './BottomBox.css';

type StateProps = {
readonly isFullscreen: boolean;
readonly sourceViewFile: string | null;
readonly sourceViewCode: SourceCodeStatus | void;
readonly sourceViewScrollGeneration: number;
Expand All @@ -69,6 +75,7 @@ type StateProps = {

type DispatchProps = {
readonly closeBottomBox: typeof closeBottomBox;
readonly toggleBottomBoxFullscreen: typeof toggleBottomBoxFullscreen;
};

type Props = ConnectedProps<{}, StateProps, DispatchProps>;
Expand Down Expand Up @@ -151,12 +158,31 @@ class BottomBoxImpl extends React.PureComponent<Props> {
_sourceView = React.createRef<SourceView>();
_assemblyView = React.createRef<AssemblyView>();

override componentDidMount() {
document.addEventListener('keydown', this._onKeyDown);
}

override componentWillUnmount() {
document.removeEventListener('keydown', this._onKeyDown);
}

_onKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape' && this.props.isFullscreen) {
this.props.toggleBottomBoxFullscreen();
}
};

_onClickCloseButton = () => {
this.props.closeBottomBox();
// Close the fullscreen if we're closing the bottom box
if (this.props.isFullscreen) {
this.props.toggleBottomBoxFullscreen();
}
};

override render() {
const {
isFullscreen,
sourceViewFile,
sourceViewCode,
globalLineTimings,
Expand Down Expand Up @@ -196,6 +222,7 @@ class BottomBoxImpl extends React.PureComponent<Props> {
const trailingHeaderButtons = (
<div className="bottom-box-header-trailing-buttons">
<AssemblyViewToggleButton />
<FullscreenToggleButton />
<Localized id="SourceView--close-button" attrs={{ title: true }}>
<button
className={classNames(
Expand All @@ -212,8 +239,13 @@ class BottomBoxImpl extends React.PureComponent<Props> {
);

return (
<div className="bottom-box">
<SplitterLayout customClassName="bottom-box" percentage>
<div
className={classNames(
'bottom-box',
isFullscreen ? 'bottom-box-fullscreen' : null
)}
>
<SplitterLayout percentage>
<div className="bottom-box-pane">
<div className="bottom-box-bar">
<h3 className="bottom-box-title">{path ?? '(no source file)'}</h3>
Expand Down Expand Up @@ -299,6 +331,7 @@ function convertErrors(errors: ApiQueryError[]): SourceCodeLoadingError[] {

export const BottomBox = explicitConnect<{}, StateProps, DispatchProps>({
mapStateToProps: (state) => ({
isFullscreen: getIsBottomBoxFullscreen(state),
sourceViewFile: getSourceViewFile(state),
sourceViewCode: getSourceViewCode(state),
globalLineTimings: selectedThreadSelectors.getSourceViewLineTimings(state),
Expand All @@ -318,6 +351,7 @@ export const BottomBox = explicitConnect<{}, StateProps, DispatchProps>({
}),
mapDispatchToProps: {
closeBottomBox,
toggleBottomBoxFullscreen,
},
component: BottomBoxImpl,
});
77 changes: 77 additions & 0 deletions src/components/app/FullscreenToggleButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import React from 'react';
import classNames from 'classnames';

import { getIsBottomBoxFullscreen } from 'firefox-profiler/selectors/url-state';
import { toggleBottomBoxFullscreen } from 'firefox-profiler/actions/profile-view';
import explicitConnect from 'firefox-profiler/utils/connect';

import type { ConnectedProps } from 'firefox-profiler/utils/connect';

import { Localized } from '@fluent/react';

type StateProps = {
readonly isBottomBoxFullscreen: boolean;
};

type DispatchProps = {
readonly toggleBottomBoxFullscreen: typeof toggleBottomBoxFullscreen;
};

type Props = ConnectedProps<{}, StateProps, DispatchProps>;

class FullscreenToggleButtonImpl extends React.PureComponent<Props> {
_onClick = () => {
this.props.toggleBottomBoxFullscreen();
};

override render() {
const { isBottomBoxFullscreen } = this.props;

return isBottomBoxFullscreen ? (
<Localized id="BottomBox--hide-fullscreen" attrs={{ title: true }}>
<button
className={classNames(
'bottom-fullscreen-hide-button',
'photon-button',
'photon-button-ghost',
'photon-button-ghost--checked'
)}
title="Exit fullscreen"
type="button"
onClick={this._onClick}
/>
</Localized>
) : (
<Localized id="BottomBox--show-fullscreen" attrs={{ title: true }}>
<button
className={classNames(
'bottom-fullscreen-show-button',
'photon-button',
'photon-button-ghost'
)}
title="Show fullscreen"
type="button"
onClick={this._onClick}
/>
</Localized>
);
}
}

export const FullscreenToggleButton = explicitConnect<
{},
StateProps,
DispatchProps
>({
mapStateToProps: (state) => ({
isBottomBoxFullscreen: getIsBottomBoxFullscreen(state),
}),
mapDispatchToProps: {
toggleBottomBoxFullscreen,
},
component: FullscreenToggleButtonImpl,
});
11 changes: 11 additions & 0 deletions src/reducers/url-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,16 @@ const isBottomBoxOpenPerPanel: Reducer<IsOpenPerPanelState> = (
}
};

const isBottomBoxFullscreen: Reducer<boolean> = (state = false, action) => {
switch (action.type) {
case 'TOGGLE_BOTTOM_BOX_FULLSCREEN': {
return !state;
}
default:
return state;
}
};

/**
* This value is only set from the URL and never changed.
*/
Expand All @@ -673,6 +683,7 @@ const profileSpecific = combineReducers({
sourceView,
assemblyView,
isBottomBoxOpenPerPanel,
isBottomBoxFullscreen,
timelineType,
globalTrackOrder,
hiddenGlobalTracks,
Expand Down
4 changes: 4 additions & 0 deletions src/selectors/url-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ export const getIsBottomBoxOpen: Selector<boolean> = (state) => {
return getProfileSpecificState(state).isBottomBoxOpenPerPanel[tab];
};

export const getIsBottomBoxFullscreen: Selector<boolean> = (state) => {
return getProfileSpecificState(state).isBottomBoxFullscreen;
};

/**
* The URL predictor is used to generate a link for an uploaded profile, to predict
* what the URL will be.
Expand Down
3 changes: 3 additions & 0 deletions src/types/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ type ProfileAction =
| {
readonly type: 'CLOSE_BOTTOM_BOX_FOR_TAB';
readonly tab: TabSlug;
}
| {
readonly type: 'TOGGLE_BOTTOM_BOX_FULLSCREEN';
};

type ReceiveProfileAction =
Expand Down
1 change: 1 addition & 0 deletions src/types/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ export type ProfileSpecificUrlState = {
sourceView: SourceViewState;
assemblyView: AssemblyViewState;
isBottomBoxOpenPerPanel: IsOpenPerPanelState;
isBottomBoxFullscreen: boolean;
globalTrackOrder: TrackIndex[];
hiddenGlobalTracks: Set<TrackIndex>;
hiddenLocalTracksByPid: Map<Pid, Set<TrackIndex>>;
Expand Down
Loading