I wrote a `forceWrap` method to support break-word wrapping in table
cells for scavengers, but apparently code blocks need it too, so I'm
moving it to Utils.
Fixes#7854
It seems every other week TypeScript does an update that affects
whether or not this line needs a cast.
This should probably have been refactored to `typeof` ages ago, because
that one way more reliably doesn't need a cast.
When settings.blockInvites is false or undefined, we should allow room invites to be sent.
However, this code denies it because it thinks that the user sending the message is not of the rank "undefined" (or "false"), which isn't a real rank.
- Default precision is now 3.
(Instead of "3 months 25 days 17 hours 46 minutes 40 seconds", it'll
say "3 months 25 days 17 hours". You can still set the precision to
`Infinity` if you actually prefer that.)
- Now displays "forever" for Infinity or overflow durations
- No longer skips blank precision levels
(Shows "3 hours 0 minutes 10 seconds" instead of
"3 hours 10 seconds")
* Lint arrow-body-style
* Lint prefer-object-spread
Object spread is faster _and_ more readable.
This also fixes a few unnecessary object clones.
* Enable no-parameter-properties
This isn't currently used, but this makes clear that it shouldn't be.
* Refactor more Promises to async/await
* Remove unnecessary code from getDataMoveHTML etc
* Lint prefer-string-starts-ends-with
* Stop using no-undef
According to the typescript-eslint FAQ, this is redundant with
TypeScript, and they're not wrong. This will save us from needing to
specify globals in two different places which will be nice.
This provides a new way to persist chat plugin data across hotpatches:
`Chat.oldPlugins`.
In a plugin, you can now do:
```
export const cache = Chat.oldPlugins.pluginname?.cache || {};
```
to create a cache that will persist across hotpatches.