summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Goldberg ✨ <git@joshuakgoldberg.com>2023-11-28 18:47:55 +0100
committerGitHub <noreply@github.com>2023-11-28 17:47:55 +0000
commit1142f4c79e3eaf4450ed727de0f480e300e8b9a2 (patch)
treef034968ea7cd63070a1c6e942035355d96ca7d4b
parentcdc789424355617c800dc3b589b36fdfdc01b796 (diff)
Converted app/javascript/mastodon/utils/ folder to TypeScript (#27895)
-rw-r--r--app/javascript/mastodon/utils/__tests__/base64-test.ts (renamed from app/javascript/mastodon/utils/__tests__/base64-test.js)0
-rw-r--r--app/javascript/mastodon/utils/__tests__/html-test.s (renamed from app/javascript/mastodon/utils/__tests__/html-test.js)0
-rw-r--r--app/javascript/mastodon/utils/config.js10
-rw-r--r--app/javascript/mastodon/utils/config.ts13
-rw-r--r--app/javascript/mastodon/utils/html.js6
-rw-r--r--app/javascript/mastodon/utils/html.ts9
-rw-r--r--app/javascript/mastodon/utils/icons.tsx (renamed from app/javascript/mastodon/utils/icons.jsx)14
-rw-r--r--app/javascript/mastodon/utils/log_out.ts (renamed from app/javascript/mastodon/utils/log_out.js)0
-rw-r--r--app/javascript/mastodon/utils/notifications.js30
-rw-r--r--app/javascript/mastodon/utils/notifications.ts13
-rw-r--r--app/javascript/mastodon/utils/react_router.tsx (renamed from app/javascript/mastodon/utils/react_router.jsx)40
-rw-r--r--app/javascript/mastodon/utils/scrollbar.ts (renamed from app/javascript/mastodon/utils/scrollbar.js)15
-rw-r--r--package.json1
-rw-r--r--yarn.lock8
14 files changed, 84 insertions, 75 deletions
diff --git a/app/javascript/mastodon/utils/__tests__/base64-test.js b/app/javascript/mastodon/utils/__tests__/base64-test.ts
index 1b3260faaf1..1b3260faaf1 100644
--- a/app/javascript/mastodon/utils/__tests__/base64-test.js
+++ b/app/javascript/mastodon/utils/__tests__/base64-test.ts
diff --git a/app/javascript/mastodon/utils/__tests__/html-test.js b/app/javascript/mastodon/utils/__tests__/html-test.s
index d948cf4c5d2..d948cf4c5d2 100644
--- a/app/javascript/mastodon/utils/__tests__/html-test.js
+++ b/app/javascript/mastodon/utils/__tests__/html-test.s
diff --git a/app/javascript/mastodon/utils/config.js b/app/javascript/mastodon/utils/config.js
deleted file mode 100644
index 932cd0cbf54..00000000000
--- a/app/javascript/mastodon/utils/config.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import ready from '../ready';
-
-export let assetHost = '';
-
-ready(() => {
- const cdnHost = document.querySelector('meta[name=cdn-host]');
- if (cdnHost) {
- assetHost = cdnHost.content || '';
- }
-});
diff --git a/app/javascript/mastodon/utils/config.ts b/app/javascript/mastodon/utils/config.ts
new file mode 100644
index 00000000000..9222c89d1ba
--- /dev/null
+++ b/app/javascript/mastodon/utils/config.ts
@@ -0,0 +1,13 @@
+import ready from '../ready';
+
+export let assetHost = '';
+
+// eslint-disable-next-line @typescript-eslint/no-floating-promises
+ready(() => {
+ const cdnHost = document.querySelector<HTMLMetaElement>(
+ 'meta[name=cdn-host]',
+ );
+ if (cdnHost) {
+ assetHost = cdnHost.content || '';
+ }
+});
diff --git a/app/javascript/mastodon/utils/html.js b/app/javascript/mastodon/utils/html.js
deleted file mode 100644
index 247e98c88a7..00000000000
--- a/app/javascript/mastodon/utils/html.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// NB: This function can still return unsafe HTML
-export const unescapeHTML = (html) => {
- const wrapper = document.createElement('div');
- wrapper.innerHTML = html.replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n').replace(/<[^>]*>/g, '');
- return wrapper.textContent;
-};
diff --git a/app/javascript/mastodon/utils/html.ts b/app/javascript/mastodon/utils/html.ts
new file mode 100644
index 00000000000..0145a045516
--- /dev/null
+++ b/app/javascript/mastodon/utils/html.ts
@@ -0,0 +1,9 @@
+// NB: This function can still return unsafe HTML
+export const unescapeHTML = (html: string) => {
+ const wrapper = document.createElement('div');
+ wrapper.innerHTML = html
+ .replace(/<br\s*\/?>/g, '\n')
+ .replace(/<\/p><p>/g, '\n\n')
+ .replace(/<[^>]*>/g, '');
+ return wrapper.textContent;
+};
diff --git a/app/javascript/mastodon/utils/icons.jsx b/app/javascript/mastodon/utils/icons.tsx
index be566032e06..6e432e32fa4 100644
--- a/app/javascript/mastodon/utils/icons.jsx
+++ b/app/javascript/mastodon/utils/icons.tsx
@@ -1,13 +1,23 @@
// Copied from emoji-mart for consistency with emoji picker and since
// they don't export the icons in the package
export const loupeIcon = (
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' width='13' height='13'>
+ <svg
+ xmlns='http://www.w3.org/2000/svg'
+ viewBox='0 0 20 20'
+ width='13'
+ height='13'
+ >
<path d='M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z' />
</svg>
);
export const deleteIcon = (
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' width='13' height='13'>
+ <svg
+ xmlns='http://www.w3.org/2000/svg'
+ viewBox='0 0 20 20'
+ width='13'
+ height='13'
+ >
<path d='M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z' />
</svg>
);
diff --git a/app/javascript/mastodon/utils/log_out.js b/app/javascript/mastodon/utils/log_out.ts
index 3a4cc8ecb1e..3a4cc8ecb1e 100644
--- a/app/javascript/mastodon/utils/log_out.js
+++ b/app/javascript/mastodon/utils/log_out.ts
diff --git a/app/javascript/mastodon/utils/notifications.js b/app/javascript/mastodon/utils/notifications.js
deleted file mode 100644
index 42623ac7c68..00000000000
--- a/app/javascript/mastodon/utils/notifications.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Handles browser quirks, based on
-// https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API
-
-const checkNotificationPromise = () => {
- try {
- // eslint-disable-next-line promise/valid-params, promise/catch-or-return
- Notification.requestPermission().then();
- } catch(e) {
- return false;
- }
-
- return true;
-};
-
-const handlePermission = (permission, callback) => {
- // Whatever the user answers, we make sure Chrome stores the information
- if(!('permission' in Notification)) {
- Notification.permission = permission;
- }
-
- callback(Notification.permission);
-};
-
-export const requestNotificationPermission = (callback) => {
- if (checkNotificationPromise()) {
- Notification.requestPermission().then((permission) => handlePermission(permission, callback)).catch(console.warn);
- } else {
- Notification.requestPermission((permission) => handlePermission(permission, callback));
- }
-};
diff --git a/app/javascript/mastodon/utils/notifications.ts b/app/javascript/mastodon/utils/notifications.ts
new file mode 100644
index 00000000000..08f677f8fe5
--- /dev/null
+++ b/app/javascript/mastodon/utils/notifications.ts
@@ -0,0 +1,13 @@
+/**
+ * Tries Notification.requestPermission, console warning instead of rejecting on error.
+ * @param callback Runs with the permission result on completion.
+ */
+export const requestNotificationPermission = async (
+ callback: NotificationPermissionCallback,
+) => {
+ try {
+ callback(await Notification.requestPermission());
+ } catch (error) {
+ console.warn(error);
+ }
+};
diff --git a/app/javascript/mastodon/utils/react_router.jsx b/app/javascript/mastodon/utils/react_router.tsx
index fa8f0db2b5c..0682fee5542 100644
--- a/app/javascript/mastodon/utils/react_router.jsx
+++ b/app/javascript/mastodon/utils/react_router.tsx
@@ -1,8 +1,8 @@
-import PropTypes from "prop-types";
+import PropTypes from 'prop-types';
-import { __RouterContext } from "react-router";
+import { __RouterContext } from 'react-router';
-import hoistStatics from "hoist-non-react-statics";
+import hoistStatics from 'hoist-non-react-statics';
export const WithRouterPropTypes = {
match: PropTypes.object.isRequired,
@@ -16,31 +16,37 @@ export const WithOptionalRouterPropTypes = {
history: PropTypes.object,
};
+export interface OptionalRouterProps {
+ ref: unknown;
+ wrappedComponentRef: unknown;
+}
+
// This is copied from https://github.com/remix-run/react-router/blob/v5.3.4/packages/react-router/modules/withRouter.js
// but does not fail if called outside of a React Router context
-export function withOptionalRouter(Component) {
- const displayName = `withRouter(${Component.displayName || Component.name})`;
- const C = props => {
+export function withOptionalRouter<
+ ComponentType extends React.ComponentType<OptionalRouterProps>,
+>(Component: ComponentType) {
+ const displayName = `withRouter(${Component.displayName ?? Component.name})`;
+ const C = (props: React.ComponentProps<ComponentType>) => {
const { wrappedComponentRef, ...remainingProps } = props;
return (
<__RouterContext.Consumer>
- {context => {
- if(context)
+ {(context) => {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (context) {
return (
+ // @ts-expect-error - Dynamic covariant generic components are tough to type.
<Component
{...remainingProps}
{...context}
ref={wrappedComponentRef}
/>
);
- else
- return (
- <Component
- {...remainingProps}
- ref={wrappedComponentRef}
- />
- );
+ } else {
+ // @ts-expect-error - Dynamic covariant generic components are tough to type.
+ return <Component {...remainingProps} ref={wrappedComponentRef} />;
+ }
}}
</__RouterContext.Consumer>
);
@@ -53,8 +59,8 @@ export function withOptionalRouter(Component) {
wrappedComponentRef: PropTypes.oneOfType([
PropTypes.string,
PropTypes.func,
- PropTypes.object
- ])
+ PropTypes.object,
+ ]),
};
return hoistStatics(C, Component);
diff --git a/app/javascript/mastodon/utils/scrollbar.js b/app/javascript/mastodon/utils/scrollbar.ts
index ca87dd76f5e..d505df12449 100644
--- a/app/javascript/mastodon/utils/scrollbar.js
+++ b/app/javascript/mastodon/utils/scrollbar.ts
@@ -1,11 +1,7 @@
import { isMobile } from '../is_mobile';
-/** @type {number | null} */
-let cachedScrollbarWidth = null;
+let cachedScrollbarWidth: number | null = null;
-/**
- * @returns {number}
- */
const getActualScrollbarWidth = () => {
const outer = document.createElement('div');
outer.style.visibility = 'hidden';
@@ -16,20 +12,19 @@ const getActualScrollbarWidth = () => {
outer.appendChild(inner);
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
- outer.parentNode.removeChild(outer);
+ outer.remove();
return scrollbarWidth;
};
-/**
- * @returns {number}
- */
export const getScrollbarWidth = () => {
if (cachedScrollbarWidth !== null) {
return cachedScrollbarWidth;
}
- const scrollbarWidth = isMobile(window.innerWidth) ? 0 : getActualScrollbarWidth();
+ const scrollbarWidth = isMobile(window.innerWidth)
+ ? 0
+ : getActualScrollbarWidth();
cachedScrollbarWidth = scrollbarWidth;
return scrollbarWidth;
diff --git a/package.json b/package.json
index 2f324f77a70..543af8a4b87 100644
--- a/package.json
+++ b/package.json
@@ -161,6 +161,7 @@
"@types/object-assign": "^4.0.30",
"@types/prop-types": "^15.7.5",
"@types/punycode": "^2.1.0",
+ "@types/rails__ujs": "^6.0.4",
"@types/react": "^18.2.7",
"@types/react-dom": "^18.2.4",
"@types/react-helmet": "^6.1.6",
diff --git a/yarn.lock b/yarn.lock
index 0dd9a627cd1..11c2724d59c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2317,6 +2317,7 @@ __metadata:
"@types/object-assign": "npm:^4.0.30"
"@types/prop-types": "npm:^15.7.5"
"@types/punycode": "npm:^2.1.0"
+ "@types/rails__ujs": "npm:^6.0.4"
"@types/react": "npm:^18.2.7"
"@types/react-dom": "npm:^18.2.4"
"@types/react-helmet": "npm:^6.1.6"
@@ -3349,6 +3350,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/rails__ujs@npm:^6.0.4":
+ version: 6.0.4
+ resolution: "@types/rails__ujs@npm:6.0.4"
+ checksum: 7477cb03a0e1339b9cd5c8ac4a197a153e2ff48742b2f527c5a39dcdf80f01493011e368483290d3717662c63066fada3ab203a335804cbb3573cf575f37007e
+ languageName: node
+ linkType: hard
+
"@types/range-parser@npm:*":
version: 1.2.7
resolution: "@types/range-parser@npm:1.2.7"