From 40b684d7de997f667d858ad13a1c8bb9d373c576 Mon Sep 17 00:00:00 2001 From: Robin Townsend Date: Tue, 23 Feb 2021 19:41:23 -0500 Subject: [PATCH] Vectorize spinners This replaces most of the GIF spinners used throughout the app with an SVG that respects the user's theme. However, spinner.gif is still retained for the room timeline avatar uploader component, since it is more difficult to replace. Signed-off-by: Robin Townsend --- res/css/views/elements/_InlineSpinner.scss | 19 +- res/css/views/elements/_Spinner.scss | 16 ++ res/img/logo-spinner.svg | 141 +++++++++++ res/img/spinner.svg | 235 +++++++----------- .../views/elements/InlineSpinner.js | 26 +- src/components/views/elements/Spinner.js | 28 ++- 6 files changed, 304 insertions(+), 161 deletions(-) create mode 100644 res/img/logo-spinner.svg diff --git a/res/css/views/elements/_InlineSpinner.scss b/res/css/views/elements/_InlineSpinner.scss index 6b91e45923..c850191b93 100644 --- a/res/css/views/elements/_InlineSpinner.scss +++ b/res/css/views/elements/_InlineSpinner.scss @@ -18,7 +18,24 @@ limitations under the License. display: inline; } -.mx_InlineSpinner_spin img { +.mx_InlineSpinner img, .mx_InlineSpinner_icon { margin: 0px 6px; vertical-align: -3px; } + +@keyframes spin { + from { + transform: rotateZ(0deg); + } + to { + transform: rotateZ(360deg); + } +} + +.mx_InlineSpinner_icon { + display: inline-block; + background-color: $primary-fg-color; + mask: url('$(res)/img/spinner.svg'); + mask-size: contain; + animation: 1.1s steps(12, end) infinite spin; +} diff --git a/res/css/views/elements/_Spinner.scss b/res/css/views/elements/_Spinner.scss index 01b4f23c2c..93d5e2d96c 100644 --- a/res/css/views/elements/_Spinner.scss +++ b/res/css/views/elements/_Spinner.scss @@ -26,3 +26,19 @@ limitations under the License. .mx_MatrixChat_middlePanel .mx_Spinner { height: auto; } + +@keyframes spin { + from { + transform: rotateZ(0deg); + } + to { + transform: rotateZ(360deg); + } +} + +.mx_Spinner_icon { + background-color: $primary-fg-color; + mask: url('$(res)/img/spinner.svg'); + mask-size: contain; + animation: 1.1s steps(12, end) infinite spin; +} diff --git a/res/img/logo-spinner.svg b/res/img/logo-spinner.svg new file mode 100644 index 0000000000..08965e982e --- /dev/null +++ b/res/img/logo-spinner.svg @@ -0,0 +1,141 @@ + + + start + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/img/spinner.svg b/res/img/spinner.svg index 08965e982e..c3680f19d2 100644 --- a/res/img/spinner.svg +++ b/res/img/spinner.svg @@ -1,141 +1,96 @@ - - - start - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/src/components/views/elements/InlineSpinner.js b/src/components/views/elements/InlineSpinner.js index 73316157f4..2dad9ebe1e 100644 --- a/src/components/views/elements/InlineSpinner.js +++ b/src/components/views/elements/InlineSpinner.js @@ -24,23 +24,29 @@ export default class InlineSpinner extends React.Component { const h = this.props.h || 16; const imgClass = this.props.imgClassName || ""; - let imageSource; + let icon; if (SettingsStore.getValue('feature_new_spinner')) { - imageSource = require("../../../../res/img/spinner.svg"); - } else { - imageSource = require("../../../../res/img/spinner.gif"); - } - - return ( -
+ icon = ( -
+ ); + } else { + icon = ( +
+ ); + } + + return ( +
{ icon }
); } } diff --git a/src/components/views/elements/Spinner.js b/src/components/views/elements/Spinner.js index 4d2dcea90a..43030d01d5 100644 --- a/src/components/views/elements/Spinner.js +++ b/src/components/views/elements/Spinner.js @@ -21,23 +21,31 @@ import {_t} from "../../../languageHandler"; import SettingsStore from "../../../settings/SettingsStore"; const Spinner = ({w = 32, h = 32, imgClassName, message}) => { - let imageSource; + let icon; if (SettingsStore.getValue('feature_new_spinner')) { - imageSource = require("../../../../res/img/spinner.svg"); - } else { - imageSource = require("../../../../res/img/spinner.gif"); - } - - return ( -
- { message &&
{ message}
 
} + icon = ( + ); + } else { + icon = ( +
+ ); + } + + return ( +
+ { message &&
{ message }
 
} + { icon }
); };