Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WRQ-2288: Implement large screen mode #3235

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
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
40 changes: 37 additions & 3 deletions packages/ui/resolution/ResolutionDecorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import hoc from '@enact/core/hoc';

import {init, config as riConfig, defineScreenTypes, getResolutionClasses} from './resolution';
import {
init,
calculateFontSize,
config as riConfig,
defineScreenTypes,
getResolutionClasses,
updateBaseFontSize,
updateScreenScale
} from './resolution';

/**
* Default config for `ResolutionDecorator`.
Expand Down Expand Up @@ -97,13 +105,29 @@ const ResolutionDecorator = hoc(defaultConfig, (config, Wrapped) => {
static displayName = 'ResolutionDecorator';

static propTypes = /** @lends ui/resolution.ResolutionDecorator.prototype */ {
className: PropTypes.string
className: PropTypes.string,

/**
* Screen Scale value for the large screen mode.
* Use this value to set the scale of the base font.
* This is the value that will be multiplied by pxPerRem, which is determined by the resolution.
*
* @type {Number}
* @default 1
* @public
*/
screenScale: PropTypes.number
};

static defaultProps = {
screenScale: 1
};

constructor (props) {
super(props);
riConfig.intermediateScreenHandling = config.intermediateScreenHandling;
riConfig.matchSmallerScreenType = config.matchSmallerScreenType;
updateScreenScale(this.props.screenScale);
init({measurementNode: (typeof window !== 'undefined' && window)});
this.state = {
resolutionClasses: ''
Expand All @@ -116,6 +140,10 @@ const ResolutionDecorator = hoc(defaultConfig, (config, Wrapped) => {
this.rootNode = ReactDOM.findDOMNode(this);
}

componentDidUpdate (prevProps) {
if (prevProps.screenScale !== this.props.screenScale) updateBaseFontSize(calculateFontSize());
}

componentWillUnmount () {
if (config.dynamic) window.removeEventListener('resize', this.handleResize);
}
Expand Down Expand Up @@ -145,11 +173,17 @@ const ResolutionDecorator = hoc(defaultConfig, (config, Wrapped) => {
}

render () {
const {...rest} = this.props;

delete rest.screenScale;

if (this.props.screenScale) updateScreenScale(this.props.screenScale);

// Check if the classes are different from our previous classes
let classes = getResolutionClasses();

if (this.props.className) classes += (classes ? ' ' : '') + this.props.className;
return <Wrapped {...this.props} className={classes} />;
return <Wrapped {...rest} className={classes} />;
}
};
});
Expand Down
27 changes: 21 additions & 6 deletions packages/ui/resolution/resolution.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
let baseScreen,
orientation,
riRatio,
screenScale = 1,
screenType,
workspaceBounds = {
width: (typeof window === 'object') ? window.innerWidth : 1920,
Expand Down Expand Up @@ -201,11 +202,11 @@ function calculateFontSize (type) {
let size;

if (orientation === 'portrait' && config.orientationHandling === 'scale') {
size = scrObj.height / scrObj.width * scrObj.pxPerRem;
size = scrObj.height / (scrObj.width * scrObj.pxPerRem * screenScale);
} else {
size = scrObj.pxPerRem;
size = scrObj.pxPerRem * screenScale;
if (orientation === 'landscape' && shouldScaleFontSize) {
size = parseInt(workspaceBounds.height * scrObj.pxPerRem / scrObj.height);
size = parseInt(workspaceBounds.height * scrObj.pxPerRem * screenScale / scrObj.height);
}
}
return size + 'px';
Expand All @@ -224,6 +225,17 @@ function updateBaseFontSize (size) {
}
}

/**
* @function
* @memberof ui/resolution
* @param {Number} screenScaleValue A value that adjusts the screen scaling.
* @returns {undefined}
* @private
*/
function updateScreenScale (screenScaleValue) {
screenScale = screenScaleValue;
}

/**
* Returns the CSS classes for the given `type`.
*
Expand Down Expand Up @@ -332,7 +344,7 @@ function getAspectRatioName (type) {
* @public
*/
function scale (px) {
return (riRatio || getRiRatio()) * px;
return (riRatio || getRiRatio()) * px * screenScale;
}

/**
Expand Down Expand Up @@ -366,7 +378,7 @@ function unit (pixels, toUnit) {
if (typeof pixels === 'string' && pixels.substr(-2) === 'px') pixels = parseInt(pixels.substr(0, pixels.length - 2));
if (typeof pixels !== 'number') return;

return (pixels / unitToPixelFactors[toUnit]) + '' + toUnit;
return (pixels / (screenScale * unitToPixelFactors[toUnit])) + '' + toUnit;
}

/**
Expand Down Expand Up @@ -494,5 +506,8 @@ export {
scaleToRem,
selectSrc,
unit,
unitToPixelFactors
unitToPixelFactors,
updateBaseFontSize,
updateScreenScale,
updateWorkspaceBounds
};
18 changes: 18 additions & 0 deletions packages/ui/resolution/tests/ResolutionDecorator-specs.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '@testing-library/jest-dom';
import {render, screen} from '@testing-library/react';

import {updateBaseFontSize, calculateFontSize} from '../resolution';
import ResolutionDecorator from '../ResolutionDecorator';

describe('ResolutionDecorator Specs', () => {
Expand Down Expand Up @@ -28,6 +29,23 @@ describe('ResolutionDecorator Specs', () => {
expect(div).toHaveClass('enact-res-mhd');
});

test('should change the base font size when screenScale prop changed', () => {
const before = 1;

const Component = ResolutionDecorator('div');
const {rerender} = render(<Component data-testid="component" screenScale={before} />);
const after = 2;
rerender(
<Component data-testid="component" screenScale={after} />
);

updateBaseFontSize(calculateFontSize());
const value = document.documentElement.style.fontSize;
const expected = '72px';

expect(value).toBe(expected);
});

test.skip('should update the resolution when the screen is resized', function () {
// TODO: write a test
});
Expand Down
39 changes: 38 additions & 1 deletion packages/ui/resolution/tests/resolution-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import {
config,
defineScreenTypes,
getScreenType,
getScreenTypeObject,
scale,
unit
unit,
updateWorkspaceBounds
} from '../resolution.js';

describe('Resolution Specs', () => {
Expand Down Expand Up @@ -272,6 +274,41 @@ describe('Resolution Specs', () => {
expect(actualHD).toBe(expectedHD);
});

test('should calculate font size when orientation is landscape and shouldScaleFontSize value is true', () => {
config.intermediateScreenHandling = 'scale';
config.matchSmallerScreenType = true;

window.innerWidth = 1920;
window.innerHeight = 1080;

// update workspaceBounds
updateWorkspaceBounds(window);
// update orientation
getScreenType();
const size = calculateFontSize();
const expected = '18px';

expect(size).toBe(expected);

// clear window inner size
window.innerWidth = 640;
window.innerHeight = 480;
});

test('should calculate font size when orientation is portrait and config.orientationHandling is scale', () => {
config.orientationHandling = 'scale';
const fhdPortrait = {width: 1080, height: 1920};
getScreenType(fhdPortrait);

const size = calculateFontSize();
const scrObj = getScreenTypeObject();
const screenScale = 1;
const expected = scrObj.height / (scrObj.width * scrObj.pxPerRem * screenScale) + 'px';

expect(size).toBe(expected);

});

// NOTE: Currently tough to test selectSrc because it relies on a global variable for screenType
test.skip('should select source for the current screen type', function () {

Expand Down
Loading