diff --git a/web/.storybook/main.js b/web/.storybook/main.js
index 0543917b4b..574ee23318 100644
--- a/web/.storybook/main.js
+++ b/web/.storybook/main.js
@@ -3,9 +3,9 @@ module.exports = {
builder: 'webpack5',
},
stories: [
- '../stories/Introduction.stories.mdx',
- '../stories/**/*.stories.mdx',
+ '../.storybook/stories-category-doc-pages/**/*.stories.mdx',
'../stories/**/*.stories.@(js|jsx|ts|tsx)',
+ '../components/**/*.stories.@(js|jsx|ts|tsx)',
],
addons: [
'@storybook/addon-links',
diff --git a/web/.storybook/preview.js b/web/.storybook/preview.js
index b67a3217d7..e01aef8bc3 100644
--- a/web/.storybook/preview.js
+++ b/web/.storybook/preview.js
@@ -1,7 +1,7 @@
import '../styles/variables.css';
import '../styles/global.less';
import '../styles/theme.less';
-import '../stories/preview.scss';
+import './preview.scss';
import { themes } from '@storybook/theming';
import { DocsContainer } from './storybook-theme';
diff --git a/web/.storybook/preview.scss b/web/.storybook/preview.scss
new file mode 100644
index 0000000000..4dde44b053
--- /dev/null
+++ b/web/.storybook/preview.scss
@@ -0,0 +1,2 @@
+@import '../styles/globals';
+@import '../styles/ant-overrides';
diff --git a/web/stories/Chat.stories.mdx b/web/.storybook/stories-category-doc-pages/Chat.stories.mdx
similarity index 90%
rename from web/stories/Chat.stories.mdx
rename to web/.storybook/stories-category-doc-pages/Chat.stories.mdx
index 89e213d317..5e826a1deb 100644
--- a/web/stories/Chat.stories.mdx
+++ b/web/.storybook/stories-category-doc-pages/Chat.stories.mdx
@@ -1,7 +1,7 @@
import { Meta } from '@storybook/addon-docs';
import { Typography } from 'antd';
-import UserChatMessage from '../components/chat/ChatUserMessage';
-import { ChatMessage } from '../interfaces/chat-message.model';
+import UserChatMessage from '../../components/chat/ChatUserMessage';
+import { ChatMessage } from '../../interfaces/chat-message.model';
@@ -73,4 +73,4 @@ It is used for:
- User "liked" that the steam went live.
- User followed the instance.
-- User shared the instance to their followers.
\ No newline at end of file
+- User shared the instance to their followers.
diff --git a/web/stories/Colors.stories.mdx b/web/.storybook/stories-category-doc-pages/Colors.stories.mdx
similarity index 98%
rename from web/stories/Colors.stories.mdx
rename to web/.storybook/stories-category-doc-pages/Colors.stories.mdx
index 5720d7d5db..94a29f5dff 100644
--- a/web/stories/Colors.stories.mdx
+++ b/web/.storybook/stories-category-doc-pages/Colors.stories.mdx
@@ -1,5 +1,5 @@
import { Canvas, Meta, Story } from '@storybook/addon-docs';
-import { Color, ColorRow } from './Color';
+import { Color, ColorRow } from '../../components/Color';
diff --git a/web/stories/Images.stories.mdx b/web/.storybook/stories-category-doc-pages/Images.stories.mdx
similarity index 60%
rename from web/stories/Images.stories.mdx
rename to web/.storybook/stories-category-doc-pages/Images.stories.mdx
index f5c44223d0..47e61eb011 100644
--- a/web/stories/Images.stories.mdx
+++ b/web/.storybook/stories-category-doc-pages/Images.stories.mdx
@@ -1,12 +1,12 @@
import { Canvas, Meta, Story } from '@storybook/addon-docs';
-import { Image, ImageRow } from './ImageAsset';
+import { Image, ImageRow } from '../../components/ImageAsset';
-import Logo from '../assets/images/logo.svg';
-import FediverseColor from '../assets/images/fediverse-color.png';
-import FediverseBlack from '../assets/images/fediverse-black.png';
-import Moderator from '../assets/images/moderator.svg';
-import IndieAuth from '../assets/images/indieauth.png';
-import IsBot from '../assets/images/bot.svg';
+import Logo from '../../assets/images/logo.svg';
+import FediverseColor from '../../assets/images/fediverse-color.png';
+import FediverseBlack from '../../assets/images/fediverse-black.png';
+import Moderator from '../../assets/images/moderator.svg';
+import IndieAuth from '../../assets/images/indieauth.png';
+import IsBot from '../../assets/images/bot.svg';
diff --git a/web/stories/Introduction.stories.mdx b/web/.storybook/stories-category-doc-pages/Introduction.stories.mdx
similarity index 100%
rename from web/stories/Introduction.stories.mdx
rename to web/.storybook/stories-category-doc-pages/Introduction.stories.mdx
diff --git a/web/stories/Typography.stories.mdx b/web/.storybook/stories-category-doc-pages/Typography.stories.mdx
similarity index 100%
rename from web/stories/Typography.stories.mdx
rename to web/.storybook/stories-category-doc-pages/Typography.stories.mdx
diff --git a/web/stories/Color.tsx b/web/components/Color.tsx
similarity index 100%
rename from web/stories/Color.tsx
rename to web/components/Color.tsx
diff --git a/web/stories/ImageAsset.tsx b/web/components/ImageAsset.tsx
similarity index 100%
rename from web/stories/ImageAsset.tsx
rename to web/components/ImageAsset.tsx
diff --git a/web/components/action-buttons/ActionButton.module.scss b/web/components/action-buttons/ActionButton/ActionButton.module.scss
similarity index 100%
rename from web/components/action-buttons/ActionButton.module.scss
rename to web/components/action-buttons/ActionButton/ActionButton.module.scss
diff --git a/web/stories/ActionButton.stories.tsx b/web/components/action-buttons/ActionButton/ActionButton.stories.tsx
similarity index 95%
rename from web/stories/ActionButton.stories.tsx
rename to web/components/action-buttons/ActionButton/ActionButton.stories.tsx
index cba08c9318..d105b94fa6 100644
--- a/web/stories/ActionButton.stories.tsx
+++ b/web/components/action-buttons/ActionButton/ActionButton.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ActionButton from '../components/action-buttons/ActionButton';
+import ActionButton from './ActionButton';
export default {
title: 'owncast/Components/Action Buttons/Single button',
diff --git a/web/components/action-buttons/ActionButton.tsx b/web/components/action-buttons/ActionButton/ActionButton.tsx
similarity index 90%
rename from web/components/action-buttons/ActionButton.tsx
rename to web/components/action-buttons/ActionButton/ActionButton.tsx
index 64316ea3a9..12bfa122ba 100644
--- a/web/components/action-buttons/ActionButton.tsx
+++ b/web/components/action-buttons/ActionButton/ActionButton.tsx
@@ -1,7 +1,7 @@
import { Button } from 'antd';
import { useState } from 'react';
-import Modal from '../ui/Modal/Modal';
-import { ExternalAction } from '../../interfaces/external-action';
+import Modal from '../../ui/Modal/Modal';
+import { ExternalAction } from '../../../interfaces/external-action';
import s from './ActionButton.module.scss';
interface Props {
diff --git a/web/components/action-buttons/ActionButtons.module.scss b/web/components/action-buttons/ActionButtonRow/ActionButtonRow.module.scss
similarity index 100%
rename from web/components/action-buttons/ActionButtons.module.scss
rename to web/components/action-buttons/ActionButtonRow/ActionButtonRow.module.scss
diff --git a/web/stories/ActionButtonRow.stories.tsx b/web/components/action-buttons/ActionButtonRow/ActionButtonRow.stories.tsx
similarity index 91%
rename from web/stories/ActionButtonRow.stories.tsx
rename to web/components/action-buttons/ActionButtonRow/ActionButtonRow.stories.tsx
index 9963980a96..dd0d408fd9 100644
--- a/web/stories/ActionButtonRow.stories.tsx
+++ b/web/components/action-buttons/ActionButtonRow/ActionButtonRow.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ActionButtonRow from '../components/action-buttons/ActionButtonRow';
-import ActionButton from '../components/action-buttons/ActionButton';
+import ActionButtonRow from './ActionButtonRow';
+import ActionButton from '../ActionButton/ActionButton';
export default {
title: 'owncast/Components/Action Buttons/Buttons Row',
diff --git a/web/components/action-buttons/ActionButtonRow.tsx b/web/components/action-buttons/ActionButtonRow/ActionButtonRow.tsx
similarity index 82%
rename from web/components/action-buttons/ActionButtonRow.tsx
rename to web/components/action-buttons/ActionButtonRow/ActionButtonRow.tsx
index e4ae9b98f9..b9ca3383e1 100644
--- a/web/components/action-buttons/ActionButtonRow.tsx
+++ b/web/components/action-buttons/ActionButtonRow/ActionButtonRow.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import s from './ActionButtons.module.scss';
+import s from './ActionButtonRow.module.scss';
interface Props {
children: React.ReactNode[];
diff --git a/web/components/action-buttons/FollowButton.tsx b/web/components/action-buttons/FollowButton.tsx
index ce69857e70..a73047d32c 100644
--- a/web/components/action-buttons/FollowButton.tsx
+++ b/web/components/action-buttons/FollowButton.tsx
@@ -3,8 +3,8 @@ import { HeartFilled } from '@ant-design/icons';
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
import Modal from '../ui/Modal/Modal';
-import FollowModal from '../modals/Follow/FollowModal';
-import s from './ActionButton.module.scss';
+import FollowModal from '../modals/FollowModal/FollowModal';
+import s from './ActionButton/ActionButton.module.scss';
import { clientConfigStateAtom } from '../stores/ClientConfigStore';
import { ClientConfig } from '../../interfaces/client-config.model';
diff --git a/web/components/action-buttons/NotifyButton.tsx b/web/components/action-buttons/NotifyButton.tsx
index 7dbc6b237f..da80e98a6f 100644
--- a/web/components/action-buttons/NotifyButton.tsx
+++ b/web/components/action-buttons/NotifyButton.tsx
@@ -1,6 +1,6 @@
import { Button } from 'antd';
import { BellFilled } from '@ant-design/icons';
-import s from './ActionButton.module.scss';
+import s from './ActionButton/ActionButton.module.scss';
interface Props {
onClick: () => void;
diff --git a/web/components/chat/ChatAction/ChatActionMessage.module.scss b/web/components/chat/ChatActionMessage/ChatActionMessage.module.scss
similarity index 100%
rename from web/components/chat/ChatAction/ChatActionMessage.module.scss
rename to web/components/chat/ChatActionMessage/ChatActionMessage.module.scss
diff --git a/web/stories/ChatActionMessage.stories.tsx b/web/components/chat/ChatActionMessage/ChatActionMessage.stories.tsx
similarity index 82%
rename from web/stories/ChatActionMessage.stories.tsx
rename to web/components/chat/ChatActionMessage/ChatActionMessage.stories.tsx
index 7e3f041912..b97d2358de 100644
--- a/web/stories/ChatActionMessage.stories.tsx
+++ b/web/components/chat/ChatActionMessage/ChatActionMessage.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ChatActionMessage from '../components/chat/ChatAction/ChatActionMessage';
-import Mock from './assets/mocks/chatmessage-action.png';
+import ChatActionMessage from './ChatActionMessage';
+import Mock from '../../../stories/assets/mocks/chatmessage-action.png';
export default {
title: 'owncast/Chat/Messages/Chat action',
diff --git a/web/components/chat/ChatAction/ChatActionMessage.tsx b/web/components/chat/ChatActionMessage/ChatActionMessage.tsx
similarity index 100%
rename from web/components/chat/ChatAction/ChatActionMessage.tsx
rename to web/components/chat/ChatActionMessage/ChatActionMessage.tsx
diff --git a/web/stories/ChatContainer.stories.tsx b/web/components/chat/ChatContainer/ChatContainer.stories.tsx
similarity index 98%
rename from web/stories/ChatContainer.stories.tsx
rename to web/components/chat/ChatContainer/ChatContainer.stories.tsx
index ca7e947e26..df183788b9 100644
--- a/web/stories/ChatContainer.stories.tsx
+++ b/web/components/chat/ChatContainer/ChatContainer.stories.tsx
@@ -1,8 +1,8 @@
import React, { useState } from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import ChatContainer from '../components/chat/ChatContainer';
-import { ChatMessage } from '../interfaces/chat-message.model';
+import ChatContainer from './index';
+import { ChatMessage } from '../../../interfaces/chat-message.model';
export default {
title: 'owncast/Chat/Chat messages container',
diff --git a/web/stories/ChatJoinMessage.stories.tsx b/web/components/chat/ChatJoinMessage/ChatJoinMessage.stories.tsx
similarity index 87%
rename from web/stories/ChatJoinMessage.stories.tsx
rename to web/components/chat/ChatJoinMessage/ChatJoinMessage.stories.tsx
index bdf8772fab..e628b0ecec 100644
--- a/web/stories/ChatJoinMessage.stories.tsx
+++ b/web/components/chat/ChatJoinMessage/ChatJoinMessage.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ChatJoinMessage from '../components/chat/ChatJoinMessage/ChatJoinMessage';
-import Mock from './assets/mocks/chatmessage-action.png';
+import ChatJoinMessage from './ChatJoinMessage';
+import Mock from '../../../stories/assets/mocks/chatmessage-action.png';
export default {
title: 'owncast/Chat/Messages/Chat Join',
diff --git a/web/stories/ChatModerationActionMenu.stories.tsx b/web/components/chat/ChatModerationActionMenu/ChatModerationActionMenu.stories.tsx
similarity index 96%
rename from web/stories/ChatModerationActionMenu.stories.tsx
rename to web/components/chat/ChatModerationActionMenu/ChatModerationActionMenu.stories.tsx
index 4fdfedcf91..f2bcb0f2dd 100644
--- a/web/stories/ChatModerationActionMenu.stories.tsx
+++ b/web/components/chat/ChatModerationActionMenu/ChatModerationActionMenu.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import ChatModerationActionMenu from '../components/chat/ChatModerationActionMenu/ChatModerationActionMenu';
+import ChatModerationActionMenu from './ChatModerationActionMenu';
const mocks = {
mocks: [
diff --git a/web/components/chat/ChatModerationActionMenu/ChatModerationActionMenu.tsx b/web/components/chat/ChatModerationActionMenu/ChatModerationActionMenu.tsx
index 11fb5e385f..de415f7c2e 100644
--- a/web/components/chat/ChatModerationActionMenu/ChatModerationActionMenu.tsx
+++ b/web/components/chat/ChatModerationActionMenu/ChatModerationActionMenu.tsx
@@ -6,7 +6,7 @@ import {
} from '@ant-design/icons';
import { Dropdown, Menu, MenuProps, Space, Modal, message } from 'antd';
import { useState } from 'react';
-import ChatModerationDetailsModal from './ChatModerationDetailsModal';
+import ChatModerationDetailsModal from '../ChatModerationDetailsModal/ChatModerationDetailsModal';
import s from './ChatModerationActionMenu.module.scss';
import ChatModeration from '../../../services/moderation-service';
diff --git a/web/components/chat/ChatModerationActionMenu/ChatModerationDetailsModal.module.scss b/web/components/chat/ChatModerationDetailsModal/ChatModerationDetailsModal.module.scss
similarity index 100%
rename from web/components/chat/ChatModerationActionMenu/ChatModerationDetailsModal.module.scss
rename to web/components/chat/ChatModerationDetailsModal/ChatModerationDetailsModal.module.scss
diff --git a/web/stories/ChatModerationDetailsModal.stories.tsx b/web/components/chat/ChatModerationDetailsModal/ChatModerationDetailsModal.stories.tsx
similarity index 96%
rename from web/stories/ChatModerationDetailsModal.stories.tsx
rename to web/components/chat/ChatModerationDetailsModal/ChatModerationDetailsModal.stories.tsx
index 8eec402f54..92badbb3a4 100644
--- a/web/stories/ChatModerationDetailsModal.stories.tsx
+++ b/web/components/chat/ChatModerationDetailsModal/ChatModerationDetailsModal.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import ChatModerationDetailsModal from '../components/chat/ChatModerationActionMenu/ChatModerationDetailsModal';
+import ChatModerationDetailsModal from './ChatModerationDetailsModal';
const mocks = {
mocks: [
diff --git a/web/components/chat/ChatModerationActionMenu/ChatModerationDetailsModal.tsx b/web/components/chat/ChatModerationDetailsModal/ChatModerationDetailsModal.tsx
similarity index 100%
rename from web/components/chat/ChatModerationActionMenu/ChatModerationDetailsModal.tsx
rename to web/components/chat/ChatModerationDetailsModal/ChatModerationDetailsModal.tsx
diff --git a/web/stories/ChatModeratorNotification.stories.tsx b/web/components/chat/ChatModeratorNotification/ChatModeratorNotification.stories.tsx
similarity index 83%
rename from web/stories/ChatModeratorNotification.stories.tsx
rename to web/components/chat/ChatModeratorNotification/ChatModeratorNotification.stories.tsx
index 35d3950b34..8edd83fd3a 100644
--- a/web/stories/ChatModeratorNotification.stories.tsx
+++ b/web/components/chat/ChatModeratorNotification/ChatModeratorNotification.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ChatModeratorNotification from '../components/chat/ChatModeratorNotification/ChatModeratorNotification';
+import ChatModeratorNotification from './ChatModeratorNotification';
export default {
title: 'owncast/Chat/Messages/Moderation Role Notification',
diff --git a/web/stories/ChatSocialMessage.stories.tsx b/web/components/chat/ChatSocialMessage/ChatSocialMessage.stories.tsx
similarity index 88%
rename from web/stories/ChatSocialMessage.stories.tsx
rename to web/components/chat/ChatSocialMessage/ChatSocialMessage.stories.tsx
index f31d7b3fae..b47b913d73 100644
--- a/web/stories/ChatSocialMessage.stories.tsx
+++ b/web/components/chat/ChatSocialMessage/ChatSocialMessage.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ChatSocialMessage from '../components/chat/ChatSocialMessage';
+import ChatSocialMessage from './ChatSocialMessage';
export default {
title: 'owncast/Chat/Messages/Social-fediverse event',
diff --git a/web/components/chat/ChatSocialMessage.tsx b/web/components/chat/ChatSocialMessage/ChatSocialMessage.tsx
similarity index 78%
rename from web/components/chat/ChatSocialMessage.tsx
rename to web/components/chat/ChatSocialMessage/ChatSocialMessage.tsx
index 1ce8f0095f..3b456c5eaa 100644
--- a/web/components/chat/ChatSocialMessage.tsx
+++ b/web/components/chat/ChatSocialMessage/ChatSocialMessage.tsx
@@ -1,6 +1,6 @@
/* eslint-disable react/no-unused-prop-types */
/* eslint-disable @typescript-eslint/no-unused-vars */
-import { ChatMessage } from '../../interfaces/chat-message.model';
+import { ChatMessage } from '../../../interfaces/chat-message.model';
interface Props {
message: ChatMessage;
diff --git a/web/stories/ChatSystemMessage.stories.tsx b/web/components/chat/ChatSystemMessage/ChatSystemMessage.stories.tsx
similarity index 84%
rename from web/stories/ChatSystemMessage.stories.tsx
rename to web/components/chat/ChatSystemMessage/ChatSystemMessage.stories.tsx
index def581f9af..78f435feac 100644
--- a/web/stories/ChatSystemMessage.stories.tsx
+++ b/web/components/chat/ChatSystemMessage/ChatSystemMessage.stories.tsx
@@ -1,8 +1,8 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ChatSystemMessage from '../components/chat/ChatSystemMessage/ChatSystemMessage';
-import Mock from './assets/mocks/chatmessage-system.png';
-import { ChatMessage } from '../interfaces/chat-message.model';
+import ChatSystemMessage from './ChatSystemMessage';
+import Mock from '../../../stories/assets/mocks/chatmessage-system.png';
+import { ChatMessage } from '../../../interfaces/chat-message.model';
export default {
title: 'owncast/Chat/Messages/System',
diff --git a/web/stories/ChatTextField.stories.tsx b/web/components/chat/ChatTextField/ChatTextField.stories.tsx
similarity index 92%
rename from web/stories/ChatTextField.stories.tsx
rename to web/components/chat/ChatTextField/ChatTextField.stories.tsx
index dc7af94855..fee8a1e30d 100644
--- a/web/stories/ChatTextField.stories.tsx
+++ b/web/components/chat/ChatTextField/ChatTextField.stories.tsx
@@ -1,8 +1,8 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import ChatTextField from '../components/chat/ChatTextField/ChatTextField';
-import Mock from './assets/mocks/chatinput-mock.png';
+import ChatTextField from './ChatTextField';
+import Mock from '../../../stories/assets/mocks/chatinput-mock.png';
export default {
title: 'owncast/Chat/Input text field',
diff --git a/web/stories/ChatUserBadge.stories.tsx b/web/components/chat/ChatUserBadge/ChatUserBadge.stories.tsx
similarity index 89%
rename from web/stories/ChatUserBadge.stories.tsx
rename to web/components/chat/ChatUserBadge/ChatUserBadge.stories.tsx
index 0774542f5f..8b76eae0bd 100644
--- a/web/stories/ChatUserBadge.stories.tsx
+++ b/web/components/chat/ChatUserBadge/ChatUserBadge.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ChatUserBadge from '../components/chat/ChatUserBadge/ChatUserBadge';
+import ChatUserBadge from './ChatUserBadge';
export default {
title: 'owncast/Chat/Messages/User Flag',
diff --git a/web/stories/ChatUserMessage.stories.tsx b/web/components/chat/ChatUserMessage/ChatUserMessage.stories.tsx
similarity index 88%
rename from web/stories/ChatUserMessage.stories.tsx
rename to web/components/chat/ChatUserMessage/ChatUserMessage.stories.tsx
index 1b4cf89d97..faee6d38ce 100644
--- a/web/stories/ChatUserMessage.stories.tsx
+++ b/web/components/chat/ChatUserMessage/ChatUserMessage.stories.tsx
@@ -1,12 +1,12 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import UserChatMessage from '../components/chat/ChatUserMessage';
-import { ChatMessage } from '../interfaces/chat-message.model';
-import Mock from './assets/mocks/chatmessage-user.png';
+import ChatUserMessage from './index';
+import { ChatMessage } from '../../../interfaces/chat-message.model';
+import Mock from '../../../stories/assets/mocks/chatmessage-user.png';
export default {
title: 'owncast/Chat/Messages/Standard user',
- component: UserChatMessage,
+ component: ChatUserMessage,
parameters: {
design: {
type: 'image',
@@ -19,9 +19,9 @@ export default {
},
},
},
-} as ComponentMeta;
+} as ComponentMeta;
-const Template: ComponentStory = args => ;
+const Template: ComponentStory = args => ;
const standardMessage: ChatMessage = JSON.parse(`{
"type": "CHAT",
diff --git a/web/components/client-table.tsx b/web/components/client-table.tsx
index b1ae3dd11d..90465c5e9f 100644
--- a/web/components/client-table.tsx
+++ b/web/components/client-table.tsx
@@ -5,7 +5,7 @@ import { SearchOutlined } from '@ant-design/icons';
import { formatDistanceToNow } from 'date-fns';
import { Client } from '../types/chat';
import UserPopover from './user-popover';
-import BanUserButton from './ban-user-button';
+import BanUserButton from './other/ban-user-button/ban-user-button';
import { formatUAstring } from '../utils/format';
export default function ClientTable({ data }: ClientTableProps) {
diff --git a/web/stories/ContentHeader.stories.tsx b/web/components/common/ContentHeader/ContentHeader.stories.tsx
similarity index 96%
rename from web/stories/ContentHeader.stories.tsx
rename to web/components/common/ContentHeader/ContentHeader.stories.tsx
index 2946dbb592..474efccc64 100644
--- a/web/stories/ContentHeader.stories.tsx
+++ b/web/components/common/ContentHeader/ContentHeader.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import ContentHeader from '../components/common/ContentHeader/ContentHeader';
+import ContentHeader from './ContentHeader';
export default {
title: 'owncast/Components/Content Header',
diff --git a/web/stories/HeaderLogo.stories.tsx b/web/components/common/Logo/Logo.stories.tsx
similarity index 92%
rename from web/stories/HeaderLogo.stories.tsx
rename to web/components/common/Logo/Logo.stories.tsx
index 88b03c91b8..f0f13f1c2f 100644
--- a/web/stories/HeaderLogo.stories.tsx
+++ b/web/components/common/Logo/Logo.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import { OwncastLogo } from '../components/common';
+import OwncastLogo from './Logo';
export default {
title: 'owncast/Components/Header Logo',
diff --git a/web/stories/UserDropdownMenu.stories.tsx b/web/components/common/UserDropdown/UserDropdown.stories.tsx
similarity index 93%
rename from web/stories/UserDropdownMenu.stories.tsx
rename to web/components/common/UserDropdown/UserDropdown.stories.tsx
index 8ed2494748..6bd45123ca 100644
--- a/web/stories/UserDropdownMenu.stories.tsx
+++ b/web/components/common/UserDropdown/UserDropdown.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import { UserDropdown } from '../components/common';
+import UserDropdown from './UserDropdown';
export default {
title: 'owncast/Components/User settings menu',
diff --git a/web/components/common/UserDropdown/UserDropdown.tsx b/web/components/common/UserDropdown/UserDropdown.tsx
index 424b307ea8..9b60472e74 100644
--- a/web/components/common/UserDropdown/UserDropdown.tsx
+++ b/web/components/common/UserDropdown/UserDropdown.tsx
@@ -16,7 +16,7 @@ import {
appStateAtom,
} from '../../stores/ClientConfigStore';
import s from './UserDropdown.module.scss';
-import NameChangeModal from '../../modals/NameChangeModal';
+import NameChangeModal from '../../modals/NameChangeModal/NameChangeModal';
import { AppStateOptions } from '../../stores/application-state';
import AuthModal from '../../modals/AuthModal/AuthModal';
diff --git a/web/components/layouts/Main.tsx b/web/components/layouts/Main.tsx
index 2cb8c1f715..b58a359966 100644
--- a/web/components/layouts/Main.tsx
+++ b/web/components/layouts/Main.tsx
@@ -11,7 +11,7 @@ import {
import { Content, Header } from '../ui';
import { ClientConfig } from '../../interfaces/client-config.model';
import { DisplayableError } from '../../types/displayable-error';
-import FatalErrorStateModal from '../modals/FatalErrorModal';
+import FatalErrorStateModal from '../modals/FatalErrorStateModal/FatalErrorStateModal';
import setupNoLinkReferrer from '../../utils/no-link-referrer';
function Main() {
diff --git a/web/stories/AuthModal.stories.tsx b/web/components/modals/AuthModal/AuthModal.stories.tsx
similarity index 90%
rename from web/stories/AuthModal.stories.tsx
rename to web/components/modals/AuthModal/AuthModal.stories.tsx
index f86d35f771..57dcf5d676 100644
--- a/web/stories/AuthModal.stories.tsx
+++ b/web/components/modals/AuthModal/AuthModal.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import AuthModal from '../components/modals/AuthModal/AuthModal';
+import AuthModal from './AuthModal';
const Example = () => (
diff --git a/web/components/modals/AuthModal/AuthModal.tsx b/web/components/modals/AuthModal/AuthModal.tsx
index 4d951eca91..f883a14f44 100644
--- a/web/components/modals/AuthModal/AuthModal.tsx
+++ b/web/components/modals/AuthModal/AuthModal.tsx
@@ -1,7 +1,7 @@
import { Tabs } from 'antd';
import { useRecoilValue } from 'recoil';
-import IndieAuthModal from '../IndieAuthModal';
-import FediAuthModal from '../FediAuthModal';
+import IndieAuthModal from '../IndieAuthModal/IndieAuthModal';
+import FediAuthModal from '../FediAuthModal/FediAuthModal';
import FediverseIcon from '../../../assets/images/fediverse-black.png';
import IndieAuthIcon from '../../../assets/images/indieauth.png';
diff --git a/web/components/modals/BrowserNotify/BrowserNotifyModal.module.scss b/web/components/modals/BrowserNotifyModal/BrowserNotifyModal.module.scss
similarity index 100%
rename from web/components/modals/BrowserNotify/BrowserNotifyModal.module.scss
rename to web/components/modals/BrowserNotifyModal/BrowserNotifyModal.module.scss
diff --git a/web/stories/BrowserNotifyModal.stories.tsx b/web/components/modals/BrowserNotifyModal/BrowserNotifyModal.stories.tsx
similarity index 87%
rename from web/stories/BrowserNotifyModal.stories.tsx
rename to web/components/modals/BrowserNotifyModal/BrowserNotifyModal.stories.tsx
index 00ecc354ec..4826f64750 100644
--- a/web/stories/BrowserNotifyModal.stories.tsx
+++ b/web/components/modals/BrowserNotifyModal/BrowserNotifyModal.stories.tsx
@@ -1,8 +1,8 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import BrowserNotifyModal from '../components/modals/BrowserNotify/BrowserNotifyModal';
-import BrowserNotifyModalMock from './assets/mocks/notify-modal.png';
+import BrowserNotifyModal from './BrowserNotifyModal';
+import BrowserNotifyModalMock from '../../../stories/assets/mocks/notify-modal.png';
const Example = () => (
@@ -22,7 +22,7 @@ export default {
docs: {
description: {
component: `The notify modal allows an end user to get notified when the stream goes live via [Browser Push Notifications](https://developers.google.com/web/ilt/pwa/introduction-to-push-notifications) It must:
-
+
- Verify the browser supports notifications.
- Handle errors that come back from the server.
- Have an enabled and disabled state with accurate information about each.
diff --git a/web/components/modals/BrowserNotify/BrowserNotifyModal.tsx b/web/components/modals/BrowserNotifyModal/BrowserNotifyModal.tsx
similarity index 100%
rename from web/components/modals/BrowserNotify/BrowserNotifyModal.tsx
rename to web/components/modals/BrowserNotifyModal/BrowserNotifyModal.tsx
diff --git a/web/stories/FatalErrorStateModal.stories.tsx b/web/components/modals/FatalErrorStateModal/FatalErrorStateModal.stories.tsx
similarity index 89%
rename from web/stories/FatalErrorStateModal.stories.tsx
rename to web/components/modals/FatalErrorStateModal/FatalErrorStateModal.stories.tsx
index 6795241886..44977e7bba 100644
--- a/web/stories/FatalErrorStateModal.stories.tsx
+++ b/web/components/modals/FatalErrorStateModal/FatalErrorStateModal.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import FatalErrorStateModal from '../components/modals/FatalErrorModal';
+import FatalErrorStateModal from './FatalErrorStateModal';
export default {
title: 'owncast/Modals/Global error state',
diff --git a/web/components/modals/FatalErrorModal.tsx b/web/components/modals/FatalErrorStateModal/FatalErrorStateModal.tsx
similarity index 100%
rename from web/components/modals/FatalErrorModal.tsx
rename to web/components/modals/FatalErrorStateModal/FatalErrorStateModal.tsx
diff --git a/web/stories/FediAuthModal.stories.tsx b/web/components/modals/FediAuthModal/FediAuthModal.stories.tsx
similarity index 82%
rename from web/stories/FediAuthModal.stories.tsx
rename to web/components/modals/FediAuthModal/FediAuthModal.stories.tsx
index 4b56560f70..2c62aca90b 100644
--- a/web/stories/FediAuthModal.stories.tsx
+++ b/web/components/modals/FediAuthModal/FediAuthModal.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import FediAuthModal from '../components/modals/FediAuthModal';
-import FediAuthModalMock from './assets/mocks/fediauth-modal.png';
+import FediAuthModal from './FediAuthModal';
+import FediAuthModalMock from '../../../stories/assets/mocks/fediauth-modal.png';
const Example = () => (
diff --git a/web/components/modals/FediAuthModal.tsx b/web/components/modals/FediAuthModal/FediAuthModal.tsx
similarity index 100%
rename from web/components/modals/FediAuthModal.tsx
rename to web/components/modals/FediAuthModal/FediAuthModal.tsx
diff --git a/web/components/modals/Follow/FollowModal.module.scss b/web/components/modals/FollowModal/FollowModal.module.scss
similarity index 100%
rename from web/components/modals/Follow/FollowModal.module.scss
rename to web/components/modals/FollowModal/FollowModal.module.scss
diff --git a/web/stories/FollowModal.stories.tsx b/web/components/modals/FollowModal/FollowModal.stories.tsx
similarity index 89%
rename from web/stories/FollowModal.stories.tsx
rename to web/components/modals/FollowModal/FollowModal.stories.tsx
index 7cd46fcdfe..63b3d3c8a9 100644
--- a/web/stories/FollowModal.stories.tsx
+++ b/web/components/modals/FollowModal/FollowModal.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import FollowModal from '../components/modals/Follow/FollowModal';
-import FollowModalMock from './assets/mocks/follow-modal.png';
+import FollowModal from './FollowModal';
+import FollowModalMock from '../../../stories/assets/mocks/follow-modal.png';
const Example = () => (
diff --git a/web/components/modals/Follow/FollowModal.tsx b/web/components/modals/FollowModal/FollowModal.tsx
similarity index 100%
rename from web/components/modals/Follow/FollowModal.tsx
rename to web/components/modals/FollowModal/FollowModal.tsx
diff --git a/web/stories/IndieAuthModal.stories.tsx b/web/components/modals/IndieAuthModal/IndieAuthModal.stories.tsx
similarity index 85%
rename from web/stories/IndieAuthModal.stories.tsx
rename to web/components/modals/IndieAuthModal/IndieAuthModal.stories.tsx
index cd22078dc2..3d77260d9c 100644
--- a/web/stories/IndieAuthModal.stories.tsx
+++ b/web/components/modals/IndieAuthModal/IndieAuthModal.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import IndieAuthModal from '../components/modals/IndieAuthModal';
-import Mock from './assets/mocks/indieauth-modal.png';
+import IndieAuthModal from './IndieAuthModal';
+import Mock from '../../../stories/assets/mocks/indieauth-modal.png';
const Example = () => (
diff --git a/web/components/modals/IndieAuthModal.tsx b/web/components/modals/IndieAuthModal/IndieAuthModal.tsx
similarity index 98%
rename from web/components/modals/IndieAuthModal.tsx
rename to web/components/modals/IndieAuthModal/IndieAuthModal.tsx
index 9a81327d63..6f0919f830 100644
--- a/web/components/modals/IndieAuthModal.tsx
+++ b/web/components/modals/IndieAuthModal/IndieAuthModal.tsx
@@ -1,6 +1,6 @@
import { Alert, Button, Input, Space, Spin, Collapse, Typography } from 'antd';
import React, { useState } from 'react';
-import isValidURL from '../../utils/urls';
+import isValidURL from '../../../utils/urls';
const { Panel } = Collapse;
const { Link } = Typography;
diff --git a/web/stories/NameChangeModal.stories.tsx b/web/components/modals/NameChangeModal/NameChangeModal.stories.tsx
similarity index 89%
rename from web/stories/NameChangeModal.stories.tsx
rename to web/components/modals/NameChangeModal/NameChangeModal.stories.tsx
index a3557b1a1a..bbc9549ead 100644
--- a/web/stories/NameChangeModal.stories.tsx
+++ b/web/components/modals/NameChangeModal/NameChangeModal.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import NameChangeModal from '../components/modals/NameChangeModal';
+import NameChangeModal from './NameChangeModal';
export default {
title: 'owncast/Modals/Name change',
diff --git a/web/components/modals/NameChangeModal.tsx b/web/components/modals/NameChangeModal/NameChangeModal.tsx
similarity index 93%
rename from web/components/modals/NameChangeModal.tsx
rename to web/components/modals/NameChangeModal/NameChangeModal.tsx
index 83c12530cd..9146bfb90e 100644
--- a/web/components/modals/NameChangeModal.tsx
+++ b/web/components/modals/NameChangeModal/NameChangeModal.tsx
@@ -1,13 +1,13 @@
import React, { CSSProperties, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { Input, Button, Select } from 'antd';
-import { MessageType } from '../../interfaces/socket-events';
-import WebsocketService from '../../services/websocket-service';
+import { MessageType } from '../../../interfaces/socket-events';
+import WebsocketService from '../../../services/websocket-service';
import {
websocketServiceAtom,
chatDisplayNameAtom,
chatDisplayColorAtom,
-} from '../stores/ClientConfigStore';
+} from '../../stores/ClientConfigStore';
const { Option } = Select;
diff --git a/web/components/ban-user-button.tsx b/web/components/other/ban-user-button/ban-user-button.tsx
similarity index 95%
rename from web/components/ban-user-button.tsx
rename to web/components/other/ban-user-button/ban-user-button.tsx
index 8763155bfe..778db4288e 100644
--- a/web/components/ban-user-button.tsx
+++ b/web/components/other/ban-user-button/ban-user-button.tsx
@@ -1,7 +1,7 @@
import { Modal, Button } from 'antd';
import { ExclamationCircleFilled, QuestionCircleFilled, StopTwoTone } from '@ant-design/icons';
-import { USER_ENABLED_TOGGLE, fetchData } from '../utils/apis';
-import { User } from '../types/chat';
+import { USER_ENABLED_TOGGLE, fetchData } from '../../../utils/apis';
+import { User } from '../../../types/chat';
interface BanUserButtonProps {
user: User;
diff --git a/web/components/ui/Content/Content.tsx b/web/components/ui/Content/Content.tsx
index 845f89b0ba..84f4009727 100644
--- a/web/components/ui/Content/Content.tsx
+++ b/web/components/ui/Content/Content.tsx
@@ -18,23 +18,23 @@ import {
} from '../../stores/ClientConfigStore';
import { ClientConfig } from '../../../interfaces/client-config.model';
import CustomPageContent from '../CustomPageContent/CustomPageContent';
-import OwncastPlayer from '../../video/OwncastPlayer';
-import FollowerCollection from '../Followers/FollowersCollection';
+import OwncastPlayer from '../../video/OwncastPlayer/OwncastPlayer';
+import FollowerCollection from '../followers/FollowerCollection/FollowerCollection';
import s from './Content.module.scss';
import Sidebar from '../Sidebar';
import Footer from '../Footer';
// import ChatContainer from '../../chat/ChatContainer';
// import { ChatMessage } from '../../../interfaces/chat-message.model';
// import ChatTextField from '../../chat/ChatTextField/ChatTextField';
-import ActionButtonRow from '../../action-buttons/ActionButtonRow';
-import ActionButton from '../../action-buttons/ActionButton';
+import ActionButtonRow from '../../action-buttons/ActionButtonRow/ActionButtonRow';
+import ActionButton from '../../action-buttons/ActionButton/ActionButton';
import NotifyReminderPopup from '../NotifyReminderPopup/NotifyReminderPopup';
import OfflineBanner from '../OfflineBanner/OfflineBanner';
import { AppStateOptions } from '../../stores/application-state';
import FollowButton from '../../action-buttons/FollowButton';
import NotifyButton from '../../action-buttons/NotifyButton';
import Modal from '../Modal/Modal';
-import BrowserNotifyModal from '../../modals/BrowserNotify/BrowserNotifyModal';
+import BrowserNotifyModal from '../../modals/BrowserNotifyModal/BrowserNotifyModal';
import ContentHeader from '../../common/ContentHeader';
import { ServerStatus } from '../../../interfaces/server-status.model';
import { StatusBar } from '..';
diff --git a/web/stories/CustomPageContent.stories.tsx b/web/components/ui/CustomPageContent/CustomPageContent.stories.tsx
similarity index 99%
rename from web/stories/CustomPageContent.stories.tsx
rename to web/components/ui/CustomPageContent/CustomPageContent.stories.tsx
index 11726d8d50..6fccdf9865 100644
--- a/web/stories/CustomPageContent.stories.tsx
+++ b/web/components/ui/CustomPageContent/CustomPageContent.stories.tsx
@@ -1,7 +1,7 @@
/* eslint-disable no-useless-escape */
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import CustomPageContent from '../components/ui/CustomPageContent/CustomPageContent';
+import CustomPageContent from './CustomPageContent';
export default {
title: 'owncast/Components/Custom page content',
diff --git a/web/stories/Footer.stories.tsx b/web/components/ui/Footer/Footer.stories.tsx
similarity index 89%
rename from web/stories/Footer.stories.tsx
rename to web/components/ui/Footer/Footer.stories.tsx
index 46d88e7b0d..fa2c1b8b40 100644
--- a/web/stories/Footer.stories.tsx
+++ b/web/components/ui/Footer/Footer.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import Footer from '../components/ui/Footer/Footer';
+import Footer from './Footer';
export default {
title: 'owncast/Layout/Footer',
diff --git a/web/stories/Header.stories.tsx b/web/components/ui/Header/Header.stories.tsx
similarity index 92%
rename from web/stories/Header.stories.tsx
rename to web/components/ui/Header/Header.stories.tsx
index 5df26c8e94..3f912ad98f 100644
--- a/web/stories/Header.stories.tsx
+++ b/web/components/ui/Header/Header.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import Header from '../components/ui/Header/Header';
+import Header from './Header';
export default {
title: 'owncast/Layout/Header',
diff --git a/web/stories/Modal.stories.tsx b/web/components/ui/Modal/Modal.stories.tsx
similarity index 94%
rename from web/stories/Modal.stories.tsx
rename to web/components/ui/Modal/Modal.stories.tsx
index 05eb6c209b..88f42ae73a 100644
--- a/web/stories/Modal.stories.tsx
+++ b/web/components/ui/Modal/Modal.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import Modal from '../components/ui/Modal/Modal';
+import Modal from './Modal';
export default {
title: 'owncast/Modals/Container',
diff --git a/web/stories/NotifyReminder.stories.tsx b/web/components/ui/NotifyReminderPopup/NotifyReminderPopup.stories.tsx
similarity index 74%
rename from web/stories/NotifyReminder.stories.tsx
rename to web/components/ui/NotifyReminderPopup/NotifyReminderPopup.stories.tsx
index 3729f4c506..89fe557820 100644
--- a/web/stories/NotifyReminder.stories.tsx
+++ b/web/components/ui/NotifyReminderPopup/NotifyReminderPopup.stories.tsx
@@ -1,20 +1,20 @@
/* eslint-disable no-alert */
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import NotifyReminder from '../components/ui/NotifyReminderPopup/NotifyReminderPopup';
-import Mock from './assets/mocks/notify-popup.png';
+import NotifyReminderPopup from './NotifyReminderPopup';
+import Mock from '../../../stories/assets/mocks/notify-popup.png';
const Example = args => (
-
+
-
+
);
export default {
title: 'owncast/Components/Notify Reminder',
- component: NotifyReminder,
+ component: NotifyReminderPopup,
parameters: {
design: {
type: 'image',
@@ -27,9 +27,9 @@ Clicking it will make the notification modal display. Clicking the "X" will hide
},
},
},
-} as ComponentMeta;
+} as ComponentMeta;
-const Template: ComponentStory = args => ;
+const Template: ComponentStory = args => ;
export const Active = Template.bind({});
Active.args = {
diff --git a/web/stories/OfflineBanner.stories.tsx b/web/components/ui/OfflineBanner/OfflineBanner.stories.tsx
similarity index 88%
rename from web/stories/OfflineBanner.stories.tsx
rename to web/components/ui/OfflineBanner/OfflineBanner.stories.tsx
index e249cc76ff..ab79017b8d 100644
--- a/web/stories/OfflineBanner.stories.tsx
+++ b/web/components/ui/OfflineBanner/OfflineBanner.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import OfflineBanner from '../components/ui/OfflineBanner/OfflineBanner';
-import OfflineState from './assets/mocks/offline-state.png';
+import OfflineBanner from './OfflineBanner';
+import OfflineState from '../../../stories/assets/mocks/offline-state.png';
export default {
title: 'owncast/Layout/Offline Banner',
diff --git a/web/stories/SocialLinks.stories.tsx b/web/components/ui/SocialLinks/SocialLinks.stories.tsx
similarity index 93%
rename from web/stories/SocialLinks.stories.tsx
rename to web/components/ui/SocialLinks/SocialLinks.stories.tsx
index ffc48d5599..ecc3f78c1e 100644
--- a/web/stories/SocialLinks.stories.tsx
+++ b/web/components/ui/SocialLinks/SocialLinks.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import SocialLinks from '../components/ui/SocialLinks/SocialLinks';
+import SocialLinks from './SocialLinks';
export default {
title: 'owncast/Components/Social links',
diff --git a/web/stories/StatusBar.stories.tsx b/web/components/ui/Statusbar/StatusBar.stories.tsx
similarity index 90%
rename from web/stories/StatusBar.stories.tsx
rename to web/components/ui/Statusbar/StatusBar.stories.tsx
index ac544a49bd..09fcd6e0da 100644
--- a/web/stories/StatusBar.stories.tsx
+++ b/web/components/ui/Statusbar/StatusBar.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { subHours } from 'date-fns';
-import Statusbar from '../components/ui/Statusbar/Statusbar';
+import Statusbar from './Statusbar';
export default {
title: 'owncast/Player/Status bar',
diff --git a/web/components/ui/followers/FollowerCollection/FollowerCollection.module.scss b/web/components/ui/followers/FollowerCollection/FollowerCollection.module.scss
new file mode 100644
index 0000000000..9bb895045c
--- /dev/null
+++ b/web/components/ui/followers/FollowerCollection/FollowerCollection.module.scss
@@ -0,0 +1,3 @@
+.followers {
+ width: 100%;
+}
diff --git a/web/stories/Followercollection.stories.tsx b/web/components/ui/followers/FollowerCollection/FollowerCollection.stories.tsx
similarity index 98%
rename from web/stories/Followercollection.stories.tsx
rename to web/components/ui/followers/FollowerCollection/FollowerCollection.stories.tsx
index 095ed84f1d..46a20d6fde 100644
--- a/web/stories/Followercollection.stories.tsx
+++ b/web/components/ui/followers/FollowerCollection/FollowerCollection.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import FollowerCollection from '../components/ui/Followers/FollowersCollection';
+import FollowerCollection from './FollowerCollection';
export default {
title: 'owncast/Components/Followers/Followers collection',
diff --git a/web/components/ui/Followers/FollowersCollection.tsx b/web/components/ui/followers/FollowerCollection/FollowerCollection.tsx
similarity index 88%
rename from web/components/ui/Followers/FollowersCollection.tsx
rename to web/components/ui/followers/FollowerCollection/FollowerCollection.tsx
index 484c5fb9af..1348e05194 100644
--- a/web/components/ui/Followers/FollowersCollection.tsx
+++ b/web/components/ui/followers/FollowerCollection/FollowerCollection.tsx
@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react';
import { Col, Pagination, Row } from 'antd';
-import { Follower } from '../../../interfaces/follower';
-import SingleFollower from './Follower';
-import s from './Followers.module.scss';
+import { Follower } from '../../../../interfaces/follower';
+import SingleFollower from '../SingleFollower/SingleFollower';
+import s from '../SingleFollower/SingleFollower.module.scss';
export default function FollowerCollection() {
const ENDPOINT = '/api/followers';
diff --git a/web/components/ui/Followers/Followers.module.scss b/web/components/ui/followers/SingleFollower/SingleFollower.module.scss
similarity index 94%
rename from web/components/ui/Followers/Followers.module.scss
rename to web/components/ui/followers/SingleFollower/SingleFollower.module.scss
index 08e6f32ac0..76515c5f12 100644
--- a/web/components/ui/Followers/Followers.module.scss
+++ b/web/components/ui/followers/SingleFollower/SingleFollower.module.scss
@@ -31,7 +31,3 @@
height: 100%;
}
}
-
-.followers {
- width: 100%;
-}
diff --git a/web/stories/Follower.stories.tsx b/web/components/ui/followers/SingleFollower/SingleFollower.stories.tsx
similarity index 85%
rename from web/stories/Follower.stories.tsx
rename to web/components/ui/followers/SingleFollower/SingleFollower.stories.tsx
index 236b2129dc..03cf1260b4 100644
--- a/web/stories/Follower.stories.tsx
+++ b/web/components/ui/followers/SingleFollower/SingleFollower.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import SingleFollower from '../components/ui/Followers/Follower';
-import SingleFollowerMock from './assets/mocks/single-follower.png';
+import SingleFollower from './SingleFollower';
+import SingleFollowerMock from '../../../../stories/assets/mocks/single-follower.png';
export default {
title: 'owncast/Components/Followers/Single Follower',
diff --git a/web/components/ui/Followers/Follower.tsx b/web/components/ui/followers/SingleFollower/SingleFollower.tsx
similarity index 87%
rename from web/components/ui/Followers/Follower.tsx
rename to web/components/ui/followers/SingleFollower/SingleFollower.tsx
index 3625939751..cd487ed718 100644
--- a/web/components/ui/Followers/Follower.tsx
+++ b/web/components/ui/followers/SingleFollower/SingleFollower.tsx
@@ -1,7 +1,7 @@
import { Avatar, Col, Row } from 'antd';
import React from 'react';
-import { Follower } from '../../../interfaces/follower';
-import s from './Followers.module.scss';
+import { Follower } from '../../../../interfaces/follower';
+import s from './SingleFollower.module.scss';
interface Props {
follower: Follower;
diff --git a/web/components/user-popover.tsx b/web/components/user-popover.tsx
index 8ea49f3d46..f0afe436e4 100644
--- a/web/components/user-popover.tsx
+++ b/web/components/user-popover.tsx
@@ -6,7 +6,7 @@ import formatDistanceToNow from 'date-fns/formatDistanceToNow';
import format from 'date-fns/format';
import { uniq } from 'lodash';
-import BlockUserbutton from './ban-user-button';
+import BlockUserbutton from './other/ban-user-button/ban-user-button';
import ModeratorUserbutton from './moderator-user-button';
import { User, UserConnectionInfo } from '../types/chat';
diff --git a/web/components/user-table.tsx b/web/components/user-table.tsx
index e46ac63dac..723fcd92ef 100644
--- a/web/components/user-table.tsx
+++ b/web/components/user-table.tsx
@@ -3,7 +3,7 @@ import format from 'date-fns/format';
import { SortOrder } from 'antd/lib/table/interface';
import { User } from '../types/chat';
import UserPopover from './user-popover';
-import BanUserButton from './ban-user-button';
+import BanUserButton from './other/ban-user-button/ban-user-button';
export function formatDisplayDate(date: string | Date) {
return format(new Date(date), 'MMM d H:mma');
diff --git a/web/stories/Video.stories.tsx b/web/components/video/OwncastPlayer/OwncastPlayer.stories.tsx
similarity index 93%
rename from web/stories/Video.stories.tsx
rename to web/components/video/OwncastPlayer/OwncastPlayer.stories.tsx
index 7f55594de7..7e40158796 100644
--- a/web/stories/Video.stories.tsx
+++ b/web/components/video/OwncastPlayer/OwncastPlayer.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { RecoilRoot } from 'recoil';
-import OwncastPlayer from '../components/video/OwncastPlayer';
+import OwncastPlayer from './OwncastPlayer';
const streams = {
DemoServer: `https://watch.owncast.online/hls/stream.m3u8`,
diff --git a/web/components/video/OwncastPlayer.tsx b/web/components/video/OwncastPlayer/OwncastPlayer.tsx
similarity index 94%
rename from web/components/video/OwncastPlayer.tsx
rename to web/components/video/OwncastPlayer/OwncastPlayer.tsx
index 1646d48c3e..d45b47dcf4 100644
--- a/web/components/video/OwncastPlayer.tsx
+++ b/web/components/video/OwncastPlayer/OwncastPlayer.tsx
@@ -1,14 +1,14 @@
import React, { useEffect } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useHotkeys } from 'react-hotkeys-hook';
-import VideoJS from './player';
-import ViewerPing from './viewer-ping';
-import VideoPoster from './VideoPoster';
-import { getLocalStorage, setLocalStorage } from '../../utils/localStorage';
-import { isVideoPlayingAtom, clockSkewAtom } from '../stores/ClientConfigStore';
-import PlaybackMetrics from './metrics/playback';
-import createVideoSettingsMenuButton from './settings-menu';
-import LatencyCompensator from './latencyCompensator';
+import VideoJS from '../player';
+import ViewerPing from '../viewer-ping';
+import VideoPoster from '../VideoPoster/VideoPoster';
+import { getLocalStorage, setLocalStorage } from '../../../utils/localStorage';
+import { isVideoPlayingAtom, clockSkewAtom } from '../../stores/ClientConfigStore';
+import PlaybackMetrics from '../metrics/playback';
+import createVideoSettingsMenuButton from '../settings-menu';
+import LatencyCompensator from '../latencyCompensator';
const VIDEO_CONFIG_URL = '/api/video/variants';
const PLAYER_VOLUME = 'owncast_volume';
diff --git a/web/components/video/VideoPoster.module.scss b/web/components/video/VideoPoster/VideoPoster.module.scss
similarity index 100%
rename from web/components/video/VideoPoster.module.scss
rename to web/components/video/VideoPoster/VideoPoster.module.scss
diff --git a/web/stories/VideoPoster.stories.tsx b/web/components/video/VideoPoster/VideoPoster.stories.tsx
similarity index 95%
rename from web/stories/VideoPoster.stories.tsx
rename to web/components/video/VideoPoster/VideoPoster.stories.tsx
index 1515e1abe6..dd5442ef62 100644
--- a/web/stories/VideoPoster.stories.tsx
+++ b/web/components/video/VideoPoster/VideoPoster.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import VideoPoster from '../components/video/VideoPoster';
+import VideoPoster from './VideoPoster';
export default {
title: 'owncast/Player/Video poster',
diff --git a/web/components/video/VideoPoster.tsx b/web/components/video/VideoPoster/VideoPoster.tsx
similarity index 93%
rename from web/components/video/VideoPoster.tsx
rename to web/components/video/VideoPoster/VideoPoster.tsx
index 988fef99a0..3761613549 100644
--- a/web/components/video/VideoPoster.tsx
+++ b/web/components/video/VideoPoster/VideoPoster.tsx
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
-import CrossfadeImage from '../ui/CrossfadeImage/CrossfadeImage';
+import CrossfadeImage from '../../ui/CrossfadeImage/CrossfadeImage';
import s from './VideoPoster.module.scss';
const REFRESH_INTERVAL = 20_000;
diff --git a/web/pages/embed/video/index.tsx b/web/pages/embed/video/index.tsx
index 4d4a6e8b6e..1adf6cce89 100644
--- a/web/pages/embed/video/index.tsx
+++ b/web/pages/embed/video/index.tsx
@@ -8,7 +8,7 @@ import {
} from '../../../components/stores/ClientConfigStore';
import OfflineBanner from '../../../components/ui/OfflineBanner/OfflineBanner';
import Statusbar from '../../../components/ui/Statusbar/Statusbar';
-import OwncastPlayer from '../../../components/video/OwncastPlayer';
+import OwncastPlayer from '../../../components/video/OwncastPlayer/OwncastPlayer';
import { ClientConfig } from '../../../interfaces/client-config.model';
import { ServerStatus } from '../../../interfaces/server-status.model';
diff --git a/web/stories/preview.scss b/web/stories/preview.scss
deleted file mode 100644
index 0b9b1cbb33..0000000000
--- a/web/stories/preview.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import '../styles/globals.scss';
-@import '../styles/ant-overrides.scss';