diff --git a/src/client/webapp/actions.ts b/src/client/webapp/actions.ts
index d157933..f2cc076 100644
--- a/src/client/webapp/actions.ts
+++ b/src/client/webapp/actions.ts
@@ -20,27 +20,4 @@ export default class Actions {
ui.setActiveConnection(guild, { id: null, avatarResourceId: null, displayName: 'Error', status: 'Error', privileges: [], roleName: null, roleColor: null, rolePriority: null });
}
}
-
- static async fetchAndUpdateChannels(q: Q, ui: UI, guild: CombinedGuild) {
- await Util.withPotentialErrorWarnOnCancel(q, {
- taskFunc: async () => {
- if (ui.activeGuild === null || ui.activeGuild.id !== guild.id) return;
- const channels = await guild.fetchChannels();
- await ui.setChannels(guild, channels);
- if (ui.activeGuild === null || ui.activeGuild.id !== guild.id) return;
- if (ui.activeChannel === null) {
- // click on the first channel in the list if no channel is active yet
- const element = q.$_('#channel-list .channel');
- if (element) {
- element.click();
- }
- }
- },
- errorIndicatorAddFunc: async (errorIndicatorElement) => {
- await ui.setChannelsErrorIndicator(guild, errorIndicatorElement);
- },
- errorContainer: q.$('#channel-list'),
- errorMessage: 'Error fetching channels'
- });
- }
}
diff --git a/src/client/webapp/elements/channel.tsx b/src/client/webapp/elements/channel.tsx
deleted file mode 100644
index a1ab02b..0000000
--- a/src/client/webapp/elements/channel.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import React from 'react';
-import ReactHelper from './require/react-helper';
-
-import ElementsUtil from './require/elements-util';
-import BaseElements from './require/base-elements';
-import { Channel } from '../data-types';
-import UI from '../ui';
-import Q from '../q-module';
-import CombinedGuild from '../guild-combined';
-import ChannelOverlay from './overlays/overlay-channel';
-
-export default function createChannel(document: Document, q: Q, ui: UI, guild: CombinedGuild, channel: Channel) {
- const element = ReactHelper.createElementFromJSX(
-
-
{BaseElements.TEXT_CHANNEL_ICON}
-
{channel.name}
-
{BaseElements.COG}
-
- );
-
- element.addEventListener('click', async () => {
- if (element.classList.contains('active')) return;
- await ui.setActiveChannel(guild, channel);
- q.$('#text-input').focus();
- });
-
- const modifyContextElement = q.create({ class: 'context', content: {
- class: 'above', content: [
- { class: 'content text', content: 'Modify Channel' },
- { class: 'tab', content: BaseElements.Q_TAB_BELOW }
- ]
- }}) as HTMLElement;
-
- q.$$$(element, '.modify').addEventListener('click', async (e) => {
- e.stopPropagation();
- if (modifyContextElement.parentElement) {
- modifyContextElement.parentElement.removeChild(modifyContextElement);
- }
- ElementsUtil.presentReactOverlay(document, );
- });
-
- q.$$$(element, '.modify').addEventListener('mouseenter', () => {
- document.body.appendChild(modifyContextElement);
- ElementsUtil.alignContextElement(modifyContextElement, q.$$$(element, '.modify'), { bottom: 'top', centerX: 'centerX' });
- });
-
- q.$$$(element, '.modify').addEventListener('mouseleave', () => {
- if (modifyContextElement.parentElement) {
- modifyContextElement.parentElement.removeChild(modifyContextElement);
- }
- });
-
- return element;
-}
diff --git a/src/client/webapp/elements/context-menus/components/context-menu.tsx b/src/client/webapp/elements/context-menus/components/context-menu.tsx
deleted file mode 100644
index cece528..0000000
--- a/src/client/webapp/elements/context-menus/components/context-menu.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import React, { FC, ReactNode, RefObject, useEffect, useMemo, useRef, useState } from 'react';
-import { ShouldNeverHappenError } from '../../../data-types';
-import ElementsUtil, { IAlignment } from '../../require/elements-util';
-import ReactHelper from '../../require/react-helper';
-
-export interface ContextMenuProps {
- relativeToRef?: RefObject;
- relativeToPos?: { x: number, y: number };
- alignment: IAlignment;
- children: ReactNode;
- close: () => void;
-}
-
-const ContextMenu: FC = (props: ContextMenuProps) => {
- const { relativeToRef, relativeToPos, alignment, children, close } = props;
-
- const rootRef = useRef(null);
-
- const [ aligned, setAligned ] = useState(false);
-
- ReactHelper.useCloseWhenClickedOutsideEffect(rootRef, close);
-
- useEffect(() => {
- if (!rootRef.current) return;
- const relativeTo = (relativeToRef && relativeToRef.current) ?? relativeToPos ?? null;
- if (!relativeTo) throw new ShouldNeverHappenError('invalid context menu props');
- ElementsUtil.alignContextElement(rootRef.current, relativeTo, alignment);
- setAligned(true);
- }, [ rootRef, relativeToRef, relativeToPos ]);
-
- const contextClass = useMemo(() => {
- return 'context react' + (aligned ? ' aligned' : '');
- }, [ aligned ]);
-
- return (
-
- );
-}
-
-export default ContextMenu;
diff --git a/src/client/webapp/elements/contexts/components/context-menu.tsx b/src/client/webapp/elements/contexts/components/context-menu.tsx
new file mode 100644
index 0000000..3cfc238
--- /dev/null
+++ b/src/client/webapp/elements/contexts/components/context-menu.tsx
@@ -0,0 +1,31 @@
+import React, { FC, ReactNode, RefObject, useRef } from 'react'
+import { IAlignment } from '../../require/elements-util';
+import ReactHelper from '../../require/react-helper';
+import Context from './context';
+
+export interface ContextMenuProps {
+ relativeToRef?: RefObject;
+ relativeToPos?: { x: number, y: number };
+ alignment: IAlignment;
+ children: ReactNode;
+ close: () => void;
+}
+
+// Automatically closes when clicked outside of and includes a