diff --git a/.vscode/launch.json b/.vscode/launch.json
index 824eaa6a..8258179a 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -9,32 +9,57 @@
"type": "node",
"request": "attach",
"port": 9229,
+ "presentation": {
+ "hidden": false,
+ "group": "",
+ "order": 0
+ }
},
{
- "name": "Next: Attach Chrome",
- "type": "pwa-chrome",
- "request": "attach",
+ "name": "Next: Launch Edge",
+ "type": "pwa-msedge",
+ "request": "launch",
"port": 9222,
- "url": "${config:develop.attachurl}",
- "webRoot": "${workspaceFolder}"
- }
+ "url": "${config:develop.attachurl}", // Custom vscode config property. does not actually exist, but configurable via user config.
+ "webRoot": "${workspaceFolder}",
+ "presentation": {
+ "hidden": false,
+ "group": "",
+ "order": 0
+ }
+ },
{
- "name": "Next: Attach Edge",
- "type": "pwa-msedge",
- "request": "attach",
+ "name": "Next: Launch Chrome",
+ "type": "pwa-chrome",
+ "request": "launch",
"port": 9222,
- "url": "${config:develop.attachurl}",
- "webRoot": "${workspaceFolder}"
+ "url": "${config:develop.attachurl}", // Custom vscode config property. does not actually exist, but configurable via user config.
+ "webRoot": "${workspaceFolder}",
+ "presentation": {
+ "hidden": false,
+ "group": "",
+ "order": 0
+ }
}
],
"compounds": [
{
- "name": "Next: Attach All",
- "configurations": ["Next: Attach Server", "Next: Attach Chrome"]
+ "name": "Next: Attach & Launch Edge",
+ "configurations": ["Next: Attach Server", "Next: Launch Edge"],
+ "presentation": {
+ "hidden": false,
+ "group": "next",
+ "order": 0
+ }
},
{
- "name": "Next: Attach All (Edge)",
- "configurations": ["Next: Attach Server", "Next: Attach Edge"]
+ "name": "Next: Attach & Launch Chrome",
+ "configurations": ["Next: Attach Server", "Next: Launch Edge"],
+ "presentation": {
+ "hidden": false,
+ "group": "next",
+ "order": 1
+ }
}
]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 9f11f470..35456f1c 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -61,5 +61,4 @@
"stylelint.packageManager": "yarn",
"stylelint.reportNeedlessDisables": true,
"cSpell.language": "en,en-US",
- "develop.attachurl": "http://localhost:3000/"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb6c5e25..fe2e841f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,12 +18,16 @@ For detailed rules of this file, see [Changelog Rules](#changelog-rules)
* Optimized image loading and accessibility for images site-wide. - [#328][]
* Further optimized font loading. - [#328][]
* Moved raw version information to an API route (`/api/version`), and reworked version page to draw information from that route. - [#328][]
-* Other smaller changes to sreamline development. - [#328][]
+* Moved all custom server functions into suitable replacements provided by our site framework. - [#329][]
+ * This move has let us drop our entire custom backend.
+* Updated `` with an improved loading state animation. - [#330][]
+* Other smaller changes to sreamline development. - [#328][], [#329][]
### 🐛 Fixed
* Resolved form submitting issues that occured when password evaluation fails to load. - [#328][]
* Fixed authorization page displaying an `Invalid Authorize Request` error when redirecting users after login. - [#328][]
+* Fixed `Using Odyssey` switch not properly entering loading state while waiting on a response from the API. - [#330][]
### ⚙ Tasks
* Update lint configs
@@ -31,6 +35,8 @@ For detailed rules of this file, see [Changelog Rules](#changelog-rules)
[#328]: https://github.com/fuelRats/fuelrats.com/pull/328
+[#329]: https://github.com/fuelRats/fuelrats.com/pull/329
+[#330]: https://github.com/fuelRats/fuelrats.com/pull/330
[Unreleased]: https://github.com/FuelRats/fuelrats.com/compare/v2.13.0...HEAD
diff --git a/src/components/RatCard/RatCard.js b/src/components/RatCard/RatCard.js
index 80b621eb..dd96d6bf 100644
--- a/src/components/RatCard/RatCard.js
+++ b/src/components/RatCard/RatCard.js
@@ -147,8 +147,8 @@ class RatCard extends React.Component {
}
}
- _handleOdysseySwitch = async () => {
- await this.props.updateRat({
+ _handleOdysseySwitch = () => {
+ return this.props.updateRat({
id: this.props.rat.id,
attributes: {
odyssey: !this.props.rat.attributes.odyssey,
@@ -224,10 +224,10 @@ class RatCard extends React.Component {
rat.attributes.platform === 'pc' && (
+ onChange={this._handleOdysseySwitch} />
)
}
diff --git a/src/components/Switch/Switch.js b/src/components/Switch/Switch.js
index d97827ed..7356a21c 100644
--- a/src/components/Switch/Switch.js
+++ b/src/components/Switch/Switch.js
@@ -2,6 +2,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import PropTypes from 'prop-types'
import { useCallback, useState } from 'react'
+import isPromise from '~/util/isPromise'
+
import styles from './Switch.module.scss'
@@ -10,7 +12,6 @@ import styles from './Switch.module.scss'
function Switch (props) {
const {
- async: isAsync,
containerProps,
className,
disabled,
@@ -23,19 +24,17 @@ function Switch (props) {
const [loading, setLoading] = useState(false)
const handleChange = useCallback(async (event) => {
- if (!isAsync) {
- onChange?.(event)
- return
+ const result = onChange?.(event)
+ if (isPromise(result)) {
+ setLoading(true)
+ await result
+ setLoading(false)
}
-
- setLoading(true)
- await onChange?.(event)
- setLoading(false)
- }, [isAsync, onChange])
+ }, [onChange])
let icon = 'times'
if (loading) {
- icon = 'circle'
+ icon = 'sync'
} else if (props.checked) {
icon = 'check'
}
@@ -71,7 +70,6 @@ function Switch (props) {
}
Switch.propTypes = {
- async: PropTypes.bool,
checked: PropTypes.bool,
className: PropTypes.string,
containerProps: PropTypes.object,
diff --git a/src/components/Switch/Switch.module.scss b/src/components/Switch/Switch.module.scss
index 20b3221a..a315ec4a 100644
--- a/src/components/Switch/Switch.module.scss
+++ b/src/components/Switch/Switch.module.scss
@@ -1,5 +1,15 @@
@import '../../scss/colors';
+@keyframes loader-spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
.switch {
display: inline-block;
position: relative;
@@ -23,6 +33,11 @@
background: $grey;
transform: translateX(50%);
+
+ > path {
+ animation: loader-spin 2s infinite linear;
+ transform-origin: center;
+ }
}
}
diff --git a/src/util/isPromise.js b/src/util/isPromise.js
new file mode 100644
index 00000000..2e84334a
--- /dev/null
+++ b/src/util/isPromise.js
@@ -0,0 +1,9 @@
+/**
+ * Accepts an object and tests some basic patterns of promises
+ * @param {any} obj
+ * @returns {boolean}
+ */
+export default function isPromise (obj) {
+ return (typeof obj === 'object' || typeof obj === 'function')
+ && typeof obj.then === 'function'
+}