From 7b82cc7b796565a888949a7375c8b5aa476201c4 Mon Sep 17 00:00:00 2001 From: Puyodead1 Date: Tue, 15 Oct 2024 15:28:03 -0400 Subject: [PATCH] some refactoring --- .gitignore | 10 +- .vscode/settings.json | 1 + package.json | 10 +- pnpm-lock.yaml | 574 +++++++++--------- src/App.tsx | 32 +- src/components/AuthComponents.tsx | 2 +- src/components/AuthenticationGuard.tsx | 29 + src/components/Avatar.tsx | 9 +- src/components/ChannelHeader.tsx | 5 +- src/components/ChannelList/ChannelList.tsx | 2 +- .../ChannelList/ChannelListItem.tsx | 17 +- src/components/ChannelSidebar.tsx | 4 +- src/components/GuildItem.tsx | 16 +- src/components/GuildSidebar.tsx | 4 +- src/components/InviteEmbed.tsx | 271 +++++++++ src/components/Loader.tsx | 6 +- src/components/MemberList/MemberList.tsx | 6 +- src/components/MemberList/MemberListItem.tsx | 11 +- src/components/SectionTitle.tsx | 1 + src/components/SidebarAction.tsx | 11 +- src/components/SidebarPill.tsx | 2 +- src/components/Tooltip.tsx | 2 +- src/components/UserPanel.tsx | 7 +- src/components/banners/OfflineBanner.tsx | 2 +- src/components/banners/index.ts | 1 + .../contextMenus/ChannelContextMenu.tsx | 4 +- .../ChannelMentionContextMenu.tsx | 2 +- src/components/contextMenus/ContextMenu.tsx | 2 +- .../contextMenus/GuildContextMenu.tsx | 8 +- .../contextMenus/MessageContextMenu.tsx | 6 +- .../contextMenus/UserContextMenu.tsx | 7 +- src/components/contextMenus/index.ts | 6 + src/components/floating/Floating.tsx | 10 +- src/components/floating/FloatingContent.tsx | 2 +- src/components/floating/FloatingTrigger.tsx | 2 +- src/components/floating/GuildMenuPopout.tsx | 10 +- src/components/floating/UserProfilePopout.tsx | 16 +- src/components/floating/index.ts | 6 + src/components/guards/AuthenticationGuard.tsx | 22 - .../guards/UnauthenticatedGuard.tsx | 22 - src/components/index.ts | 31 + src/components/markdown/MarkdownRenderer.tsx | 10 +- .../{ => markdown/components}/Codeblock.tsx | 6 +- .../markdown/{ => components}/Mention.tsx | 13 +- .../{ => markdown/components}/Spoiler.tsx | 0 .../markdown/{ => components}/Timestamp.tsx | 3 +- src/components/markdown/components/index.ts | 4 + src/components/markdown/index.ts | 4 + src/components/markdown/style.css | 160 ----- src/components/media/Audio.tsx | 10 +- src/components/media/File.tsx | 6 +- src/components/media/Video.tsx | 6 +- src/components/media/index.ts | 3 + src/components/messaging/Chat.tsx | 9 +- src/components/messaging/ChatHeader.tsx | 13 +- src/components/messaging/EmbedMedia.tsx | 4 +- src/components/messaging/Message.tsx | 16 +- .../messaging/MessageAttachment.tsx | 10 +- src/components/messaging/MessageAuthor.tsx | 13 +- src/components/messaging/MessageBase.tsx | 8 +- src/components/messaging/MessageEmbed.tsx | 8 +- src/components/messaging/MessageGroup.tsx | 2 +- src/components/messaging/MessageInput.tsx | 15 +- src/components/messaging/MessageList.tsx | 13 +- src/components/messaging/MessageTextArea.tsx | 7 +- src/components/messaging/SystemMessage.tsx | 4 +- src/components/messaging/TextareaAutosize.tsx | 276 +++++++++ src/components/messaging/TypingIndicator.tsx | 2 +- .../attachments/AttachmentUpload.tsx | 9 +- .../attachments/AttachmentUploadPreview.tsx | 8 +- .../attachments/AttachmentUploadProgress.tsx | 10 +- src/components/modals/AddServerModal.tsx | 4 +- src/components/modals/BanMemberModal.tsx | 4 +- src/components/modals/CreateChannelModel.tsx | 12 +- src/components/modals/CreateInviteModal.tsx | 20 +- src/components/modals/CreateServerModal.tsx | 12 +- src/components/modals/DeleteMessageModal.tsx | 6 +- src/components/modals/ErrorModal.tsx | 2 +- src/components/modals/InviteModal.tsx | 56 ++ src/components/modals/InviteUnauthedModal.tsx | 20 + src/components/modals/JoinServerModal.tsx | 12 +- src/components/modals/KickMemberModal.tsx | 4 +- src/components/modals/LeaveServerModal.tsx | 6 +- src/components/modals/ModalComponents.tsx | 6 +- src/components/modals/SettingsModal.tsx | 11 +- .../SettingsPages/AccountSettingsPage.tsx | 8 +- .../SettingsPages/DeveloperSettingsPage.tsx | 2 +- .../modals/SettingsPages/ExperimentsPage.tsx | 6 +- src/components/modals/index.ts | 2 + src/contexts/ContextMenuContext.ts | 7 +- src/contexts/ContextMenuContextProvider.tsx | 2 +- src/contexts/FloatingContext.tsx | 2 +- src/contexts/Theme.tsx | 4 +- src/controllers/banners/BannerController.tsx | 4 +- src/controllers/banners/BannerRenderer.tsx | 2 +- src/controllers/modals/ModalController.tsx | 4 +- src/controllers/modals/index.ts | 2 +- src/controllers/modals/types.ts | 17 +- src/hooks/useAppStore.ts | 2 +- src/hooks/useContextMenu.tsx | 14 +- src/hooks/useFloating.tsx | 2 +- src/hooks/useFloatingContext.tsx | 2 +- src/hooks/useLogger.ts | 2 +- src/index.tsx | 4 +- src/pages/AppPage.tsx | 2 +- src/pages/ErrorPage.tsx | 4 +- src/pages/InvitePage.tsx | 66 ++ src/pages/LoadingPage.tsx | 8 +- src/pages/LoginPage.tsx | 34 +- src/pages/LogoutPage.tsx | 2 +- src/pages/NotFound.tsx | 4 +- src/pages/RegistrationPage.tsx | 34 +- src/pages/subpages/ChannelPage.tsx | 16 +- src/pages/subpages/MFA.tsx | 22 +- src/stores/AccountStore.ts | 2 +- src/stores/AppStore.ts | 38 +- src/stores/ChannelStore.ts | 2 +- src/stores/GatewayConnectionStore.ts | 5 +- src/stores/GuildMemberListStore.ts | 5 +- src/stores/GuildMemberStore.ts | 5 +- src/stores/GuildStore.ts | 4 +- src/stores/MessageQueue.ts | 8 +- src/stores/MessageStore.ts | 10 +- src/stores/PresenceStore.ts | 2 +- src/stores/PrivateChannelStore.ts | 2 +- src/stores/ReadStateStore.ts | 2 +- src/stores/RoleStore.ts | 2 +- src/stores/ThemeStore.ts | 3 +- src/stores/UpdaterStore.ts | 4 +- src/stores/UserStore.ts | 4 +- src/stores/index.ts | 18 + src/stores/objects/Channel.ts | 9 +- src/stores/objects/Guild.ts | 11 +- src/stores/objects/GuildMember.ts | 4 +- src/stores/objects/Message.ts | 5 +- src/stores/objects/MessageBase.ts | 9 +- src/stores/objects/Presence.ts | 2 +- src/stores/objects/QueuedMessage.ts | 2 +- src/stores/objects/ReadState.ts | 4 +- src/stores/objects/Role.ts | 2 +- src/stores/objects/User.ts | 2 +- src/stores/objects/index.ts | 12 + src/utils/Message.ts | 44 -- src/utils/Permissions.ts | 28 +- src/utils/REST.ts | 4 +- src/utils/Utils.ts | 194 +++++- src/utils/constants.ts | 6 + src/utils/debounce.ts | 2 +- src/utils/index.ts | 15 + src/utils/isTouchscreenDevice.ts | 6 - src/utils/messageFromFieldError.ts | 33 - src/utils/mui/debounce.ts | 24 + src/utils/mui/index.ts | 6 + src/utils/mui/ownerDocument.ts | 4 + src/utils/mui/ownerWindow.ts | 7 + src/utils/mui/setRef.ts | 27 + src/utils/mui/useEnhancedEffect.ts | 12 + src/utils/mui/useForkRef.ts | 27 + tsconfig.json | 21 +- vite.config.ts | 61 +- 160 files changed, 1928 insertions(+), 1069 deletions(-) create mode 100644 src/components/AuthenticationGuard.tsx create mode 100644 src/components/InviteEmbed.tsx create mode 100644 src/components/banners/index.ts create mode 100644 src/components/contextMenus/index.ts create mode 100644 src/components/floating/index.ts delete mode 100644 src/components/guards/AuthenticationGuard.tsx delete mode 100644 src/components/guards/UnauthenticatedGuard.tsx create mode 100644 src/components/index.ts rename src/components/{ => markdown/components}/Codeblock.tsx (88%) rename src/components/markdown/{ => components}/Mention.tsx (88%) rename src/components/{ => markdown/components}/Spoiler.tsx (100%) rename src/components/markdown/{ => components}/Timestamp.tsx (91%) create mode 100644 src/components/markdown/components/index.ts create mode 100644 src/components/markdown/index.ts delete mode 100644 src/components/markdown/style.css create mode 100644 src/components/media/index.ts create mode 100644 src/components/messaging/TextareaAutosize.tsx create mode 100644 src/components/modals/InviteModal.tsx create mode 100644 src/components/modals/InviteUnauthedModal.tsx create mode 100644 src/pages/InvitePage.tsx create mode 100644 src/stores/index.ts create mode 100644 src/stores/objects/index.ts delete mode 100644 src/utils/Message.ts create mode 100644 src/utils/index.ts delete mode 100644 src/utils/isTouchscreenDevice.ts delete mode 100644 src/utils/messageFromFieldError.ts create mode 100644 src/utils/mui/debounce.ts create mode 100644 src/utils/mui/index.ts create mode 100644 src/utils/mui/ownerDocument.ts create mode 100644 src/utils/mui/ownerWindow.ts create mode 100644 src/utils/mui/setRef.ts create mode 100644 src/utils/mui/useEnhancedEffect.ts create mode 100644 src/utils/mui/useForkRef.ts diff --git a/.gitignore b/.gitignore index 3979734..fc89a0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,15 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies -/node_modules -/.pnp +node_modules +.pnp .pnp.js # testing -/coverage +coverage # production -/dist +dist # misc .DS_Store @@ -22,3 +22,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* src-tauri/.cargo/config.toml + +.swc/ diff --git a/.vscode/settings.json b/.vscode/settings.json index 2c63c08..15d3835 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,2 +1,3 @@ { + "references.preferredLocation": "view" } diff --git a/package.json b/package.json index 32a23c1..7095f30 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "@mattjennings/react-modal-stack": "^1.0.4", "@mdi/js": "^7.4.47", "@mdi/react": "^1.6.1", - "@mui/material": "^6.1.3", "@originjs/vite-plugin-commonjs": "^1.0.3", "@rollup/plugin-replace": "^6.0.1", "@spacebarchat/spacebar-api-types": "0.37.51", @@ -75,6 +74,7 @@ }, "devDependencies": { "@craco/craco": "^7.1.0", + "@swc/plugin-styled-components": "^3.0.3", "@tauri-apps/cli": "2.0.2", "@types/jest": "^29.5.13", "@types/loadable__component": "^5.13.9", @@ -88,10 +88,12 @@ "@typescript-eslint/eslint-plugin": "^8.7.0", "@typescript-eslint/parser": "^8.7.0", "@vitejs/plugin-react": "^4.3.2", + "@vitejs/plugin-react-swc": "^3.7.1", "cross-env": "^7.0.3", "eslint": "^8.57.1", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.12", + "source-map-explorer": "^2.5.3", "typescript": "^5.6.3", "vite": "^5.4.8", "vite-plugin-chunk-split": "^0.5.0", @@ -108,12 +110,14 @@ "url": "git+https://github.com/spacebarchat/client.git" }, "scripts": { + "dev": "vite --open", + "preview": "vite preview", + "analyze": "source-map-explorer 'dist/asset/*.js'", "build": "tsc && vite build", + "build:dev": "tsc && cross-env VITE_ENV_DEV=true vite build", "ci:prebuild": "node scripts/tauri-version.js", - "dev": "vite", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint:fix": "pnpx prettier . --write", - "preview": "vite preview", "tauri:dev": "pnpm run ci:prebuild && tauri dev", "tauri:build": "pnpm run ci:prebuild && tauri build", "tauri:android:dev": "pnpm run ci:prebuild && tauri android dev", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c628592..8981ad0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,9 +38,6 @@ importers: '@mdi/react': specifier: ^1.6.1 version: 1.6.1 - '@mui/material': - specifier: ^6.1.3 - version: 6.1.3(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@originjs/vite-plugin-commonjs': specifier: ^1.0.3 version: 1.0.3 @@ -215,7 +212,10 @@ importers: devDependencies: '@craco/craco': specifier: ^7.1.0 - version: 7.1.0(@types/node@22.7.5)(postcss@8.4.47)(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(type-fest@4.26.1)(typescript@5.6.3))(typescript@5.6.3) + version: 7.1.0(@swc/core@1.7.35)(@types/node@22.7.5)(postcss@8.4.47)(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(@swc/core@1.7.35)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3))(type-fest@4.26.1)(typescript@5.6.3))(typescript@5.6.3) + '@swc/plugin-styled-components': + specifier: ^3.0.3 + version: 3.0.3 '@tauri-apps/cli': specifier: 2.0.2 version: 2.0.2 @@ -255,6 +255,9 @@ importers: '@vitejs/plugin-react': specifier: ^4.3.2 version: 4.3.2(vite@5.4.8(@types/node@22.7.5)(terser@5.34.1)) + '@vitejs/plugin-react-swc': + specifier: ^3.7.1 + version: 3.7.1(vite@5.4.8(@types/node@22.7.5)(terser@5.34.1)) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -267,6 +270,9 @@ importers: eslint-plugin-react-refresh: specifier: ^0.4.12 version: 0.4.12(eslint@8.57.1) + source-map-explorer: + specifier: ^2.5.3 + version: 2.5.3 typescript: specifier: ^5.6.3 version: 5.6.3 @@ -1835,86 +1841,6 @@ packages: '@mdi/react@1.6.1': resolution: {integrity: sha512-4qZeDcluDFGFTWkHs86VOlHkm6gnKaMql13/gpIcUQ8kzxHgpj31NuCkD8abECVfbULJ3shc7Yt4HJ6Wu6SN4w==} - '@mui/core-downloads-tracker@6.1.3': - resolution: {integrity: sha512-ajMUgdfhTb++rwqj134Cq9f4SRN8oXUqMRnY72YBnXiXai3olJLLqETheRlq3MM8wCKrbq7g6j7iWL1VvP44VQ==} - - '@mui/material@6.1.3': - resolution: {integrity: sha512-loV5MBoMKLrK80JeWINmQ1A4eWoLv51O2dBPLJ260IAhupkB3Wol8lEQTEvvR2vO3o6xRHuXe1WaQEP6N3riqg==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@emotion/react': ^11.5.0 - '@emotion/styled': ^11.3.0 - '@mui/material-pigment-css': ^6.1.3 - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - '@mui/material-pigment-css': - optional: true - '@types/react': - optional: true - - '@mui/private-theming@6.1.3': - resolution: {integrity: sha512-XK5OYCM0x7gxWb/WBEySstBmn+dE3YKX7U7jeBRLm6vHU5fGUd7GiJWRirpivHjOK9mRH6E1MPIVd+ze5vguKQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - '@mui/styled-engine@6.1.3': - resolution: {integrity: sha512-i4yh9m+eMZE3cNERpDhVr6Wn73Yz6C7MH0eE2zZvw8d7EFkIJlCQNZd1xxGZqarD2DDq2qWHcjIOucWGhxACtA==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@emotion/react': ^11.4.1 - '@emotion/styled': ^11.3.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - - '@mui/system@6.1.3': - resolution: {integrity: sha512-ILaD9UsLTBLjMcep3OumJMXh1PYr7aqnkHm/L47bH46+YmSL1zWAX6tWG8swEQROzW2GvYluEMp5FreoxOOC6w==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@emotion/react': ^11.5.0 - '@emotion/styled': ^11.3.0 - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - '@types/react': - optional: true - - '@mui/types@7.2.18': - resolution: {integrity: sha512-uvK9dWeyCJl/3ocVnTOS6nlji/Knj8/tVqVX03UVTpdmTJYu/s4jtDd9Kvv0nRGE0CUSNW1UYAci7PYypjealg==} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - '@mui/utils@6.1.3': - resolution: {integrity: sha512-4JBpLkjprlKjN10DGb1aiy/ii9TKbQ601uSHtAmYFAS879QZgAD7vRnv/YBE4iBbc7NXzFgbQMCOFrupXWekIA==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -1963,9 +1889,6 @@ packages: webpack-plugin-serve: optional: true - '@popperjs/core@2.11.8': - resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@react-native-community/cli-clean@14.1.0': resolution: {integrity: sha512-/C4j1yntLo6faztNgZnsDtgpGqa6j0+GYrxOY8LqaKAN03OCnoeUUKO6w78dycbYSGglc1xjJg2RZI/M2oF2AA==} @@ -2447,6 +2370,84 @@ packages: resolution: {integrity: sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==} engines: {node: '>=10'} + '@swc/core-darwin-arm64@1.7.35': + resolution: {integrity: sha512-BQSSozVxjxS+SVQz6e3GC/+OBWGIK3jfe52pWdANmycdjF3ch7lrCKTHTU7eHwyoJ96mofszPf5AsiVJF34Fwg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.7.35': + resolution: {integrity: sha512-44TYdKN/EWtkU88foXR7IGki9JzhEJzaFOoPevfi9Xe7hjAD/x2+AJOWWqQNzDPMz9+QewLdUVLyR6s5okRgtg==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.7.35': + resolution: {integrity: sha512-ccfA5h3zxwioD+/z/AmYtkwtKz9m4rWTV7RoHq6Jfsb0cXHrd6tbcvgqRWXra1kASlE+cDWsMtEZygs9dJRtUQ==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.7.35': + resolution: {integrity: sha512-hx65Qz+G4iG/IVtxJKewC5SJdki8PAPFGl6gC/57Jb0+jA4BIoGLD/J3Q3rCPeoHfdqpkCYpahtyUq8CKx41Jg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.7.35': + resolution: {integrity: sha512-kL6tQL9No7UEoEvDRuPxzPTpxrvbwYteNRbdChSSP74j13/55G2/2hLmult5yFFaWuyoyU/2lvzjRL/i8OLZxg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.7.35': + resolution: {integrity: sha512-Ke4rcLQSwCQ2LHdJX1FtnqmYNQ3IX6BddKlUtS7mcK13IHkQzZWp0Dcu6MgNA3twzb/dBpKX5GLy07XdGgfmyw==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.7.35': + resolution: {integrity: sha512-T30tlLnz0kYyDFyO5RQF5EQ4ENjW9+b56hEGgFUYmfhFhGA4E4V67iEx7KIG4u0whdPG7oy3qjyyIeTb7nElEw==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.7.35': + resolution: {integrity: sha512-CfM/k8mvtuMyX+okRhemfLt784PLS0KF7Q9djA8/Dtavk0L5Ghnq+XsGltO3d8B8+XZ7YOITsB14CrjehzeHsg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.7.35': + resolution: {integrity: sha512-ATB3uuH8j/RmS64EXQZJSbo2WXfRNpTnQszHME/sGaexsuxeijrp3DTYSFAA3R2Bu6HbIIX6jempe1Au8I3j+A==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.7.35': + resolution: {integrity: sha512-iDGfQO1571NqWUXtLYDhwIELA/wadH42ioGn+J9R336nWx40YICzy9UQyslWRhqzhQ5kT+QXAW/MoCWc058N6Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.7.35': + resolution: {integrity: sha512-3cUteCTbr2r5jqfgx0r091sfq5Mgh6F1SQh8XAOnSvtKzwv2bC31mvBHVAieD1uPa2kHJhLav20DQgXOhpEitw==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '*' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/plugin-styled-components@3.0.3': + resolution: {integrity: sha512-IeEaH6aFaYav0L/AyLeblhrO+e8FCS/HwIMJfxo0z2edq9JNzRiCkTI5z1q5vObSRT+T51fkiBZiyqby3D8VSQ==} + + '@swc/types@0.1.13': + resolution: {integrity: sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==} + '@tauri-apps/api@2.0.2': resolution: {integrity: sha512-3wSwmG+1kr6WrgAFKK5ijkNFPp8TT3FLj3YHUb5EwMO+3FxX4uWlfSWkeeBy+Kc1RsKzugtYLuuya+98Flj+3w==} @@ -2756,9 +2757,6 @@ packages: '@types/react-syntax-highlighter@15.5.13': resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==} - '@types/react-transition-group@4.4.11': - resolution: {integrity: sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==} - '@types/react-virtualized@9.21.30': resolution: {integrity: sha512-4l2TFLQ8BCjNDQlvH85tU6gctuZoEdgYzENQyZHpgTHU7hoLzYgPSOALMAeA58LOWua8AzC6wBivPj1lfl6JgQ==} @@ -2953,6 +2951,11 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vitejs/plugin-react-swc@3.7.1': + resolution: {integrity: sha512-vgWOY0i1EROUK0Ctg1hwhtC3SdcDjZcdit4Ups4aPkDcB1jYhmo+RMYWY87cmXMhvtD5uf8lV89j2w16vkdSVg==} + peerDependencies: + vite: ^4 || ^5 + '@vitejs/plugin-react@4.3.2': resolution: {integrity: sha512-hieu+o05v4glEBucTcKMK3dlES0OeJlD9YVOAPraVMOInBCwzumaIFiUjr4bHK7NPgnAHgiskUoceKercrN8vg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -3413,6 +3416,11 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + btoa@1.2.1: + resolution: {integrity: sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==} + engines: {node: '>= 0.4.0'} + hasBin: true + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -3598,10 +3606,6 @@ packages: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -7318,12 +7322,6 @@ packages: peerDependencies: react: '>= 0.14.0' - react-transition-group@4.4.5: - resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} - peerDependencies: - react: '>=16.6.0' - react-dom: '>=16.6.0' - react-use-error-boundary@3.0.0: resolution: {integrity: sha512-5urkfyU3ZzInEMSHe1gxtDzlQAHs0krTt0V6h8H2L5nXhDKq3OYXnCs9lGHDkEkYvLmsphw8ap5g8uYfvrkJng==} peerDependencies: @@ -7733,6 +7731,11 @@ packages: source-list-map@2.0.1: resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} + source-map-explorer@2.5.3: + resolution: {integrity: sha512-qfUGs7UHsOBE5p/lGfQdaAj/5U/GWYBw2imEpD6UQNkqElYonkow8t+HBL1qqIl3CuGZx7n8/CQo4x1HwSHhsg==} + engines: {node: '>=12'} + hasBin: true + source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -8008,6 +8011,10 @@ packages: resolution: {integrity: sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==} engines: {node: '>=6.0.0'} + temp@0.9.4: + resolution: {integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==} + engines: {node: '>=6.0.0'} + tempy@0.6.0: resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} engines: {node: '>=10'} @@ -10715,14 +10722,14 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@craco/craco@7.1.0(@types/node@22.7.5)(postcss@8.4.47)(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(type-fest@4.26.1)(typescript@5.6.3))(typescript@5.6.3)': + '@craco/craco@7.1.0(@swc/core@1.7.35)(@types/node@22.7.5)(postcss@8.4.47)(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(@swc/core@1.7.35)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3))(type-fest@4.26.1)(typescript@5.6.3))(typescript@5.6.3)': dependencies: autoprefixer: 10.4.17(postcss@8.4.47) cosmiconfig: 7.1.0 - cosmiconfig-typescript-loader: 1.0.9(@types/node@22.7.5)(cosmiconfig@7.1.0)(typescript@5.6.3) + cosmiconfig-typescript-loader: 1.0.9(@swc/core@1.7.35)(@types/node@22.7.5)(cosmiconfig@7.1.0)(typescript@5.6.3) cross-spawn: 7.0.3 lodash: 4.17.21 - react-scripts: 5.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(type-fest@4.26.1)(typescript@5.6.3) + react-scripts: 5.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(@swc/core@1.7.35)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3))(type-fest@4.26.1)(typescript@5.6.3) semver: 7.6.0 webpack-merge: 5.10.0 transitivePeerDependencies: @@ -11109,7 +11116,7 @@ snapshots: jest-util: 28.1.3 slash: 3.0.0 - '@jest/core@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))': + '@jest/core@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3))': dependencies: '@jest/console': 27.5.1 '@jest/reporters': 27.5.1 @@ -11123,7 +11130,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 27.5.1 - jest-config: 27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + jest-config: 27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) jest-haste-map: 27.5.1 jest-message-util: 27.5.1 jest-regex-util: 27.5.1 @@ -11374,83 +11381,6 @@ snapshots: dependencies: prop-types: 15.8.1 - '@mui/core-downloads-tracker@6.1.3': {} - - '@mui/material@6.1.3(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.25.7 - '@mui/core-downloads-tracker': 6.1.3 - '@mui/system': 6.1.3(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1) - '@mui/types': 7.2.18(@types/react@18.3.11) - '@mui/utils': 6.1.3(@types/react@18.3.11)(react@18.3.1) - '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.11 - clsx: 2.1.1 - csstype: 3.1.3 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-is: 18.3.1 - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - optionalDependencies: - '@emotion/react': 11.13.3(@types/react@18.3.11)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1) - '@types/react': 18.3.11 - - '@mui/private-theming@6.1.3(@types/react@18.3.11)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.25.7 - '@mui/utils': 6.1.3(@types/react@18.3.11)(react@18.3.1) - prop-types: 15.8.1 - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.11 - - '@mui/styled-engine@6.1.3(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.25.7 - '@emotion/cache': 11.13.1 - '@emotion/serialize': 1.3.2 - '@emotion/sheet': 1.4.0 - csstype: 3.1.3 - prop-types: 15.8.1 - react: 18.3.1 - optionalDependencies: - '@emotion/react': 11.13.3(@types/react@18.3.11)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1) - - '@mui/system@6.1.3(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.25.7 - '@mui/private-theming': 6.1.3(@types/react@18.3.11)(react@18.3.1) - '@mui/styled-engine': 6.1.3(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1))(react@18.3.1) - '@mui/types': 7.2.18(@types/react@18.3.11) - '@mui/utils': 6.1.3(@types/react@18.3.11)(react@18.3.1) - clsx: 2.1.1 - csstype: 3.1.3 - prop-types: 15.8.1 - react: 18.3.1 - optionalDependencies: - '@emotion/react': 11.13.3(@types/react@18.3.11)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.11)(react@18.3.1))(@types/react@18.3.11)(react@18.3.1) - '@types/react': 18.3.11 - - '@mui/types@7.2.18(@types/react@18.3.11)': - optionalDependencies: - '@types/react': 18.3.11 - - '@mui/utils@6.1.3(@types/react@18.3.11)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.25.7 - '@mui/types': 7.2.18(@types/react@18.3.11) - '@types/prop-types': 15.7.13 - clsx: 2.1.1 - prop-types: 15.8.1 - react: 18.3.1 - react-is: 18.3.1 - optionalDependencies: - '@types/react': 18.3.11 - '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -11474,7 +11404,7 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@4.26.1)(webpack-dev-server@4.15.2(webpack@5.95.0))(webpack@5.95.0)': + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@4.26.1)(webpack-dev-server@4.15.2(webpack@5.95.0(@swc/core@1.7.35)))(webpack@5.95.0(@swc/core@1.7.35))': dependencies: ansi-html: 0.0.9 core-js-pure: 3.38.1 @@ -11484,12 +11414,10 @@ snapshots: react-refresh: 0.11.0 schema-utils: 4.2.0 source-map: 0.7.4 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) optionalDependencies: type-fest: 4.26.1 - webpack-dev-server: 4.15.2(webpack@5.95.0) - - '@popperjs/core@2.11.8': {} + webpack-dev-server: 4.15.2(webpack@5.95.0(@swc/core@1.7.35)) '@react-native-community/cli-clean@14.1.0': dependencies: @@ -12139,6 +12067,62 @@ snapshots: transitivePeerDependencies: - supports-color + '@swc/core-darwin-arm64@1.7.35': + optional: true + + '@swc/core-darwin-x64@1.7.35': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.7.35': + optional: true + + '@swc/core-linux-arm64-gnu@1.7.35': + optional: true + + '@swc/core-linux-arm64-musl@1.7.35': + optional: true + + '@swc/core-linux-x64-gnu@1.7.35': + optional: true + + '@swc/core-linux-x64-musl@1.7.35': + optional: true + + '@swc/core-win32-arm64-msvc@1.7.35': + optional: true + + '@swc/core-win32-ia32-msvc@1.7.35': + optional: true + + '@swc/core-win32-x64-msvc@1.7.35': + optional: true + + '@swc/core@1.7.35': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.13 + optionalDependencies: + '@swc/core-darwin-arm64': 1.7.35 + '@swc/core-darwin-x64': 1.7.35 + '@swc/core-linux-arm-gnueabihf': 1.7.35 + '@swc/core-linux-arm64-gnu': 1.7.35 + '@swc/core-linux-arm64-musl': 1.7.35 + '@swc/core-linux-x64-gnu': 1.7.35 + '@swc/core-linux-x64-musl': 1.7.35 + '@swc/core-win32-arm64-msvc': 1.7.35 + '@swc/core-win32-ia32-msvc': 1.7.35 + '@swc/core-win32-x64-msvc': 1.7.35 + + '@swc/counter@0.1.3': {} + + '@swc/plugin-styled-components@3.0.3': + dependencies: + '@swc/counter': 0.1.3 + + '@swc/types@0.1.13': + dependencies: + '@swc/counter': 0.1.3 + '@tauri-apps/api@2.0.2': {} '@tauri-apps/cli-darwin-arm64@2.0.2': @@ -12464,10 +12448,6 @@ snapshots: dependencies: '@types/react': 18.3.11 - '@types/react-transition-group@4.4.11': - dependencies: - '@types/react': 18.3.11 - '@types/react-virtualized@9.21.30': dependencies: '@types/prop-types': 15.7.11 @@ -12723,6 +12703,13 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@vitejs/plugin-react-swc@3.7.1(vite@5.4.8(@types/node@22.7.5)(terser@5.34.1))': + dependencies: + '@swc/core': 1.7.35 + vite: 5.4.8(@types/node@22.7.5)(terser@5.34.1) + transitivePeerDependencies: + - '@swc/helpers' + '@vitejs/plugin-react@4.3.2(vite@5.4.8(@types/node@22.7.5)(terser@5.34.1))': dependencies: '@babel/core': 7.25.2 @@ -13098,14 +13085,14 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@8.4.1(@babel/core@7.25.7)(webpack@5.95.0): + babel-loader@8.4.1(@babel/core@7.25.7)(webpack@5.95.0(@swc/core@1.7.35)): dependencies: '@babel/core': 7.25.7 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) babel-plugin-istanbul@6.1.1: dependencies: @@ -13334,6 +13321,8 @@ snapshots: dependencies: node-int64: 0.4.0 + btoa@1.2.1: {} + buffer-from@1.1.2: {} buffer@5.7.1: @@ -13518,8 +13507,6 @@ snapshots: clsx@1.2.1: {} - clsx@2.1.1: {} - co@4.6.0: {} coa@2.0.2: @@ -13631,11 +13618,11 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@1.0.9(@types/node@22.7.5)(cosmiconfig@7.1.0)(typescript@5.6.3): + cosmiconfig-typescript-loader@1.0.9(@swc/core@1.7.35)(@types/node@22.7.5)(cosmiconfig@7.1.0)(typescript@5.6.3): dependencies: '@types/node': 22.7.5 cosmiconfig: 7.1.0 - ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.6.3) + ts-node: 10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3) typescript: 5.6.3 transitivePeerDependencies: - '@swc/core' @@ -13714,7 +13701,7 @@ snapshots: postcss: 8.4.47 postcss-selector-parser: 6.1.2 - css-loader@6.11.0(webpack@5.95.0): + css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.35)): dependencies: icss-utils: 5.1.0(postcss@8.4.47) postcss: 8.4.47 @@ -13725,9 +13712,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) - css-minimizer-webpack-plugin@3.4.1(webpack@5.95.0): + css-minimizer-webpack-plugin@3.4.1(webpack@5.95.0(@swc/core@1.7.35)): dependencies: cssnano: 5.1.15(postcss@8.4.47) jest-worker: 27.5.1 @@ -13735,7 +13722,7 @@ snapshots: schema-utils: 4.2.0 serialize-javascript: 6.0.2 source-map: 0.6.1 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) css-prefers-color-scheme@6.0.3(postcss@8.4.47): dependencies: @@ -14369,7 +14356,7 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)))(typescript@5.6.3): + eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)))(typescript@5.6.3): dependencies: '@babel/core': 7.25.7 '@babel/eslint-parser': 7.25.7(@babel/core@7.25.7)(eslint@8.57.1) @@ -14381,7 +14368,7 @@ snapshots: eslint: 8.57.1 eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)))(typescript@5.6.3) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)))(typescript@5.6.3) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) eslint-plugin-react: 7.37.1(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -14451,13 +14438,13 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)))(typescript@5.6.3): + eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)))(typescript@5.6.3): dependencies: '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@5.6.3) eslint: 8.57.1 optionalDependencies: '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) - jest: 27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + jest: 27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) transitivePeerDependencies: - supports-color - typescript @@ -14534,7 +14521,7 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.95.0): + eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.95.0(@swc/core@1.7.35)): dependencies: '@types/eslint': 8.56.12 eslint: 8.57.1 @@ -14542,7 +14529,7 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 schema-utils: 4.2.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) eslint@8.57.1: dependencies: @@ -14734,11 +14721,11 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.95.0): + file-loader@6.2.0(webpack@5.95.0(@swc/core@1.7.35)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) filelist@1.0.4: dependencies: @@ -14827,7 +14814,7 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.6.3)(webpack@5.95.0): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.6.3)(webpack@5.95.0(@swc/core@1.7.35)): dependencies: '@babel/code-frame': 7.25.7 '@types/json-schema': 7.0.15 @@ -14843,7 +14830,7 @@ snapshots: semver: 7.6.3 tapable: 1.1.3 typescript: 5.6.3 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) optionalDependencies: eslint: 8.57.1 @@ -15111,7 +15098,7 @@ snapshots: html-url-attributes@3.0.0: {} - html-webpack-plugin@5.6.0(webpack@5.95.0): + html-webpack-plugin@5.6.0(webpack@5.95.0(@swc/core@1.7.35)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -15119,7 +15106,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) htmlparser2@6.1.0: dependencies: @@ -15535,16 +15522,16 @@ snapshots: transitivePeerDependencies: - supports-color - jest-cli@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)): + jest-cli@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)): dependencies: - '@jest/core': 27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + '@jest/core': 27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 import-local: 3.2.0 - jest-config: 27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + jest-config: 27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) jest-util: 27.5.1 jest-validate: 27.5.1 prompts: 2.4.2 @@ -15556,7 +15543,7 @@ snapshots: - ts-node - utf-8-validate - jest-config@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)): + jest-config@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)): dependencies: '@babel/core': 7.25.7 '@jest/test-sequencer': 27.5.1 @@ -15583,7 +15570,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.6.3) + ts-node: 10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3) transitivePeerDependencies: - bufferutil - canvas @@ -15920,11 +15907,11 @@ snapshots: leven: 3.1.0 pretty-format: 29.7.0 - jest-watch-typeahead@1.1.0(jest@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))): + jest-watch-typeahead@1.1.0(jest@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3))): dependencies: ansi-escapes: 4.3.2 chalk: 4.1.2 - jest: 27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + jest: 27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) jest-regex-util: 28.0.2 jest-watcher: 28.1.3 slash: 4.0.0 @@ -15977,11 +15964,11 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)): + jest@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)): dependencies: - '@jest/core': 27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + '@jest/core': 27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) import-local: 3.2.0 - jest-cli: 27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + jest-cli: 27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) transitivePeerDependencies: - bufferutil - canvas @@ -16855,11 +16842,11 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.1(webpack@5.95.0): + mini-css-extract-plugin@2.9.1(webpack@5.95.0(@swc/core@1.7.35)): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) minimalistic-assert@1.0.1: {} @@ -17381,21 +17368,21 @@ snapshots: postcss: 8.4.47 postcss-value-parser: 4.2.0 - postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)): + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)): dependencies: lilconfig: 3.1.2 yaml: 2.5.1 optionalDependencies: postcss: 8.4.47 - ts-node: 10.9.2(@types/node@22.7.5)(typescript@5.6.3) + ts-node: 10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3) - postcss-loader@6.2.1(postcss@8.4.47)(webpack@5.95.0): + postcss-loader@6.2.1(postcss@8.4.47)(webpack@5.95.0(@swc/core@1.7.35)): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 postcss: 8.4.47 semver: 7.6.3 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) postcss-logical@5.0.4(postcss@8.4.47): dependencies: @@ -17799,7 +17786,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.6.3)(webpack@5.95.0): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.6.3)(webpack@5.95.0(@swc/core@1.7.35)): dependencies: '@babel/code-frame': 7.25.7 address: 1.2.2 @@ -17810,7 +17797,7 @@ snapshots: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.6.3)(webpack@5.95.0) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.6.3)(webpack@5.95.0(@swc/core@1.7.35)) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -17825,7 +17812,7 @@ snapshots: shell-quote: 1.8.1 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: @@ -18006,56 +17993,56 @@ snapshots: '@remix-run/router': 1.19.2 react: 18.3.1 - react-scripts@5.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))(type-fest@4.26.1)(typescript@5.6.3): + react-scripts@5.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(@swc/core@1.7.35)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3))(type-fest@4.26.1)(typescript@5.6.3): dependencies: '@babel/core': 7.25.7 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@4.26.1)(webpack-dev-server@4.15.2(webpack@5.95.0))(webpack@5.95.0) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@4.26.1)(webpack-dev-server@4.15.2(webpack@5.95.0(@swc/core@1.7.35)))(webpack@5.95.0(@swc/core@1.7.35)) '@svgr/webpack': 5.5.0 babel-jest: 27.5.1(@babel/core@7.25.7) - babel-loader: 8.4.1(@babel/core@7.25.7)(webpack@5.95.0) + babel-loader: 8.4.1(@babel/core@7.25.7)(webpack@5.95.0(@swc/core@1.7.35)) babel-plugin-named-asset-import: 0.3.8(@babel/core@7.25.7) babel-preset-react-app: 10.0.1 bfj: 7.1.0 browserslist: 4.24.0 camelcase: 6.3.0 case-sensitive-paths-webpack-plugin: 2.4.0 - css-loader: 6.11.0(webpack@5.95.0) - css-minimizer-webpack-plugin: 3.4.1(webpack@5.95.0) + css-loader: 6.11.0(webpack@5.95.0(@swc/core@1.7.35)) + css-minimizer-webpack-plugin: 3.4.1(webpack@5.95.0(@swc/core@1.7.35)) dotenv: 10.0.0 dotenv-expand: 5.1.0 eslint: 8.57.1 - eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)))(typescript@5.6.3) - eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.95.0) - file-loader: 6.2.0(webpack@5.95.0) + eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.25.7(@babel/core@7.23.9))(@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.23.9))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)))(typescript@5.6.3) + eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.95.0(@swc/core@1.7.35)) + file-loader: 6.2.0(webpack@5.95.0(@swc/core@1.7.35)) fs-extra: 10.1.0 - html-webpack-plugin: 5.6.0(webpack@5.95.0) + html-webpack-plugin: 5.6.0(webpack@5.95.0(@swc/core@1.7.35)) identity-obj-proxy: 3.0.0 - jest: 27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + jest: 27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) jest-resolve: 27.5.1 - jest-watch-typeahead: 1.1.0(jest@27.5.1(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3))) - mini-css-extract-plugin: 2.9.1(webpack@5.95.0) + jest-watch-typeahead: 1.1.0(jest@27.5.1(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3))) + mini-css-extract-plugin: 2.9.1(webpack@5.95.0(@swc/core@1.7.35)) postcss: 8.4.47 postcss-flexbugs-fixes: 5.0.2(postcss@8.4.47) - postcss-loader: 6.2.1(postcss@8.4.47)(webpack@5.95.0) + postcss-loader: 6.2.1(postcss@8.4.47)(webpack@5.95.0(@swc/core@1.7.35)) postcss-normalize: 10.0.1(browserslist@4.24.0)(postcss@8.4.47) postcss-preset-env: 7.8.3(postcss@8.4.47) prompts: 2.4.2 react: 18.3.1 react-app-polyfill: 3.0.0 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.3)(webpack@5.95.0) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.6.3)(webpack@5.95.0(@swc/core@1.7.35)) react-refresh: 0.11.0 resolve: 1.22.8 resolve-url-loader: 4.0.0 - sass-loader: 12.6.0(webpack@5.95.0) + sass-loader: 12.6.0(webpack@5.95.0(@swc/core@1.7.35)) semver: 7.6.3 - source-map-loader: 3.0.2(webpack@5.95.0) - style-loader: 3.3.4(webpack@5.95.0) - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) - terser-webpack-plugin: 5.3.10(webpack@5.95.0) - webpack: 5.95.0 - webpack-dev-server: 4.15.2(webpack@5.95.0) - webpack-manifest-plugin: 4.1.1(webpack@5.95.0) - workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.95.0) + source-map-loader: 3.0.2(webpack@5.95.0(@swc/core@1.7.35)) + style-loader: 3.3.4(webpack@5.95.0(@swc/core@1.7.35)) + tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.35)(webpack@5.95.0(@swc/core@1.7.35)) + webpack: 5.95.0(@swc/core@1.7.35) + webpack-dev-server: 4.15.2(webpack@5.95.0(@swc/core@1.7.35)) + webpack-manifest-plugin: 4.1.1(webpack@5.95.0(@swc/core@1.7.35)) + workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.95.0(@swc/core@1.7.35)) optionalDependencies: fsevents: 2.3.3 typescript: 5.6.3 @@ -18139,15 +18126,6 @@ snapshots: react: 18.3.1 refractor: 3.6.0 - react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.25.7 - dom-helpers: 5.2.1 - loose-envify: 1.4.0 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-use-error-boundary@3.0.0(react@18.3.1): dependencies: react: 18.3.1 @@ -18446,11 +18424,11 @@ snapshots: sanitize.css@13.0.0: {} - sass-loader@12.6.0(webpack@5.95.0): + sass-loader@12.6.0(webpack@5.95.0(@swc/core@1.7.35)): dependencies: klona: 2.0.6 neo-async: 2.6.2 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) sax@1.2.4: {} @@ -18633,16 +18611,31 @@ snapshots: source-list-map@2.0.1: {} + source-map-explorer@2.5.3: + dependencies: + btoa: 1.2.1 + chalk: 4.1.2 + convert-source-map: 1.9.0 + ejs: 3.1.10 + escape-html: 1.0.3 + glob: 7.2.3 + gzip-size: 6.0.0 + lodash: 4.17.21 + open: 7.4.2 + source-map: 0.7.4 + temp: 0.9.4 + yargs: 16.2.0 + source-map-js@1.0.2: {} source-map-js@1.2.1: {} - source-map-loader@3.0.2(webpack@5.95.0): + source-map-loader@3.0.2(webpack@5.95.0(@swc/core@1.7.35)): dependencies: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) source-map-support@0.5.21: dependencies: @@ -18827,9 +18820,9 @@ snapshots: strnum@1.0.5: {} - style-loader@3.3.4(webpack@5.95.0): + style-loader@3.3.4(webpack@5.95.0(@swc/core@1.7.35)): dependencies: - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) style-to-object@1.0.5: dependencies: @@ -18928,7 +18921,7 @@ snapshots: tabbable@6.2.0: {} - tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)): + tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -18947,7 +18940,7 @@ snapshots: postcss: 8.4.47 postcss-import: 15.1.0(postcss@8.4.47) postcss-js: 4.0.1(postcss@8.4.47) - postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3)) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3)) postcss-nested: 6.2.0(postcss@8.4.47) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -18965,6 +18958,11 @@ snapshots: dependencies: rimraf: 2.6.3 + temp@0.9.4: + dependencies: + mkdirp: 0.5.6 + rimraf: 2.6.3 + tempy@0.6.0: dependencies: is-stream: 2.0.1 @@ -18977,14 +18975,16 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 - terser-webpack-plugin@5.3.10(webpack@5.95.0): + terser-webpack-plugin@5.3.10(@swc/core@1.7.35)(webpack@5.95.0(@swc/core@1.7.35)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.1 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) + optionalDependencies: + '@swc/core': 1.7.35 terser@5.28.1: dependencies: @@ -19074,7 +19074,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@22.7.5)(typescript@5.6.3): + ts-node@10.9.2(@swc/core@1.7.35)(@types/node@22.7.5)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 @@ -19091,6 +19091,8 @@ snapshots: typescript: 5.6.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.7.35 tsconfig-paths@3.15.0: dependencies: @@ -19425,16 +19427,16 @@ snapshots: webidl-conversions@6.1.0: {} - webpack-dev-middleware@5.3.4(webpack@5.95.0): + webpack-dev-middleware@5.3.4(webpack@5.95.0(@swc/core@1.7.35)): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) - webpack-dev-server@4.15.2(webpack@5.95.0): + webpack-dev-server@4.15.2(webpack@5.95.0(@swc/core@1.7.35)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -19464,20 +19466,20 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.95.0) + webpack-dev-middleware: 5.3.4(webpack@5.95.0(@swc/core@1.7.35)) ws: 8.18.0 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-manifest-plugin@4.1.1(webpack@5.95.0): + webpack-manifest-plugin@4.1.1(webpack@5.95.0(@swc/core@1.7.35)): dependencies: tapable: 2.2.1 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) webpack-sources: 2.3.1 webpack-merge@5.10.0: @@ -19498,7 +19500,7 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.95.0: + webpack@5.95.0(@swc/core@1.7.35): dependencies: '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 @@ -19520,7 +19522,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.95.0) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.35)(webpack@5.95.0(@swc/core@1.7.35)) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -19721,12 +19723,12 @@ snapshots: workbox-sw@6.6.0: {} - workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.95.0): + workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.95.0(@swc/core@1.7.35)): dependencies: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.35) webpack-sources: 1.4.3 workbox-build: 6.6.0(@types/babel__core@7.20.5) transitivePeerDependencies: diff --git a/src/App.tsx b/src/App.tsx index 056c65e..7f1e4bc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,27 +1,26 @@ -import { observer } from "mobx-react-lite"; -import React from "react"; -import { Route, Routes, useNavigate } from "react-router-dom"; -import { AuthenticationGuard } from "./components/guards/AuthenticationGuard"; -import LoginPage from "./pages/LoginPage"; -import NotFoundPage from "./pages/NotFound"; -import RegistrationPage from "./pages/RegistrationPage"; - +import { bannerController } from "@/controllers/banners"; import { getTauriVersion, getVersion } from "@tauri-apps/api/app"; import { arch, locale, platform, version } from "@tauri-apps/plugin-os"; import { useNetworkState } from "@uidotdev/usehooks"; import { reaction } from "mobx"; +import { observer } from "mobx-react-lite"; +import React from "react"; +import { Route, Routes, useNavigate } from "react-router-dom"; import ErrorBoundary from "./components/ErrorBoundary"; import Loader from "./components/Loader"; -import { UnauthenticatedGuard } from "./components/guards/UnauthenticatedGuard"; import useLogger from "./hooks/useLogger"; import AppPage from "./pages/AppPage"; +import LoginPage from "./pages/LoginPage"; import LogoutPage from "./pages/LogoutPage"; +import NotFoundPage from "./pages/NotFound"; +import RegistrationPage from "./pages/RegistrationPage"; import ChannelPage from "./pages/subpages/ChannelPage"; import { Globals } from "./utils/Globals"; // @ts-expect-error no types import FPSStats from "react-fps-stats"; -import { bannerController } from "./controllers/banners"; +import AuthenticationGuard from "./components/AuthenticationGuard"; import { useAppStore } from "./hooks/useAppStore"; +import InvitePage from "./pages/InvitePage"; import { isTauri } from "./utils/Utils"; function App() { @@ -69,7 +68,7 @@ function App() { }; }; - isTauri && loadAsyncGlobals(); + if (isTauri) loadAsyncGlobals(); Globals.load(); app.loadSettings(); @@ -104,9 +103,16 @@ function App() { path="/channels/:guildId/:channelId?" element={} /> - } /> - } /> + } + /> + } + /> } /> + } /> } /> diff --git a/src/components/AuthComponents.tsx b/src/components/AuthComponents.tsx index 38cee90..ecd5f06 100644 --- a/src/components/AuthComponents.tsx +++ b/src/components/AuthComponents.tsx @@ -1,6 +1,6 @@ +import Container from "@components/Container"; import styled from "styled-components"; import Button from "./Button"; -import Container from "./Container"; export const Wrapper = styled(Container)` display: flex; diff --git a/src/components/AuthenticationGuard.tsx b/src/components/AuthenticationGuard.tsx new file mode 100644 index 0000000..d9d3a4d --- /dev/null +++ b/src/components/AuthenticationGuard.tsx @@ -0,0 +1,29 @@ +import { useAppStore } from "@hooks/useAppStore"; +import { LoadingSuspense } from "@pages/LoadingPage"; +import { Navigate } from "react-router-dom"; + +interface Props { + component: React.FC; + requireUnauthenticated?: boolean; +} + +export default function AuthenticationGuard({ component, requireUnauthenticated }: Props) { + const app = useAppStore(); + + // if we need the user to be logged in, and there isn't a token, go to login page + if (!requireUnauthenticated && !app.token) { + return ; + } + + // if we need the user to be logged out to access the page, but there is a token, go to the app page + if (requireUnauthenticated && app.token) { + return ; + } + + const Component = component; + return ( + + + + ); +} diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 0a22f9f..00bd5c9 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -1,12 +1,11 @@ +import Container from "@components/Container"; +import { useAppStore } from "@hooks/useAppStore"; import { PresenceUpdateStatus } from "@spacebarchat/spacebar-api-types/v9"; +import { AccountStore } from "@stores"; +import { Presence, User } from "@structures"; import { observer } from "mobx-react-lite"; import React, { useRef } from "react"; import styled from "styled-components"; -import { useAppStore } from "../hooks/useAppStore"; -import AccountStore from "../stores/AccountStore"; -import Presence from "../stores/objects/Presence"; -import User from "../stores/objects/User"; -import Container from "./Container"; const Wrapper = styled(Container)<{ size: number; hasClick?: boolean }>` background-color: transparent; diff --git a/src/components/ChannelHeader.tsx b/src/components/ChannelHeader.tsx index b6bf3b5..8361eed 100644 --- a/src/components/ChannelHeader.tsx +++ b/src/components/ChannelHeader.tsx @@ -1,11 +1,10 @@ +import { Floating, FloatingTrigger } from "@components/floating"; +import { useAppStore } from "@hooks/useAppStore"; import { observer } from "mobx-react-lite"; import React, { useEffect } from "react"; import styled from "styled-components"; -import { useAppStore } from "../hooks/useAppStore"; import Icon, { IconProps } from "./Icon"; import { SectionHeader } from "./SectionHeader"; -import Floating from "./floating/Floating"; -import FloatingTrigger from "./floating/FloatingTrigger"; const Wrapper = styled(SectionHeader)` background-color: var(--background-secondary); diff --git a/src/components/ChannelList/ChannelList.tsx b/src/components/ChannelList/ChannelList.tsx index fec3077..6d65e78 100644 --- a/src/components/ChannelList/ChannelList.tsx +++ b/src/components/ChannelList/ChannelList.tsx @@ -1,8 +1,8 @@ +import { useAppStore } from "@hooks/useAppStore"; import { ChannelType } from "@spacebarchat/spacebar-api-types/v9"; import { observer } from "mobx-react-lite"; import { AutoSizer, List, ListRowProps } from "react-virtualized"; import styled from "styled-components"; -import { useAppStore } from "../../hooks/useAppStore"; import ChannelListItem from "./ChannelListItem"; const Container = styled.div` diff --git a/src/components/ChannelList/ChannelListItem.tsx b/src/components/ChannelList/ChannelListItem.tsx index 5a18378..5f51c20 100644 --- a/src/components/ChannelList/ChannelListItem.tsx +++ b/src/components/ChannelList/ChannelListItem.tsx @@ -1,16 +1,15 @@ +import { modalController } from "@/controllers/modals"; +import { Floating, FloatingTrigger } from "@components/floating"; +import Icon from "@components/Icon"; +import SidebarPill from "@components/SidebarPill"; +import { ContextMenuContext } from "@contexts/ContextMenuContext"; +import { useAppStore } from "@hooks/useAppStore"; +import { Channel } from "@structures"; +import { Permissions } from "@utils"; import { observer } from "mobx-react-lite"; import React, { useContext, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import styled from "styled-components"; -import { ContextMenuContext } from "../../contexts/ContextMenuContext"; -import { modalController } from "../../controllers/modals"; -import { useAppStore } from "../../hooks/useAppStore"; -import Channel from "../../stores/objects/Channel"; -import { Permissions } from "../../utils/Permissions"; -import Icon from "../Icon"; -import SidebarPill from "../SidebarPill"; -import Floating from "../floating/Floating"; -import FloatingTrigger from "../floating/FloatingTrigger"; const ListItem = styled.div<{ isCategory?: boolean }>` padding: ${(props) => (props.isCategory ? "16px 8px 0 0" : "1px 8px 0 0")}; diff --git a/src/components/ChannelSidebar.tsx b/src/components/ChannelSidebar.tsx index 23eefbe..7ea046a 100644 --- a/src/components/ChannelSidebar.tsx +++ b/src/components/ChannelSidebar.tsx @@ -1,12 +1,12 @@ +import Container from "@components/Container"; import { useWindowSize } from "@uidotdev/usehooks"; +import { isTouchscreenDevice } from "@utils"; import { observer } from "mobx-react-lite"; import { useEffect, useState } from "react"; import { isDesktop } from "react-device-detect"; import styled from "styled-components"; -import { isTouchscreenDevice } from "../utils/isTouchscreenDevice"; import ChannelHeader from "./ChannelHeader"; import ChannelList from "./ChannelList/ChannelList"; -import Container from "./Container"; import UserPanel from "./UserPanel"; const Wrapper = styled(Container)` diff --git a/src/components/GuildItem.tsx b/src/components/GuildItem.tsx index 7b2e21f..2d981c3 100644 --- a/src/components/GuildItem.tsx +++ b/src/components/GuildItem.tsx @@ -1,18 +1,16 @@ +import Container from "@components/Container"; +import { Floating, FloatingTrigger } from "@components/floating"; +import { ContextMenuContext } from "@contexts/ContextMenuContext"; +import { useAppStore } from "@hooks/useAppStore"; +import useLogger from "@hooks/useLogger"; import { CDNRoutes, ChannelType, ImageFormat } from "@spacebarchat/spacebar-api-types/v9"; +import { Guild } from "@structures"; +import { Permissions, REST } from "@utils"; import { observer } from "mobx-react-lite"; import React, { useContext } from "react"; import { useNavigate } from "react-router-dom"; import styled from "styled-components"; -import { ContextMenuContext } from "../contexts/ContextMenuContext"; -import { useAppStore } from "../hooks/useAppStore"; -import useLogger from "../hooks/useLogger"; -import Guild from "../stores/objects/Guild"; -import { Permissions } from "../utils/Permissions"; -import REST from "../utils/REST"; -import Container from "./Container"; import SidebarPill, { PillType } from "./SidebarPill"; -import Floating from "./floating/Floating"; -import FloatingTrigger from "./floating/FloatingTrigger"; export const GuildSidebarListItem = styled.div` position: relative; diff --git a/src/components/GuildSidebar.tsx b/src/components/GuildSidebar.tsx index e82bffd..d2ebba1 100644 --- a/src/components/GuildSidebar.tsx +++ b/src/components/GuildSidebar.tsx @@ -1,10 +1,10 @@ +import { modalController } from "@/controllers/modals"; +import { useAppStore } from "@hooks/useAppStore"; import { observer } from "mobx-react-lite"; import React from "react"; import { useNavigate } from "react-router-dom"; import { AutoSizer, List, ListRowProps } from "react-virtualized"; import styled from "styled-components"; -import { modalController } from "../controllers/modals"; -import { useAppStore } from "../hooks/useAppStore"; import GuildItem, { GuildSidebarListItem } from "./GuildItem"; import SidebarAction from "./SidebarAction"; diff --git a/src/components/InviteEmbed.tsx b/src/components/InviteEmbed.tsx new file mode 100644 index 0000000..8479493 --- /dev/null +++ b/src/components/InviteEmbed.tsx @@ -0,0 +1,271 @@ +import Container from "@components/Container"; +import { useAppStore } from "@hooks/useAppStore"; +import useLogger from "@hooks/useLogger"; +import { APIInvite, CDNRoutes, ImageFormat, Routes } from "@spacebarchat/spacebar-api-types/v9"; +import { asAcronym, REST } from "@utils"; +import { useEffect, useState } from "react"; +import styled from "styled-components"; +import Button from "./Button"; + +const MainContainer = styled(Container)` + background-color: var(--background-secondary); + border-radius: 8px; + max-width: 430px; + min-width: 160px; + padding: 16px; + display: flex; + flex-direction: column; + justify-self: start; + align-self: start; + width: 100%; +`; + +const Wrapper = styled.div``; + +const Header = styled.h3` + margin: 0 0 12px 0; + font-size: 16px; + font-weight: var(--font-weight-medium); + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + color: var(--text-secondary); +`; + +const SplashWrapper = styled.div` + border-radius: 8px 8px 0 0; + height: 64px; + margin: -16px -16px 16px -16px; + overflow: hidden; +`; + +const Splash = styled.img` + object-fit: cover; + width: 100%; + height: 100%; +`; + +const ContentWrapper = styled.div` + display: flex; + flex-flow: row wrap; + gap: 16px; +`; + +const GuildHeader = styled.div` + display: flex; + flex: 1000 0 auto; + align-items: center; + max-width: 100%; + gap: 16px; +`; + +const GuildInfo = styled.div` + display: flex; + flex: 1; + min-width: 1px; + flex-direction: column; + justify-content: center; + align-items: stretch; + flex-wrap: nowrap; +`; + +const GuildName = styled.h3` + margin: 0 0 2px 0; + font-size: 16px; + font-weight: var(--font-weight-medium); + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + color: var(--text-header); +`; + +const GuildDetailsWrapper = styled.div` + display: flex; + flex-flow: row wrap; + align-items: center; + column-gap: 12px; +`; + +const StatusWrapper = styled.div` + display: flex; + flex: 0 1 auto; + align-items: center; + flex-flow: nowrap; + min-width: 0; +`; + +const OnlineStatus = styled.div` + background-color: var(--success); + border-radius: 50%; + height: 8px; + width: 8px; + margin-right: 4px; + flex: 0 0 auto; +`; + +const OfflineStatus = styled.div` + background-color: var(--status-offline); + border-radius: 50%; + height: 8px; + width: 8px; + margin-right: 4px; + flex: 0 0 auto; +`; + +const StatusCount = styled.span` + margin-right: 0; + flex: 0 1 auto; + color: var(--text-header-secondary); + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + font-size: 14px; +`; + +const InvalidInviteHeader = styled(GuildName)` + color: var(--error); +`; + +const InvalidInviteDetails = styled.span` + font-size: 14px; + color: var(--text-header-secondary); + font-weight: var(--font-weight-regular); +`; + +const JoinButton = styled(Button)` + height: 40px; + align-self: center; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + flex: 1 0 auto; + width: auto; +`; + +interface Props { + isSelf: boolean; + code: string; +} + +function InviteEmbed({ isSelf, code }: Props) { + const app = useAppStore(); + const logger = useLogger("InviteEmbed"); + const [data, setData] = useState(); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + + useEffect(() => { + app.rest + .get(Routes.invite(code), { + wuth_counts: true, + with_expiration: true, + }) + .then((r) => { + setData(r); + setLoading(false); + logger.debug(`Resolved invite: `, r); + }) + .catch((e) => { + logger.error(`Error fetching invite: `, e); + setError(true); + setLoading(false); + }); + }, []); + + return ( + + {loading && ( + +
Resolving Invite
+
+ )} + + {error && ( + +
{isSelf ? "You sent an invite, but..." : "You received an invite, but..."}
+ + +
+ + Invalid Invite + Try sending a new invite! + + + + + )} + + {data && ( + + {data.guild!.splash && ( + + + + )} +
+ {isSelf ? "You sent an invite to join a guild" : "You've been invited to join a guild"} +
+ + +
+ + {data.guild!.name} + + + + + {/* @ts-expect-error the server is incorrect here */} + {(data.guild!.presence_count || 0).toLocaleString()} Online + + + + + + {/* @ts-expect-error the server is incorrect here */} + {(data.guild!.member_count || 0).toLocaleString()} Members + + + + + + Join + + + )} + + ); +} + +export default InviteEmbed; diff --git a/src/components/Loader.tsx b/src/components/Loader.tsx index e4cbc66..3de568f 100644 --- a/src/components/Loader.tsx +++ b/src/components/Loader.tsx @@ -1,9 +1,9 @@ +import { useAppStore } from "@hooks/useAppStore"; +import LoadingPage from "@pages/LoadingPage"; import { invoke } from "@tauri-apps/api/core"; +import { isTauri } from "@utils"; import { observer } from "mobx-react-lite"; import React from "react"; -import { useAppStore } from "../hooks/useAppStore"; -import LoadingPage from "../pages/LoadingPage"; -import { isTauri } from "../utils/Utils"; interface Props { children: React.ReactNode; diff --git a/src/components/MemberList/MemberList.tsx b/src/components/MemberList/MemberList.tsx index 0246c25..de7550f 100644 --- a/src/components/MemberList/MemberList.tsx +++ b/src/components/MemberList/MemberList.tsx @@ -1,10 +1,10 @@ +import ListSection from "@components/ListSection"; +import { useAppStore } from "@hooks/useAppStore"; +import { GuildMemberListStore } from "@stores"; import { autorun } from "mobx"; import { observer } from "mobx-react-lite"; import React from "react"; import styled from "styled-components"; -import { useAppStore } from "../../hooks/useAppStore"; -import GuildMemberListStore from "../../stores/GuildMemberListStore"; -import ListSection from "../ListSection"; import MemberListItem from "./MemberListItem"; const Container = styled.div` diff --git a/src/components/MemberList/MemberListItem.tsx b/src/components/MemberList/MemberListItem.tsx index dca1ce0..8fc89c5 100644 --- a/src/components/MemberList/MemberListItem.tsx +++ b/src/components/MemberList/MemberListItem.tsx @@ -1,13 +1,12 @@ +import Avatar from "@components/Avatar"; +import { Floating, FloatingTrigger } from "@components/floating"; +import { ContextMenuContext } from "@contexts/ContextMenuContext"; +import { useAppStore } from "@hooks/useAppStore"; import { PresenceUpdateStatus } from "@spacebarchat/spacebar-api-types/v9"; +import { GuildMember } from "@structures"; import { observer } from "mobx-react-lite"; import { useContext } from "react"; import styled from "styled-components"; -import { ContextMenuContext } from "../../contexts/ContextMenuContext"; -import { useAppStore } from "../../hooks/useAppStore"; -import GuildMember from "../../stores/objects/GuildMember"; -import Avatar from "../Avatar"; -import Floating from "../floating/Floating"; -import FloatingTrigger from "../floating/FloatingTrigger"; const ListItem = styled(FloatingTrigger)<{ isCategory?: boolean }>` padding: ${(props) => (props.isCategory ? "16px 8px 0 0" : "1px 8px 0 0")}; diff --git a/src/components/SectionTitle.tsx b/src/components/SectionTitle.tsx index 6026bac..0ac5897 100644 --- a/src/components/SectionTitle.tsx +++ b/src/components/SectionTitle.tsx @@ -13,6 +13,7 @@ const Text = styled.h2` flex: 1; `; +// eslint-disable-next-line @typescript-eslint/no-empty-object-type interface Props {} function SectionTitle({ children }: React.PropsWithChildren) { diff --git a/src/components/SidebarAction.tsx b/src/components/SidebarAction.tsx index 95d084f..919e515 100644 --- a/src/components/SidebarAction.tsx +++ b/src/components/SidebarAction.tsx @@ -1,11 +1,10 @@ +import Container from "@components/Container"; +import { Floating, FloatingTrigger } from "@components/floating"; +import { GuildSidebarListItem } from "@components/GuildItem"; +import Icon, { IconProps } from "@components/Icon"; +import SidebarPill, { PillType } from "@components/SidebarPill"; import React from "react"; import styled from "styled-components"; -import Container from "./Container"; -import { GuildSidebarListItem } from "./GuildItem"; -import Icon, { IconProps } from "./Icon"; -import SidebarPill, { PillType } from "./SidebarPill"; -import Floating from "./floating/Floating"; -import FloatingTrigger from "./floating/FloatingTrigger"; const Wrapper = styled(Container)<{ margin?: boolean; diff --git a/src/components/SidebarPill.tsx b/src/components/SidebarPill.tsx index 01fa623..3b32b70 100644 --- a/src/components/SidebarPill.tsx +++ b/src/components/SidebarPill.tsx @@ -1,5 +1,5 @@ +import Container from "@components/Container"; import styled from "styled-components"; -import Container from "./Container"; export type PillType = "none" | "unread" | "hover" | "active"; diff --git a/src/components/Tooltip.tsx b/src/components/Tooltip.tsx index 400279d..c865de4 100644 --- a/src/components/Tooltip.tsx +++ b/src/components/Tooltip.tsx @@ -1,5 +1,5 @@ +import { FloatingProps } from "@components/floating"; import styled from "styled-components"; -import { FloatingProps } from "./floating/Floating"; const Container = styled.div` background-color: var(--background-tertiary); diff --git a/src/components/UserPanel.tsx b/src/components/UserPanel.tsx index d7954d2..3a08dcb 100644 --- a/src/components/UserPanel.tsx +++ b/src/components/UserPanel.tsx @@ -1,12 +1,11 @@ +import { modalController } from "@/controllers/modals"; +import { Floating, FloatingTrigger } from "@components/floating"; +import { useAppStore } from "@hooks/useAppStore"; import { observer } from "mobx-react-lite"; import styled from "styled-components"; -import { modalController } from "../controllers/modals"; -import { useAppStore } from "../hooks/useAppStore"; import Avatar from "./Avatar"; import Icon from "./Icon"; import IconButton from "./IconButton"; -import Floating from "./floating/Floating"; -import FloatingTrigger from "./floating/FloatingTrigger"; const Section = styled.section` flex: 0 0 auto; diff --git a/src/components/banners/OfflineBanner.tsx b/src/components/banners/OfflineBanner.tsx index f6927f4..efec117 100644 --- a/src/components/banners/OfflineBanner.tsx +++ b/src/components/banners/OfflineBanner.tsx @@ -1,5 +1,5 @@ +import Icon from "@components/Icon"; import styled from "styled-components"; -import Icon from "../Icon"; const Wrapper = styled.div` display: flex; diff --git a/src/components/banners/index.ts b/src/components/banners/index.ts new file mode 100644 index 0000000..852e51f --- /dev/null +++ b/src/components/banners/index.ts @@ -0,0 +1 @@ +export { default as OfflineBanner } from "./OfflineBanner"; diff --git a/src/components/contextMenus/ChannelContextMenu.tsx b/src/components/contextMenus/ChannelContextMenu.tsx index 1e95650..7b359c0 100644 --- a/src/components/contextMenus/ChannelContextMenu.tsx +++ b/src/components/contextMenus/ChannelContextMenu.tsx @@ -1,7 +1,7 @@ // loosely based on https://github.com/revoltchat/frontend/blob/master/components/app/menus/UserContextMenu.tsx -import { modalController } from "../../controllers/modals"; -import Channel from "../../stores/objects/Channel"; +import { modalController } from "@/controllers/modals"; +import Channel from "@structures/Channel"; import { ContextMenu, ContextMenuButton, ContextMenuDivider } from "./ContextMenu"; interface MenuProps { diff --git a/src/components/contextMenus/ChannelMentionContextMenu.tsx b/src/components/contextMenus/ChannelMentionContextMenu.tsx index dcbe99d..bfb834b 100644 --- a/src/components/contextMenus/ChannelMentionContextMenu.tsx +++ b/src/components/contextMenus/ChannelMentionContextMenu.tsx @@ -1,6 +1,6 @@ // loosely based on https://github.com/revoltchat/frontend/blob/master/components/app/menus/UserContextMenu.tsx -import Channel from "../../stores/objects/Channel"; +import Channel from "@structures/Channel"; import { ContextMenu, ContextMenuButton, ContextMenuDivider } from "./ContextMenu"; interface MenuProps { diff --git a/src/components/contextMenus/ContextMenu.tsx b/src/components/contextMenus/ContextMenu.tsx index 14cca10..d7f41ef 100644 --- a/src/components/contextMenus/ContextMenu.tsx +++ b/src/components/contextMenus/ContextMenu.tsx @@ -1,9 +1,9 @@ // modified from https://github.com/revoltchat/frontend/blob/master/components/app/menus/ContextMenu.tsx // changed some styling +import Icon, { IconProps } from "@components/Icon"; import { ComponentProps } from "react"; import styled from "styled-components"; -import Icon, { IconProps } from "../Icon"; export const ContextMenu = styled.div` display: flex; diff --git a/src/components/contextMenus/GuildContextMenu.tsx b/src/components/contextMenus/GuildContextMenu.tsx index a0aad1c..6887db1 100644 --- a/src/components/contextMenus/GuildContextMenu.tsx +++ b/src/components/contextMenus/GuildContextMenu.tsx @@ -1,10 +1,10 @@ // loosely based on https://github.com/revoltchat/frontend/blob/master/components/app/menus/UserContextMenu.tsx +import { modalController } from "@/controllers/modals"; +import { useAppStore } from "@hooks/useAppStore"; +import useLogger from "@hooks/useLogger"; import { ChannelType } from "@spacebarchat/spacebar-api-types/v9"; -import { modalController } from "../../controllers/modals"; -import { useAppStore } from "../../hooks/useAppStore"; -import useLogger from "../../hooks/useLogger"; -import Guild from "../../stores/objects/Guild"; +import { Guild } from "@structures"; import { ContextMenu, ContextMenuButton, ContextMenuDivider } from "./ContextMenu"; interface MenuProps { diff --git a/src/components/contextMenus/MessageContextMenu.tsx b/src/components/contextMenus/MessageContextMenu.tsx index 2030374..f619ff6 100644 --- a/src/components/contextMenus/MessageContextMenu.tsx +++ b/src/components/contextMenus/MessageContextMenu.tsx @@ -1,6 +1,6 @@ -import { modalController } from "../../controllers/modals"; -import { useAppStore } from "../../hooks/useAppStore"; -import Message from "../../stores/objects/Message"; +import { modalController } from "@/controllers/modals"; +import { useAppStore } from "@hooks/useAppStore"; +import { Message } from "@structures"; import { ContextMenu, ContextMenuButton, ContextMenuDivider } from "./ContextMenu"; interface MenuProps { diff --git a/src/components/contextMenus/UserContextMenu.tsx b/src/components/contextMenus/UserContextMenu.tsx index 798e875..829a1a2 100644 --- a/src/components/contextMenus/UserContextMenu.tsx +++ b/src/components/contextMenus/UserContextMenu.tsx @@ -1,9 +1,8 @@ // loosely based on https://github.com/revoltchat/frontend/blob/master/components/app/menus/UserContextMenu.tsx -import { modalController } from "../../controllers/modals"; -import { useAppStore } from "../../hooks/useAppStore"; -import GuildMember from "../../stores/objects/GuildMember"; -import User from "../../stores/objects/User"; +import { modalController } from "@/controllers/modals"; +import { useAppStore } from "@hooks/useAppStore"; +import { GuildMember, User } from "@structures"; import { ContextMenu, ContextMenuButton, ContextMenuDivider } from "./ContextMenu"; interface MenuProps { diff --git a/src/components/contextMenus/index.ts b/src/components/contextMenus/index.ts new file mode 100644 index 0000000..cdf2664 --- /dev/null +++ b/src/components/contextMenus/index.ts @@ -0,0 +1,6 @@ +export { default as ChannelContextMenu } from "./ChannelContextMenu"; +export { default as ChannelMentionContextMenu } from "./ChannelMentionContextMenu"; +export * from "./ContextMenu"; +export { default as GuildContextMenu } from "./GuildContextMenu"; +export { default as MessageContextMenu } from "./MessageContextMenu"; +export { default as UserContextMenu } from "./UserContextMenu"; diff --git a/src/components/floating/Floating.tsx b/src/components/floating/Floating.tsx index dc8d655..6194558 100644 --- a/src/components/floating/Floating.tsx +++ b/src/components/floating/Floating.tsx @@ -1,11 +1,9 @@ +import Tooltip from "@components/Tooltip"; +import { FloatingContext } from "@contexts/FloatingContext"; import { FloatingArrow, FloatingPortal, Placement } from "@floating-ui/react"; +import useFloating from "@hooks/useFloating"; +import { Guild, GuildMember, User } from "@structures"; import { motion } from "framer-motion"; -import { FloatingContext } from "../../contexts/FloatingContext"; -import useFloating from "../../hooks/useFloating"; -import Guild from "../../stores/objects/Guild"; -import GuildMember from "../../stores/objects/GuildMember"; -import User from "../../stores/objects/User"; -import Tooltip from "../Tooltip"; import GuildMenuPopout from "./GuildMenuPopout"; import UserProfilePopout from "./UserProfilePopout"; diff --git a/src/components/floating/FloatingContent.tsx b/src/components/floating/FloatingContent.tsx index 7a72a9e..ddaf329 100644 --- a/src/components/floating/FloatingContent.tsx +++ b/src/components/floating/FloatingContent.tsx @@ -1,7 +1,7 @@ import { FloatingFocusManager, FloatingPortal, useMergeRefs } from "@floating-ui/react"; +import useFloatingContext from "@hooks/useFloatingContext"; import { motion } from "framer-motion"; import React from "react"; -import useFloatingContext from "../../hooks/useFloatingContext"; export default React.forwardRef>(function PopoverContent( { style, ...props }, diff --git a/src/components/floating/FloatingTrigger.tsx b/src/components/floating/FloatingTrigger.tsx index 88c728c..f47c8d0 100644 --- a/src/components/floating/FloatingTrigger.tsx +++ b/src/components/floating/FloatingTrigger.tsx @@ -1,6 +1,6 @@ import { useMergeRefs } from "@floating-ui/react"; +import useFloatingContext from "@hooks/useFloatingContext"; import React from "react"; -import useFloatingContext from "../../hooks/useFloatingContext"; interface PopoverTriggerProps { children: React.ReactNode; diff --git a/src/components/floating/GuildMenuPopout.tsx b/src/components/floating/GuildMenuPopout.tsx index 5177e52..22c5028 100644 --- a/src/components/floating/GuildMenuPopout.tsx +++ b/src/components/floating/GuildMenuPopout.tsx @@ -1,11 +1,11 @@ +import useLogger from "@hooks/useLogger"; import styled from "styled-components"; -import useLogger from "../../hooks/useLogger"; +import { modalController } from "@/controllers/modals"; +import { ContextMenu, ContextMenuButton, ContextMenuDivider } from "@components/contextMenus/ContextMenu"; +import { useAppStore } from "@hooks/useAppStore"; +import { Permissions } from "@utils"; import React, { useEffect } from "react"; -import { modalController } from "../../controllers/modals"; -import { useAppStore } from "../../hooks/useAppStore"; -import { Permissions } from "../../utils/Permissions"; -import { ContextMenu, ContextMenuButton, ContextMenuDivider } from "../contextMenus/ContextMenu"; const CustomContextMenu = styled(ContextMenu)` width: 200px; diff --git a/src/components/floating/UserProfilePopout.tsx b/src/components/floating/UserProfilePopout.tsx index af8aff6..6705f90 100644 --- a/src/components/floating/UserProfilePopout.tsx +++ b/src/components/floating/UserProfilePopout.tsx @@ -1,16 +1,14 @@ +import Avatar from "@components/Avatar"; +import { HorizontalDivider } from "@components/Divider"; +import useLogger from "@hooks/useLogger"; +import { GuildMember, User } from "@structures"; +import { REST, Snowflake } from "@utils"; import styled from "styled-components"; -import useLogger from "../../hooks/useLogger"; -import GuildMember from "../../stores/objects/GuildMember"; -import User from "../../stores/objects/User"; -import Snowflake from "../../utils/Snowflake"; -import Avatar from "../Avatar"; -import { HorizontalDivider } from "../Divider"; +import SpacebarLogoBlue from "@assets/images/logo/Spacebar_Icon.svg?react"; +import { useAppStore } from "@hooks/useAppStore"; import { CDNRoutes, ImageFormat } from "@spacebarchat/spacebar-api-types/v9"; import dayjs from "dayjs"; -import SpacebarLogoBlue from "../../assets/images/logo/Spacebar_Icon.svg?react"; -import { useAppStore } from "../../hooks/useAppStore"; -import REST from "../../utils/REST"; import Floating from "./Floating"; import FloatingTrigger from "./FloatingTrigger"; diff --git a/src/components/floating/index.ts b/src/components/floating/index.ts new file mode 100644 index 0000000..b057ed9 --- /dev/null +++ b/src/components/floating/index.ts @@ -0,0 +1,6 @@ +export * from "./Floating"; +export { default as Floating } from "./Floating"; +export { default as FloatingContent } from "./FloatingContent"; +export { default as FloatingTrigger } from "./FloatingTrigger"; +export { default as GuildMenuPopout } from "./GuildMenuPopout"; +export { default as UserProfilePopout } from "./UserProfilePopout"; diff --git a/src/components/guards/AuthenticationGuard.tsx b/src/components/guards/AuthenticationGuard.tsx deleted file mode 100644 index ffd164f..0000000 --- a/src/components/guards/AuthenticationGuard.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Navigate } from "react-router-dom"; -import { useAppStore } from "../../hooks/useAppStore"; -import { LoadingSuspense } from "../../pages/LoadingPage"; - -interface Props { - component: React.FC; -} - -export const AuthenticationGuard = ({ component }: Props) => { - const app = useAppStore(); - - if (!app.token) { - return ; - } - - const Component = component; - return ( - - - - ); -}; diff --git a/src/components/guards/UnauthenticatedGuard.tsx b/src/components/guards/UnauthenticatedGuard.tsx deleted file mode 100644 index 45eefb1..0000000 --- a/src/components/guards/UnauthenticatedGuard.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Navigate } from "react-router-dom"; -import { useAppStore } from "../../hooks/useAppStore"; -import { LoadingSuspense } from "../../pages/LoadingPage"; - -interface Props { - component: React.FC; -} - -export const UnauthenticatedGuard = ({ component }: Props) => { - const app = useAppStore(); - - if (app.token) { - return ; - } - - const Component = component; - return ( - - - - ); -}; diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..0427a54 --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1,31 @@ +// export * from "./AuthComponents" +export { default as Avatar } from "./Avatar"; +export { default as Button } from "./Button"; +export { default as ChannelHeader } from "./ChannelHeader"; +export { default as ChannelSidebar } from "./ChannelSidebar"; +export { default as Container } from "./Container"; +export * from "./Divider"; +export { default as DOBInput } from "./DOBInput"; +export { default as ErrorBoundary } from "./ErrorBoundary"; +// export * from "./FormComponents"; +export * from "./banners"; +export * from "./contextMenus"; +export * from "./floating"; +export { default as GuildItem } from "./GuildItem"; +export { default as HCaptcha } from "./HCaptcha"; +export { default as Icon } from "./Icon"; +export { default as IconButton } from "./IconButton"; +export { default as InviteEmbed } from "./InviteEmbed"; +export { default as Link } from "./Link"; +export { default as ListSection } from "./ListSection"; +export { default as Loader } from "./Loader"; +export * from "./markdown"; +export * from "./media"; +export * from "./SectionHeader"; +export { default as SectionTitle } from "./SectionTitle"; +export { default as SidebarAction } from "./SidebarAction"; +export { default as SidebarPill } from "./SidebarPill"; +export { default as SwipeableLayout } from "./SwipeableLayout"; +export { default as Text } from "./Text"; +export { default as Tooltip } from "./Tooltip"; +export { default as UserPanel } from "./UserPanel"; diff --git a/src/components/markdown/MarkdownRenderer.tsx b/src/components/markdown/MarkdownRenderer.tsx index 9269bfc..f9e4081 100644 --- a/src/components/markdown/MarkdownRenderer.tsx +++ b/src/components/markdown/MarkdownRenderer.tsx @@ -1,3 +1,4 @@ +import Link from "@components/Link"; import { FormattingPatterns } from "@spacebarchat/spacebar-api-types/v9"; import Marked, { ReactRenderer } from "marked-react"; import React from "react"; @@ -5,12 +6,11 @@ import reactStringReplace from "react-string-replace"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { materialDark } from "react-syntax-highlighter/dist/cjs/styles/prism"; import styled from "styled-components"; -import CodeBlock from "../Codeblock"; -import Link from "../Link"; -import Spoiler from "../Spoiler"; +import CodeBlock from "./components/Codeblock"; +import Mention from "./components/Mention"; +import Spoiler from "./components/Spoiler"; +import Timestamp from "./components/Timestamp"; import { MarkdownProps } from "./Markdown"; -import Mention from "./Mention"; -import Timestamp from "./Timestamp"; const Container = styled.div` // remove the excessive left padding, and margin in lists diff --git a/src/components/Codeblock.tsx b/src/components/markdown/components/Codeblock.tsx similarity index 88% rename from src/components/Codeblock.tsx rename to src/components/markdown/components/Codeblock.tsx index b5cb703..3e9b7ee 100644 --- a/src/components/Codeblock.tsx +++ b/src/components/markdown/components/Codeblock.tsx @@ -1,10 +1,10 @@ // adapted from Revite // https://github.com/revoltchat/revite/blob/fe63c6633f32b54aa1989cb34627e72bb3377efd/src/components/markdown/plugins/Codeblock.tsx +import Floating from "@components/floating/Floating"; +import FloatingTrigger from "@components/floating/FloatingTrigger"; import React from "react"; import styled from "styled-components"; -import Floating from "./floating/Floating"; -import FloatingTrigger from "./floating/FloatingTrigger"; const Actions = styled.div` position: absolute; @@ -47,7 +47,7 @@ function CodeBlock(props: Props) { const onCopy = React.useCallback(() => { const text = ref.current?.querySelector("code")?.innerText; - text && navigator.clipboard.writeText(text); + if (text) navigator.clipboard.writeText(text); }, [ref]); return ( diff --git a/src/components/markdown/Mention.tsx b/src/components/markdown/components/Mention.tsx similarity index 88% rename from src/components/markdown/Mention.tsx rename to src/components/markdown/components/Mention.tsx index 43359a0..e3604db 100644 --- a/src/components/markdown/Mention.tsx +++ b/src/components/markdown/components/Mention.tsx @@ -1,14 +1,11 @@ +import { Floating, FloatingTrigger } from "@components/floating"; +import { ContextMenuContext } from "@contexts/ContextMenuContext"; +import { useAppStore } from "@hooks/useAppStore"; +import { Channel, Role, User } from "@structures"; +import { hexToRGB, rgbToHsl } from "@utils"; import React, { memo } from "react"; import { useNavigate } from "react-router-dom"; import styled from "styled-components"; -import { ContextMenuContext } from "../../contexts/ContextMenuContext"; -import { useAppStore } from "../../hooks/useAppStore"; -import Channel from "../../stores/objects/Channel"; -import Role from "../../stores/objects/Role"; -import User from "../../stores/objects/User"; -import { hexToRGB, rgbToHsl } from "../../utils/Utils"; -import Floating from "../floating/Floating"; -import FloatingTrigger from "../floating/FloatingTrigger"; const MentionText = styled.span<{ color?: string; withHover?: boolean }>` padding: 0 2px; diff --git a/src/components/Spoiler.tsx b/src/components/markdown/components/Spoiler.tsx similarity index 100% rename from src/components/Spoiler.tsx rename to src/components/markdown/components/Spoiler.tsx diff --git a/src/components/markdown/Timestamp.tsx b/src/components/markdown/components/Timestamp.tsx similarity index 91% rename from src/components/markdown/Timestamp.tsx rename to src/components/markdown/components/Timestamp.tsx index 7295c8b..51b0429 100644 --- a/src/components/markdown/Timestamp.tsx +++ b/src/components/markdown/components/Timestamp.tsx @@ -1,8 +1,7 @@ +import { Floating, FloatingTrigger } from "@components/floating"; import dayjs from "dayjs"; import { memo } from "react"; import styled from "styled-components"; -import Floating from "../floating/Floating"; -import FloatingTrigger from "../floating/FloatingTrigger"; const Container = styled.div` background-color: hsl(var(--background-tertiary-hsl) / 0.3); diff --git a/src/components/markdown/components/index.ts b/src/components/markdown/components/index.ts new file mode 100644 index 0000000..c83b825 --- /dev/null +++ b/src/components/markdown/components/index.ts @@ -0,0 +1,4 @@ +export * from "./Codeblock"; +export * from "./Mention"; +export * from "./Spoiler"; +export * from "./Timestamp"; diff --git a/src/components/markdown/index.ts b/src/components/markdown/index.ts new file mode 100644 index 0000000..d8deac2 --- /dev/null +++ b/src/components/markdown/index.ts @@ -0,0 +1,4 @@ +export * from "./components"; +export { default as Markdown } from "./Markdown"; +export type { MarkdownProps } from "./Markdown"; +export { default as MarkdownRenderer } from "./MarkdownRenderer"; diff --git a/src/components/markdown/style.css b/src/components/markdown/style.css deleted file mode 100644 index a73f978..0000000 --- a/src/components/markdown/style.css +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Synthwave '84 Theme originally by Robb Owen [@Robb0wen] for Visual Studio Code - * Demo: https://marc.dev/demo/prism-synthwave84 - * - * Ported for PrismJS by Marc Backes [@themarcba] - */ - -code[class*="language-"], -pre[class*="language-"] { - color: #f92aad; - text-shadow: - 0 0 2px #100c0f, - 0 0 5px #dc078e33, - 0 0 10px #fff3; - background: none; - font-family: var(--font-family-code); - font-size: 1em; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -/* Code blocks */ -pre[class*="language-"] { - padding: 1em; - margin: 0.5em 0; - overflow: auto; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background-color: transparent !important; - background-image: linear-gradient(to bottom, #2a2139 75%, #34294f); -} - -/* Inline code */ -:not(pre) > code[class*="language-"] { - padding: 0.1em; - border-radius: 0.3em; - white-space: normal; -} - -.token.comment, -.token.block-comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: #8e8e8e; -} - -.token.punctuation { - color: #ccc; -} - -.token.tag, -.token.attr-name, -.token.namespace, -.token.number, -.token.unit, -.token.hexcode, -.token.deleted { - color: #e2777a; -} - -.token.property, -.token.selector { - color: #72f1b8; - text-shadow: - 0 0 2px #100c0f, - 0 0 10px #257c5575, - 0 0 35px #21272475; -} - -.token.function-name { - color: #6196cc; -} - -.token.boolean, -.token.selector .token.id, -.token.function { - color: #fdfdfd; - text-shadow: - 0 0 2px #001716, - 0 0 3px #03edf975, - 0 0 5px #03edf975, - 0 0 8px #03edf975; -} - -.token.class-name { - color: #fff5f6; - text-shadow: - 0 0 2px #000, - 0 0 10px #fc1f2c75, - 0 0 5px #fc1f2c75, - 0 0 25px #fc1f2c75; -} - -.token.constant, -.token.symbol { - color: #f92aad; - text-shadow: - 0 0 2px #100c0f, - 0 0 5px #dc078e33, - 0 0 10px #fff3; -} - -.token.important, -.token.atrule, -.token.keyword, -.token.selector .token.class, -.token.builtin { - color: #f4eee4; - text-shadow: - 0 0 2px #393a33, - 0 0 8px #f39f0575, - 0 0 2px #f39f0575; -} - -.token.string, -.token.char, -.token.attr-value, -.token.regex, -.token.variable { - color: #f87c32; -} - -.token.operator, -.token.entity, -.token.url { - color: #67cdcc; -} - -.token.important, -.token.bold { - font-weight: bold; -} - -.token.italic { - font-style: italic; -} - -.token.entity { - cursor: help; -} - -.token.inserted { - color: green; -} diff --git a/src/components/media/Audio.tsx b/src/components/media/Audio.tsx index c2893c7..f5cfeca 100644 --- a/src/components/media/Audio.tsx +++ b/src/components/media/Audio.tsx @@ -1,8 +1,8 @@ +import Icon from "@components/Icon"; +import Link from "@components/Link"; import { APIAttachment } from "@spacebarchat/spacebar-api-types/v9"; +import { bytesToSize } from "@utils"; import styled from "styled-components"; -import { bytesToSize } from "../../utils/Utils"; -import Icon from "../Icon"; -import Link from "../Link"; const Container = styled.div` margin-top: 10px; @@ -48,7 +48,7 @@ interface Props { attachment: APIAttachment; } -function Audio({ attachment }: Props) { +export function Audio({ attachment }: Props) { const url = attachment.proxy_url && attachment.proxy_url.length > 0 ? attachment.proxy_url : attachment.url; return ( @@ -68,5 +68,3 @@ function Audio({ attachment }: Props) { ); } - -export default Audio; diff --git a/src/components/media/File.tsx b/src/components/media/File.tsx index 47315f2..b9ba04d 100644 --- a/src/components/media/File.tsx +++ b/src/components/media/File.tsx @@ -1,6 +1,6 @@ import { APIAttachment } from "@spacebarchat/spacebar-api-types/v9"; +import { bytesToSize } from "@utils"; import styled from "styled-components"; -import { bytesToSize } from "../../utils/Utils"; import Icon from "../Icon"; import Link from "../Link"; @@ -48,7 +48,7 @@ interface Props { attachment: APIAttachment; } -function File({ attachment }: Props) { +export function File({ attachment }: Props) { const url = attachment.proxy_url && attachment.proxy_url.length > 0 ? attachment.proxy_url : attachment.url; return ( @@ -65,5 +65,3 @@ function File({ attachment }: Props) { ); } - -export default File; diff --git a/src/components/media/Video.tsx b/src/components/media/Video.tsx index 5d1c78f..1daa56e 100644 --- a/src/components/media/Video.tsx +++ b/src/components/media/Video.tsx @@ -1,8 +1,8 @@ import { APIAttachment } from "@spacebarchat/spacebar-api-types/v9"; +import { calculateImageRatio, calculateScaledDimensions } from "@utils"; import React from "react"; import { PuffLoader } from "react-spinners"; import styled from "styled-components"; -import { calculateImageRatio, calculateScaledDimensions } from "../../utils/Message"; const Container = styled.div` display: flex; @@ -18,7 +18,7 @@ interface Props { attachment: APIAttachment; } -function Video({ attachment }: Props) { +export function Video({ attachment }: Props) { const ref = React.useRef(null); const [isLoading, setLoading] = React.useState(true); const [dimensions, setDimensions] = React.useState({ width: 0, height: 0 }); @@ -72,5 +72,3 @@ function Video({ attachment }: Props) { ); } - -export default Video; diff --git a/src/components/media/index.ts b/src/components/media/index.ts new file mode 100644 index 0000000..e865a53 --- /dev/null +++ b/src/components/media/index.ts @@ -0,0 +1,3 @@ +export * from "./Audio"; +export * from "./File"; +export * from "./Video"; diff --git a/src/components/messaging/Chat.tsx b/src/components/messaging/Chat.tsx index 723992f..d9fa76c 100644 --- a/src/components/messaging/Chat.tsx +++ b/src/components/messaging/Chat.tsx @@ -1,12 +1,11 @@ +import MemberList from "@components/MemberList/MemberList"; +import { useAppStore } from "@hooks/useAppStore"; +import useLogger from "@hooks/useLogger"; +import { Channel, Guild } from "@structures"; import { runInAction } from "mobx"; import { observer } from "mobx-react-lite"; import React, { useEffect } from "react"; import styled from "styled-components"; -import { useAppStore } from "../../hooks/useAppStore"; -import useLogger from "../../hooks/useLogger"; -import Channel from "../../stores/objects/Channel"; -import Guild from "../../stores/objects/Guild"; -import MemberList from "../MemberList/MemberList"; import ChatHeader from "./ChatHeader"; import MessageInput from "./MessageInput"; import MessageList from "./MessageList"; diff --git a/src/components/messaging/ChatHeader.tsx b/src/components/messaging/ChatHeader.tsx index 411fb9e..98c0044 100644 --- a/src/components/messaging/ChatHeader.tsx +++ b/src/components/messaging/ChatHeader.tsx @@ -1,13 +1,12 @@ +import { Floating, FloatingTrigger } from "@components/floating"; +import Icon from "@components/Icon"; +import { SectionHeader } from "@components/SectionHeader"; +import { useAppStore } from "@hooks/useAppStore"; +import useLogger from "@hooks/useLogger"; import * as Icons from "@mdi/js"; +import { Channel } from "@structures"; import { observer } from "mobx-react-lite"; import styled from "styled-components"; -import { useAppStore } from "../../hooks/useAppStore"; -import useLogger from "../../hooks/useLogger"; -import Channel from "../../stores/objects/Channel"; -import Icon from "../Icon"; -import { SectionHeader } from "../SectionHeader"; -import Floating from "../floating/Floating"; -import FloatingTrigger from "../floating/FloatingTrigger"; const IconButton = styled.button` margin: 0; diff --git a/src/components/messaging/EmbedMedia.tsx b/src/components/messaging/EmbedMedia.tsx index aae58a2..b2612e0 100644 --- a/src/components/messaging/EmbedMedia.tsx +++ b/src/components/messaging/EmbedMedia.tsx @@ -1,9 +1,9 @@ // adapted from Revite // https://github.com/revoltchat/revite/blob/master/src/components/common/messaging/embed/Embed.tsx +import { modalController } from "@/controllers/modals"; +import Icon from "@components/Icon"; import { APIEmbed, EmbedType } from "@spacebarchat/spacebar-api-types/v9"; -import { modalController } from "../../controllers/modals"; -import Icon from "../Icon"; import styles from "./Embed.module.css"; function getScaledDimensions(originalWidth: number, originalHeight: number, maxWidth: number, maxHeight: number) { diff --git a/src/components/messaging/Message.tsx b/src/components/messaging/Message.tsx index bb5824c..2cf4e01 100644 --- a/src/components/messaging/Message.tsx +++ b/src/components/messaging/Message.tsx @@ -1,11 +1,11 @@ +import Avatar from "@components/Avatar"; +import InviteEmbed from "@components/InviteEmbed"; +import Markdown from "@components/markdown/MarkdownRenderer"; +import { ContextMenuContext } from "@contexts/ContextMenuContext"; +import { useAppStore } from "@hooks/useAppStore"; +import { MessageLike, QueuedMessageStatus } from "@structures"; import { observer } from "mobx-react-lite"; import { memo, useContext } from "react"; -import { ContextMenuContext } from "../../contexts/ContextMenuContext"; -import { useAppStore } from "../../hooks/useAppStore"; -import { MessageLike } from "../../stores/objects/Message"; -import { QueuedMessageStatus } from "../../stores/objects/QueuedMessage"; -import Avatar from "../Avatar"; -import Markdown from "../markdown/MarkdownRenderer"; import MessageAttachment from "./MessageAttachment"; import MessageAuthor from "./MessageAuthor"; import MessageBase, { MessageContent, MessageContentText, MessageDetails, MessageInfo } from "./MessageBase"; @@ -69,6 +69,10 @@ function Message({ message, header }: Props) { {"embeds" in message && message.embeds?.map((embed, index) => )} {"files" in message && message.files?.length !== 0 && } + {"invites" in message && + message.invites.map((code, index) => ( + + ))} ); diff --git a/src/components/messaging/MessageAttachment.tsx b/src/components/messaging/MessageAttachment.tsx index 55f99f3..c39397b 100644 --- a/src/components/messaging/MessageAttachment.tsx +++ b/src/components/messaging/MessageAttachment.tsx @@ -1,11 +1,9 @@ +import { modalController } from "@/controllers/modals"; +import { Audio, File, Video } from "@components/media"; +import useLogger from "@hooks/useLogger"; import { APIAttachment } from "@spacebarchat/spacebar-api-types/v9"; +import { getFileDetails, zoomFit } from "@utils"; import styled from "styled-components"; -import { modalController } from "../../controllers/modals"; -import useLogger from "../../hooks/useLogger"; -import { getFileDetails, zoomFit } from "../../utils/Utils"; -import Audio from "../media/Audio"; -import File from "../media/File"; -import Video from "../media/Video"; const MAX_ATTACHMENT_HEIGHT = 350; diff --git a/src/components/messaging/MessageAuthor.tsx b/src/components/messaging/MessageAuthor.tsx index 73d5920..56275e6 100644 --- a/src/components/messaging/MessageAuthor.tsx +++ b/src/components/messaging/MessageAuthor.tsx @@ -1,14 +1,11 @@ +import { Floating, FloatingTrigger } from "@components/floating"; +import { ContextMenuContext } from "@contexts/ContextMenuContext"; +import { useAppStore } from "@hooks/useAppStore"; +import useLogger from "@hooks/useLogger"; +import { Guild, GuildMember, MessageLike } from "@structures"; import { observer } from "mobx-react-lite"; import React, { useContext } from "react"; import styled from "styled-components"; -import { ContextMenuContext } from "../../contexts/ContextMenuContext"; -import { useAppStore } from "../../hooks/useAppStore"; -import useLogger from "../../hooks/useLogger"; -import Guild from "../../stores/objects/Guild"; -import GuildMember from "../../stores/objects/GuildMember"; -import { MessageLike } from "../../stores/objects/Message"; -import Floating from "../floating/Floating"; -import FloatingTrigger from "../floating/FloatingTrigger"; const Container = styled.div` font-size: 16px; diff --git a/src/components/messaging/MessageBase.tsx b/src/components/messaging/MessageBase.tsx index 527dd2c..967d39b 100644 --- a/src/components/messaging/MessageBase.tsx +++ b/src/components/messaging/MessageBase.tsx @@ -1,10 +1,9 @@ +import { Floating, FloatingTrigger } from "@components/floating"; +import { Message, MessageLike } from "@structures"; +import { calendarStrings } from "@utils"; import dayjs from "dayjs"; import { observer } from "mobx-react-lite"; import styled from "styled-components"; -import Message, { MessageLike } from "../../stores/objects/Message"; -import { calendarStrings } from "../../utils/i18n"; -import Floating from "../floating/Floating"; -import FloatingTrigger from "../floating/FloatingTrigger"; interface Props { header?: boolean; @@ -71,6 +70,7 @@ export const MessageContent = styled.div` justify-content: center; padding-right: 48px; word-wrap: anywhere; + flex: 1; `; export const MessageContentText = styled.div<{ sending?: boolean; failed?: boolean }>` diff --git a/src/components/messaging/MessageEmbed.tsx b/src/components/messaging/MessageEmbed.tsx index 11921e2..9d91a99 100644 --- a/src/components/messaging/MessageEmbed.tsx +++ b/src/components/messaging/MessageEmbed.tsx @@ -1,16 +1,14 @@ // adapted from Revite // https://github.com/revoltchat/revite/blob/master/src/components/common/messaging/embed/Embed.tsx +import { Markdown, MarkdownRenderer } from "@components/markdown"; import { APIEmbed, EmbedType } from "@spacebarchat/spacebar-api-types/v9"; +import { decimalColorToHex } from "@utils"; import classNames from "classnames"; import React from "react"; -import { decimalColorToHex } from "../../utils/Utils"; -import Markdown from "../markdown/Markdown"; -import MarkdownRenderer from "../markdown/MarkdownRenderer"; import styles from "./Embed.module.css"; import EmbedMedia from "./EmbedMedia"; import { MessageAreaWidthContext } from "./MessageList"; - const LINK_EMBED_MAX_WIDTH = 516; const RICH_EMBED_MAX_WIDTH = 428; const CONTAINER_PADDING = 24; @@ -60,7 +58,7 @@ function MessageEmbed({ embed }: Props) { className={classNames(styles.embed, styles.website)} style={{ borderInlineStartColor: embed.color ? decimalColorToHex(embed.color) : "var(--background-tertiary)", - maxWidth: 432, + maxWidth: 430, }} >
{ if (isTouchscreenDevice) return; - ref.current && ref.current.focus(); + if (ref.current) ref.current.focus(); }, [props.value]); const inputSelected = () => ["TEXTAREA", "INPUT"].includes(document.activeElement?.nodeName ?? ""); diff --git a/src/components/messaging/SystemMessage.tsx b/src/components/messaging/SystemMessage.tsx index 0d7ab69..a6d82b6 100644 --- a/src/components/messaging/SystemMessage.tsx +++ b/src/components/messaging/SystemMessage.tsx @@ -1,11 +1,11 @@ +import Icon from "@components/Icon"; import * as Icons from "@mdi/js"; import { MessageType } from "@spacebarchat/spacebar-api-types/v9"; +import { MessageLike } from "@structures"; import { observer } from "mobx-react-lite"; import ReactMarkdown from "react-markdown"; import reactStringReplace from "react-string-replace"; import styled from "styled-components"; -import { MessageLike } from "../../stores/objects/Message"; -import Icon from "../Icon"; import MessageBase, { MessageDetails, MessageInfo } from "./MessageBase"; const SystemContent = styled.div` diff --git a/src/components/messaging/TextareaAutosize.tsx b/src/components/messaging/TextareaAutosize.tsx new file mode 100644 index 0000000..ca2c056 --- /dev/null +++ b/src/components/messaging/TextareaAutosize.tsx @@ -0,0 +1,276 @@ +import { muiDebounce as debounce, ownerWindow, useEnhancedEffect, useForkRef } from "@utils/mui"; +import * as React from "react"; +// import PropTypes from 'prop-types'; +// import { +// unstable_debounce as debounce, +// unstable_useForkRef as useForkRef, +// unstable_useEnhancedEffect as useEnhancedEffect, +// unstable_ownerWindow as ownerWindow, +// } from '@mui/utils'; + +export interface TextareaAutosizeProps + extends Omit, "children" | "rows"> { + ref?: React.Ref; + /** + * Maximum number of rows to display. + */ + maxRows?: string | number; + /** + * Minimum number of rows to display. + * @default 1 + */ + minRows?: string | number; +} + +function getStyleValue(value: string) { + return parseInt(value, 10) || 0; +} + +const styles: { + shadow: React.CSSProperties; +} = { + shadow: { + // Visibility needed to hide the extra text area on iPads + visibility: "hidden", + // Remove from the content flow + position: "absolute", + // Ignore the scrollbar width + overflow: "hidden", + height: 0, + top: 0, + left: 0, + // Create a new layer, increase the isolation of the computed values + transform: "translateZ(0)", + }, +}; + +type TextareaStyles = { + outerHeightStyle: number; + overflowing: boolean; +}; + +function isEmpty(obj: TextareaStyles) { + return ( + obj === undefined || + obj === null || + Object.keys(obj).length === 0 || + (obj.outerHeightStyle === 0 && !obj.overflowing) + ); +} + +/** + * + * Demos: + * + * - [Textarea Autosize](https://mui.com/base-ui/react-textarea-autosize/) + * - [Textarea Autosize](https://mui.com/material-ui/react-textarea-autosize/) + * + * API: + * + * - [TextareaAutosize API](https://mui.com/base-ui/react-textarea-autosize/components-api/#textarea-autosize) + */ +const TextareaAutosize = React.forwardRef(function TextareaAutosize( + props: TextareaAutosizeProps, + forwardedRef: React.ForwardedRef, +) { + const { onChange, maxRows, minRows = 1, style, value, ...other } = props; + + const { current: isControlled } = React.useRef(value != null); + const inputRef = React.useRef(null); + const handleRef = useForkRef(forwardedRef, inputRef); + const heightRef = React.useRef(null); + const shadowRef = React.useRef(null); + + const calculateTextareaStyles = React.useCallback(() => { + const input = inputRef.current!; + + const containerWindow = ownerWindow(input); + const computedStyle = containerWindow.getComputedStyle(input); + + // If input's width is shrunk and it's not visible, don't sync height. + if (computedStyle.width === "0px") { + return { + outerHeightStyle: 0, + overflowing: false, + }; + } + + const inputShallow = shadowRef.current!; + + inputShallow.style.width = computedStyle.width; + inputShallow.value = input.value || props.placeholder || "x"; + if (inputShallow.value.slice(-1) === "\n") { + // Certain fonts which overflow the line height will cause the textarea + // to report a different scrollHeight depending on whether the last line + // is empty. Make it non-empty to avoid this issue. + inputShallow.value += " "; + } + + const boxSizing = computedStyle.boxSizing; + const padding = getStyleValue(computedStyle.paddingBottom) + getStyleValue(computedStyle.paddingTop); + const border = getStyleValue(computedStyle.borderBottomWidth) + getStyleValue(computedStyle.borderTopWidth); + + // The height of the inner content + const innerHeight = inputShallow.scrollHeight; + + // Measure height of a textarea with a single row + inputShallow.value = "x"; + const singleRowHeight = inputShallow.scrollHeight; + + // The height of the outer content + let outerHeight = innerHeight; + + if (minRows) { + outerHeight = Math.max(Number(minRows) * singleRowHeight, outerHeight); + } + if (maxRows) { + outerHeight = Math.min(Number(maxRows) * singleRowHeight, outerHeight); + } + outerHeight = Math.max(outerHeight, singleRowHeight); + + // Take the box sizing into account for applying this value as a style. + const outerHeightStyle = outerHeight + (boxSizing === "border-box" ? padding + border : 0); + const overflowing = Math.abs(outerHeight - innerHeight) <= 1; + + return { outerHeightStyle, overflowing }; + }, [maxRows, minRows, props.placeholder]); + + const syncHeight = React.useCallback(() => { + const textareaStyles = calculateTextareaStyles(); + + if (isEmpty(textareaStyles)) { + return; + } + + const outerHeightStyle = textareaStyles.outerHeightStyle; + const input = inputRef.current!; + if (heightRef.current !== outerHeightStyle) { + heightRef.current = outerHeightStyle; + input.style.height = `${outerHeightStyle}px`; + } + input.style.overflow = textareaStyles.overflowing ? "hidden" : ""; + }, [calculateTextareaStyles]); + + useEnhancedEffect(() => { + const handleResize = () => { + syncHeight(); + }; + // Workaround a "ResizeObserver loop completed with undelivered notifications" error + // in test. + // Note that we might need to use this logic in production per https://github.com/WICG/resize-observer/issues/38 + // Also see https://github.com/mui/mui-x/issues/8733 + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let rAF: any; + const rAFHandleResize = () => { + cancelAnimationFrame(rAF); + rAF = requestAnimationFrame(() => { + handleResize(); + }); + }; + const debounceHandleResize = debounce(handleResize); + const input = inputRef.current!; + const containerWindow = ownerWindow(input); + + containerWindow.addEventListener("resize", debounceHandleResize); + + let resizeObserver: ResizeObserver; + + if (typeof ResizeObserver !== "undefined") { + resizeObserver = new ResizeObserver(process.env.NODE_ENV === "test" ? rAFHandleResize : handleResize); + resizeObserver.observe(input); + } + + return () => { + debounceHandleResize.clear(); + cancelAnimationFrame(rAF); + containerWindow.removeEventListener("resize", debounceHandleResize); + if (resizeObserver) { + resizeObserver.disconnect(); + } + }; + }, [calculateTextareaStyles, syncHeight]); + + useEnhancedEffect(() => { + syncHeight(); + }); + + const handleChange = (event: React.ChangeEvent) => { + if (!isControlled) { + syncHeight(); + } + + if (onChange) { + onChange(event); + } + }; + + return ( + +