Address beta feedback

* Use signal blue for search box focus outline
* Reduce debounce for draft saves
* Be less aggressive in our scrolling corrections
* Lightbox: Ensure that a tall image is still fully visible
* Fix spell checking after Electron API breaking changes
* Fix link preview image generation
* Message highlight: Move to border in signal blue
This commit is contained in:
Scott Nonnenberg 2019-08-22 14:11:36 -07:00 committed by Ken Powers
parent eec0fce62a
commit b19659f5ac
9 changed files with 108 additions and 89 deletions

View file

@ -96,11 +96,12 @@ if (process.platform === 'linux') {
} }
const simpleChecker = { const simpleChecker = {
spellCheck(text) { spellCheck(words, callback) {
return !this.isMisspelled(text); const mispelled = words.filter(word => this.isMisspelled(word));
callback(mispelled);
}, },
isMisspelled(text) { isMisspelled(word) {
const misspelled = spellchecker.isMisspelled(text); const misspelled = spellchecker.isMisspelled(word);
// The idea is to make this as fast as possible. For the many, many calls which // The idea is to make this as fast as possible. For the many, many calls which
// don't result in the red squiggly, we minimize the number of checks. // don't result in the red squiggly, we minimize the number of checks.
@ -109,7 +110,7 @@ const simpleChecker = {
} }
// Only if we think we've found an error do we check the locale and skip list. // Only if we think we've found an error do we check the locale and skip list.
if (locale.match(EN_VARIANT) && _.contains(ENGLISH_SKIP_WORDS, text)) { if (locale.match(EN_VARIANT) && _.contains(ENGLISH_SKIP_WORDS, word)) {
return false; return false;
} }
@ -118,14 +119,14 @@ const simpleChecker = {
getSuggestions(text) { getSuggestions(text) {
return spellchecker.getCorrectionsForMisspelling(text); return spellchecker.getCorrectionsForMisspelling(text);
}, },
add(text) { add(word) {
spellchecker.add(text); spellchecker.add(word);
}, },
}; };
const dummyChecker = { const dummyChecker = {
spellCheck() { spellCheck(words, callback) {
return true; callback([]);
}, },
isMisspelled() { isMisspelled() {
return false; return false;

View file

@ -186,7 +186,7 @@
this.maybeGrabLinkPreview.bind(this), this.maybeGrabLinkPreview.bind(this),
200 200
); );
this.debouncedSaveDraft = _.debounce(this.saveDraft.bind(this), 2000); this.debouncedSaveDraft = _.debounce(this.saveDraft.bind(this), 500);
this.render(); this.render();
@ -2668,18 +2668,18 @@
); );
} }
const data = await this.makeChunkedRequest(imageUrl); const chunked = await this.makeChunkedRequest(imageUrl);
// Ensure that this file is either small enough or is resized to meet our // Ensure that this file is either small enough or is resized to meet our
// requirements for attachments // requirements for attachments
const withBlob = await this.autoScale({ const withBlob = await this.autoScale({
contentType: data.contentType, contentType: chunked.contentType,
file: new Blob([data.data], { file: new Blob([chunked.data], {
type: data.contentType, type: chunked.contentType,
}), }),
}); });
const attachment = await this.arrayBufferFromFile(withBlob); const data = await this.arrayBufferFromFile(withBlob.file);
objectUrl = URL.createObjectURL(withBlob.file); objectUrl = URL.createObjectURL(withBlob.file);
const dimensions = await Signal.Types.VisualAttachment.getImageDimensions( const dimensions = await Signal.Types.VisualAttachment.getImageDimensions(
@ -2690,7 +2690,8 @@
); );
image = { image = {
...attachment, data,
size: data.byteLength,
...dimensions, ...dimensions,
contentType: withBlob.file.type, contentType: withBlob.file.type,
}; };

View file

@ -24,7 +24,7 @@ index d9716a0..e7a9f9f 100644
} }
} }
diff --git a/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js b/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js diff --git a/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js b/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js
index e1b959a..1e3a269 100644 index e1b959a..18f8f1d 100644
--- a/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js --- a/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js
+++ b/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js +++ b/node_modules/react-virtualized/dist/commonjs/Grid/Grid.js
@@ -132,6 +132,9 @@ var Grid = function (_React$PureComponent) { @@ -132,6 +132,9 @@ var Grid = function (_React$PureComponent) {
@ -104,11 +104,27 @@ index e1b959a..1e3a269 100644
}); });
this._maybeCallOnScrollbarPresenceChange(); this._maybeCallOnScrollbarPresenceChange();
@@ -584,6 +611,51 @@ var Grid = function (_React$PureComponent) { @@ -584,6 +611,59 @@ var Grid = function (_React$PureComponent) {
} }
} }
+ if (scrollToColumn >= 0) { + // We reset our hasScrolled flags if our target has changed, or if target is not longer set
+ if (scrollToColumn !== prevProps.scrollToColumn || scrollToColumn == null || scrollToColumn < 0) {
+ this._hasScrolledToColumnTarget = false;
+ }
+ if (scrollToRow !== prevProps.scrollToRow || scrollToRow == null || scrollToRow < 0) {
+ this._hasScrolledToRowTarget = false;
+ }
+
+ // We deactivate our forced scrolling if the user scrolls
+ if (scrollLeft !== prevState.scrollLeft && scrollToColumn >= 0 && scrollPositionChangeReason === SCROLL_POSITION_CHANGE_REASONS.OBSERVED) {
+ this._hasScrolledToColumnTarget = true;
+ }
+ if (scrollTop !== prevState.scrollTop && scrollToRow >= 0 && scrollPositionChangeReason === SCROLL_POSITION_CHANGE_REASONS.OBSERVED) {
+ this._hasScrolledToRowTarget = true;
+ }
+
+ if (scrollToColumn >= 0 && !this._hasScrolledToColumnTarget) {
+ const scrollRight = scrollLeft + width; + const scrollRight = scrollLeft + width;
+ const targetColumn = instanceProps.columnSizeAndPositionManager.getSizeAndPositionOfCell(scrollToColumn); + const targetColumn = instanceProps.columnSizeAndPositionManager.getSizeAndPositionOfCell(scrollToColumn);
+ +
@ -124,13 +140,9 @@ index e1b959a..1e3a269 100644
+ const totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); + const totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize();
+ const maxScroll = totalColumnsWidth - width; + const maxScroll = totalColumnsWidth - width;
+ this._hasScrolledToColumnTarget = (scrollLeft >= maxScroll || targetColumn.offset === scrollLeft); + this._hasScrolledToColumnTarget = (scrollLeft >= maxScroll || targetColumn.offset === scrollLeft);
+ } else if (scrollToColumn !== prevProps.scrollToColumn) {
+ this._hasScrolledToColumnTarget = false;
+ } + }
+ } else {
+ this._hasScrolledToColumnTarget = false;
+ } + }
+ if (scrollToRow >= 0) { + if (scrollToRow >= 0 && !this._hasScrolledToRowTarget) {
+ const scrollBottom = scrollTop + height; + const scrollBottom = scrollTop + height;
+ const targetRow = instanceProps.rowSizeAndPositionManager.getSizeAndPositionOfCell(scrollToRow); + const targetRow = instanceProps.rowSizeAndPositionManager.getSizeAndPositionOfCell(scrollToRow);
+ +
@ -146,17 +158,13 @@ index e1b959a..1e3a269 100644
+ const totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); + const totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize();
+ const maxScroll = totalRowsHeight - height; + const maxScroll = totalRowsHeight - height;
+ this._hasScrolledToRowTarget = (scrollTop >= maxScroll || targetRow.offset === scrollTop); + this._hasScrolledToRowTarget = (scrollTop >= maxScroll || targetRow.offset === scrollTop);
+ } else if (scrollToRow !== prevProps.scrollToRow) {
+ this._hasScrolledToRowTarget = false;
+ } + }
+ } else {
+ this._hasScrolledToRowTarget = false;
+ } + }
+ +
// Special case where the previous size was 0: // Special case where the previous size was 0:
// In this case we don't show any windowed cells at all. // In this case we don't show any windowed cells at all.
// So we should always recalculate offset afterwards. // So we should always recalculate offset afterwards.
@@ -594,6 +666,8 @@ var Grid = function (_React$PureComponent) { @@ -594,6 +674,8 @@ var Grid = function (_React$PureComponent) {
if (this._recomputeScrollLeftFlag) { if (this._recomputeScrollLeftFlag) {
this._recomputeScrollLeftFlag = false; this._recomputeScrollLeftFlag = false;
this._updateScrollLeftForScrollToColumn(this.props); this._updateScrollLeftForScrollToColumn(this.props);
@ -165,7 +173,7 @@ index e1b959a..1e3a269 100644
} else { } else {
(0, _updateScrollIndexHelper2.default)({ (0, _updateScrollIndexHelper2.default)({
cellSizeAndPositionManager: instanceProps.columnSizeAndPositionManager, cellSizeAndPositionManager: instanceProps.columnSizeAndPositionManager,
@@ -616,6 +690,8 @@ var Grid = function (_React$PureComponent) { @@ -616,6 +698,8 @@ var Grid = function (_React$PureComponent) {
if (this._recomputeScrollTopFlag) { if (this._recomputeScrollTopFlag) {
this._recomputeScrollTopFlag = false; this._recomputeScrollTopFlag = false;
this._updateScrollTopForScrollToRow(this.props); this._updateScrollTopForScrollToRow(this.props);
@ -174,7 +182,7 @@ index e1b959a..1e3a269 100644
} else { } else {
(0, _updateScrollIndexHelper2.default)({ (0, _updateScrollIndexHelper2.default)({
cellSizeAndPositionManager: instanceProps.rowSizeAndPositionManager, cellSizeAndPositionManager: instanceProps.rowSizeAndPositionManager,
@@ -630,11 +706,56 @@ var Grid = function (_React$PureComponent) { @@ -630,11 +714,56 @@ var Grid = function (_React$PureComponent) {
size: height, size: height,
sizeJustIncreasedFromZero: sizeJustIncreasedFromZero, sizeJustIncreasedFromZero: sizeJustIncreasedFromZero,
updateScrollIndexCallback: function updateScrollIndexCallback() { updateScrollIndexCallback: function updateScrollIndexCallback() {
@ -232,7 +240,7 @@ index e1b959a..1e3a269 100644
// Update onRowsRendered callback if start/stop indices have changed // Update onRowsRendered callback if start/stop indices have changed
this._invokeOnGridRenderedHelper(); this._invokeOnGridRenderedHelper();
@@ -647,7 +768,11 @@ var Grid = function (_React$PureComponent) { @@ -647,7 +776,11 @@ var Grid = function (_React$PureComponent) {
scrollLeft: scrollLeft, scrollLeft: scrollLeft,
scrollTop: scrollTop, scrollTop: scrollTop,
totalColumnsWidth: totalColumnsWidth, totalColumnsWidth: totalColumnsWidth,
@ -245,7 +253,7 @@ index e1b959a..1e3a269 100644
}); });
} }
@@ -962,7 +1087,11 @@ var Grid = function (_React$PureComponent) { @@ -962,7 +1095,11 @@ var Grid = function (_React$PureComponent) {
var scrollLeft = _ref6.scrollLeft, var scrollLeft = _ref6.scrollLeft,
scrollTop = _ref6.scrollTop, scrollTop = _ref6.scrollTop,
totalColumnsWidth = _ref6.totalColumnsWidth, totalColumnsWidth = _ref6.totalColumnsWidth,
@ -258,7 +266,7 @@ index e1b959a..1e3a269 100644
this._onScrollMemoizer({ this._onScrollMemoizer({
callback: function callback(_ref7) { callback: function callback(_ref7) {
@@ -973,19 +1102,26 @@ var Grid = function (_React$PureComponent) { @@ -973,19 +1110,26 @@ var Grid = function (_React$PureComponent) {
onScroll = _props7.onScroll, onScroll = _props7.onScroll,
width = _props7.width; width = _props7.width;
@ -289,7 +297,7 @@ index e1b959a..1e3a269 100644
}); });
} }
diff --git a/node_modules/react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js b/node_modules/react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js diff --git a/node_modules/react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js b/node_modules/react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js
index 70b0abe..2f04448 100644 index 70b0abe..8e12ffc 100644
--- a/node_modules/react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js --- a/node_modules/react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js
+++ b/node_modules/react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js +++ b/node_modules/react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js
@@ -32,15 +32,8 @@ function defaultOverscanIndicesGetter(_ref) { @@ -32,15 +32,8 @@ function defaultOverscanIndicesGetter(_ref) {
@ -312,8 +320,9 @@ index 70b0abe..2f04448 100644
+ overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount), + overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount),
+ }; + };
} }
\ No newline at end of file
diff --git a/node_modules/react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js b/node_modules/react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js diff --git a/node_modules/react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js b/node_modules/react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js
index d5f6d04..e01e69a 100644 index d5f6d04..c4b3d84 100644
--- a/node_modules/react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js --- a/node_modules/react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js
+++ b/node_modules/react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js +++ b/node_modules/react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js
@@ -27,15 +27,8 @@ function defaultOverscanIndicesGetter(_ref) { @@ -27,15 +27,8 @@ function defaultOverscanIndicesGetter(_ref) {
@ -336,6 +345,7 @@ index d5f6d04..e01e69a 100644
+ overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount), + overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount),
+ }; + };
} }
\ No newline at end of file
diff --git a/node_modules/react-virtualized/dist/commonjs/List/List.js b/node_modules/react-virtualized/dist/commonjs/List/List.js diff --git a/node_modules/react-virtualized/dist/commonjs/List/List.js b/node_modules/react-virtualized/dist/commonjs/List/List.js
index b5ad0eb..efb2cd7 100644 index b5ad0eb..efb2cd7 100644
--- a/node_modules/react-virtualized/dist/commonjs/List/List.js --- a/node_modules/react-virtualized/dist/commonjs/List/List.js

View file

@ -12,7 +12,8 @@
// can be used outside tht Timeline contact more easily. // can be used outside tht Timeline contact more easily.
.module-message-container { .module-message-container {
width: 100%; width: 100%;
margin-top: 10px; margin-top: 4px;
margin-bottom: 4px;
&::after { &::after {
visibility: hidden; visibility: hidden;
@ -65,7 +66,7 @@
} }
.module-message--incoming.module-message--group { .module-message--incoming.module-message--group {
margin-left: 44px; margin-left: 48px;
} }
.module-message__buttons { .module-message__buttons {
@ -175,6 +176,14 @@
padding-top: 10px; padding-top: 10px;
padding-bottom: 10px; padding-bottom: 10px;
min-width: 0px; min-width: 0px;
@include light-theme {
border: 1px solid $color-white;
}
@include dark-theme {
border: 1px solid $color-gray-95;
}
} }
.module-message__container--with-sticker { .module-message__container--with-sticker {
@ -185,34 +194,23 @@
background-color: $color-light-10; background-color: $color-light-10;
} }
.module-message__container__selection { .module-message__container--selected {
position: absolute; // cubic-bezier taken from https://easings.net/en#easeOutExpo
display: block; animation: message--selected 1s cubic-bezier(0.19, 1, 0.22, 1);
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 16px;
background-color: $color-black;
opacity: 0;
animation: message--selected 1s ease-in-out;
} }
@keyframes message--selected { @keyframes message--selected {
0% { 0% {
opacity: 0; box-shadow: 0 0 0 5px transparent;
} }
20% { 10% {
opacity: 0.3; box-shadow: 0 0 0 5px $color-signal-blue;
} }
80% { 70% {
opacity: 0.3; box-shadow: 0 0 0 5px $color-signal-blue;
} }
100% { 100% {
opacity: 0; box-shadow: 0 0 0 5px transparent;
} }
} }
@ -806,7 +804,7 @@
.module-message__author-avatar { .module-message__author-avatar {
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
right: calc(100% + 4px); right: calc(100% + 8px);
} }
.module-message__typing-container { .module-message__typing-container {
@ -2420,7 +2418,7 @@
} }
&:focus { &:focus {
border: solid 1px blue; border: solid 1px $color-signal-blue;
outline: none; outline: none;
} }
} }
@ -2496,7 +2494,6 @@
// Module: Image // Module: Image
.module-image { .module-image {
overflow: hidden;
position: relative; position: relative;
display: inline-block; display: inline-block;
margin: 1px; margin: 1px;
@ -2537,6 +2534,18 @@
border-top-left-radius: 10px; border-top-left-radius: 10px;
} }
.module-image--selection--selected {
position: absolute;
top: 1px;
bottom: 1px;
left: 1px;
right: 1px;
border-radius: 10px;
// cubic-bezier taken from https://easings.net/en#easeOutExpo
animation: message--selected 1s cubic-bezier(0.19, 1, 0.22, 1);
}
.module-image__border-overlay { .module-image__border-overlay {
position: absolute; position: absolute;
top: 0; top: 0;
@ -2551,13 +2560,6 @@
background-color: $color-black-02; background-color: $color-black-02;
} }
.module-image__border-overlay--selected {
background-color: $color-black;
opacity: 0;
animation: message--selected 1s ease-in-out;
}
.module-image__loading-placeholder { .module-image__loading-placeholder {
display: inline-flex; display: inline-flex;
flex-direction: row; flex-direction: row;
@ -3504,7 +3506,8 @@
} }
.module-timeline__message-container { .module-timeline__message-container {
padding-top: 10px; padding-top: 4px;
padding-bottom: 4px;
} }
.ReactVirtualized__List { .ReactVirtualized__List {

View file

@ -1,6 +1,15 @@
describe('spellChecker', () => { describe('spellChecker', () => {
it('should work', () => { it('should work', () => {
assert(window.spellChecker.spellCheck('correct')); let result = null;
assert(!window.spellChecker.spellCheck('fhqwgads'));
window.spellChecker.spellCheck(['correct'], answer => {
result = answer;
});
assert.deepEqual(result, []);
window.spellChecker.spellCheck(['fhqwgads'], answer => {
result = answer;
});
assert.deepEqual(result, ['fhqwgads']);
}); });
}); });

View file

@ -56,6 +56,8 @@ const styles = {
paddingLeft: 40, paddingLeft: 40,
paddingRight: 40, paddingRight: 40,
paddingBottom: 0, paddingBottom: 0,
// To ensure that a large image doesn't overflow the flex layout
minHeight: '50px',
} as React.CSSProperties, } as React.CSSProperties,
objectContainer: { objectContainer: {
position: 'relative', position: 'relative',

View file

@ -90,6 +90,9 @@ export class Image extends React.Component<Props> {
softCorners ? 'module-image--soft-corners' : null softCorners ? 'module-image--soft-corners' : null
)} )}
> >
{isSelected ? (
<div className="module-image--selection--selected" />
) : null}
{pending ? ( {pending ? (
<div <div
className="module-image__loading-placeholder" className="module-image__loading-placeholder"
@ -120,7 +123,7 @@ export class Image extends React.Component<Props> {
alt={i18n('imageCaptionIconAlt')} alt={i18n('imageCaptionIconAlt')}
/> />
) : null} ) : null}
{!noBorder || isSelected ? ( {!noBorder ? (
<div <div
className={classNames( className={classNames(
'module-image__border-overlay', 'module-image__border-overlay',
@ -130,8 +133,7 @@ export class Image extends React.Component<Props> {
curveBottomRight ? 'module-image--curved-bottom-right' : null, curveBottomRight ? 'module-image--curved-bottom-right' : null,
smallCurveTopLeft ? 'module-image--small-curved-top-left' : null, smallCurveTopLeft ? 'module-image--small-curved-top-left' : null,
softCorners ? 'module-image--soft-corners' : null, softCorners ? 'module-image--soft-corners' : null,
darkOverlay ? 'module-image__border-overlay--dark' : null, darkOverlay ? 'module-image__border-overlay--dark' : null
isSelected ? 'module-image__border-overlay--selected' : null
)} )}
/> />
) : null} ) : null}

View file

@ -1243,17 +1243,6 @@ export class Message extends React.PureComponent<Props, State> {
); );
} }
public renderSelectionHighlight() {
const { isSticker } = this.props;
const { isSelected } = this.state;
if (!isSelected || isSticker) {
return;
}
return <div className="module-message__container__selection" />;
}
// tslint:disable-next-line cyclomatic-complexity // tslint:disable-next-line cyclomatic-complexity
public render() { public render() {
const { const {
@ -1270,7 +1259,7 @@ export class Message extends React.PureComponent<Props, State> {
isTapToViewError, isTapToViewError,
timestamp, timestamp,
} = this.props; } = this.props;
const { expired, expiring, imageBroken } = this.state; const { expired, expiring, imageBroken, isSelected } = this.state;
const isAttachmentPending = this.isAttachmentPending(); const isAttachmentPending = this.isAttachmentPending();
const isButton = isTapToView && !isTapToViewExpired && !isAttachmentPending; const isButton = isTapToView && !isTapToViewExpired && !isAttachmentPending;
@ -1306,6 +1295,9 @@ export class Message extends React.PureComponent<Props, State> {
<div <div
className={classNames( className={classNames(
'module-message__container', 'module-message__container',
isSelected && !isSticker
? 'module-message__container--selected'
: null,
isSticker ? 'module-message__container--with-sticker' : null, isSticker ? 'module-message__container--with-sticker' : null,
!isSticker ? `module-message__container--${direction}` : null, !isSticker ? `module-message__container--${direction}` : null,
isTapToView ? 'module-message__container--with-tap-to-view' : null, isTapToView ? 'module-message__container--with-tap-to-view' : null,
@ -1333,7 +1325,6 @@ export class Message extends React.PureComponent<Props, State> {
> >
{this.renderAuthor()} {this.renderAuthor()}
{this.renderContents()} {this.renderContents()}
{this.renderSelectionHighlight()}
{this.renderAvatar()} {this.renderAvatar()}
</div> </div>
{this.renderError(direction === 'outgoing')} {this.renderError(direction === 'outgoing')}

View file

@ -7484,7 +7484,7 @@
"rule": "React-createRef", "rule": "React-createRef",
"path": "ts/components/Lightbox.js", "path": "ts/components/Lightbox.js",
"line": " this.videoRef = react_1.default.createRef();", "line": " this.videoRef = react_1.default.createRef();",
"lineNumber": 183, "lineNumber": 185,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-03-09T00:08:44.242Z", "updated": "2019-03-09T00:08:44.242Z",
"reasonDetail": "Used to auto-start playback on videos" "reasonDetail": "Used to auto-start playback on videos"
@ -7493,7 +7493,7 @@
"rule": "React-createRef", "rule": "React-createRef",
"path": "ts/components/Lightbox.tsx", "path": "ts/components/Lightbox.tsx",
"line": " this.videoRef = React.createRef();", "line": " this.videoRef = React.createRef();",
"lineNumber": 179, "lineNumber": 181,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2019-03-09T00:08:44.242Z", "updated": "2019-03-09T00:08:44.242Z",
"reasonDetail": "Used to auto-start playback on videos" "reasonDetail": "Used to auto-start playback on videos"