diff --git a/src/components/common/IconBase.tsx b/src/components/common/IconBase.tsx
index bebc0a8f8b23c57fa6d829af27c29c2358122207..acb5387ea9216d2af1346c8a955ab90fe2641662 100644
--- a/src/components/common/IconBase.tsx
+++ b/src/components/common/IconBase.tsx
@@ -14,6 +14,8 @@ interface IconModifiers {
 }
 
 export default styled.svg<IconModifiers>`
+    flex-shrink: 0;
+
     img {
         width: 100%;
         height: 100%;
@@ -26,6 +28,7 @@ export default styled.svg<IconModifiers>`
 `;
 
 export const ImageIconBase = styled.img<IconModifiers>`
+    flex-shrink: 0;
     object-fit: cover;
 
     ${ props => !props.square && css`
diff --git a/src/components/navigation/left/HomeSidebar.tsx b/src/components/navigation/left/HomeSidebar.tsx
index ac05418ee2dce6112568b7edf6ed0c5ee893b303..c0e657e0bbc1cd8601eb030254ee7260153c6716 100644
--- a/src/components/navigation/left/HomeSidebar.tsx
+++ b/src/components/navigation/left/HomeSidebar.tsx
@@ -1,5 +1,5 @@
 import { Localizer, Text } from "preact-i18n";
-import { useContext } from "preact/hooks";
+import { useContext, useEffect } from "preact/hooks";
 import { Home, Users, Tool, Save } from "@styled-icons/feather";
 
 import Category from '../../ui/Category';
@@ -10,6 +10,7 @@ import { connectState } from "../../../redux/connector";
 import ConnectionStatus from '../items/ConnectionStatus';
 import { WithDispatcher } from "../../../redux/reducers";
 import { Unreads } from "../../../redux/reducers/unreads";
+import ConditionalLink from "../../../lib/ConditionalLink";
 import { mapChannelWithUnread, useUnreads } from "./common";
 import { Users as UsersNS } from 'revolt.js/dist/api/objects';
 import ButtonItem, { ChannelButton } from '../items/ButtonItem';
@@ -37,6 +38,16 @@ function HomeSidebar(props: Props) {
     if (channel && !obj) return <Redirect to="/" />;
     if (obj) useUnreads({ ...props, channel: obj });
 
+    useEffect(() => {
+        if (!channel) return;
+
+        props.dispatcher({
+            type: 'LAST_OPENED_SET',
+            parent: 'home',
+            child: channel
+        });
+    }, [ channel ]);
+
     const channelsArr = channels
         .filter(x => x.channel_type !== 'SavedMessages')
         .map(x => mapChannelWithUnread(x, props.unreads));
@@ -55,13 +66,13 @@ function HomeSidebar(props: Props) {
             <GenericSidebarList>
                 {!isTouchscreenDevice && (
                     <>
-                        <Link to="/">
+                        <ConditionalLink active={pathname === "/"} to="/">
                             <ButtonItem active={pathname === "/"}>
                                 <Home size={20} />
                                 <span><Text id="app.navigation.tabs.home" /></span>
                             </ButtonItem>
-                        </Link>
-                        <Link to="/friends">
+                        </ConditionalLink>
+                        <ConditionalLink active={pathname === "/friends"} to="/friends">
                             <ButtonItem
                                 active={pathname === "/friends"}
                                 alert={
@@ -75,15 +86,15 @@ function HomeSidebar(props: Props) {
                                 <Users size={20} />
                                 <span><Text id="app.navigation.tabs.friends" /></span>
                             </ButtonItem>
-                        </Link>
+                        </ConditionalLink>
                     </>
                 )}
-                <Link to="/open/saved">
+                <ConditionalLink active={obj?.channel_type === "SavedMessages"} to="/open/saved">
                     <ButtonItem active={obj?.channel_type === "SavedMessages"}>
                         <Save size={20} />
                         <span><Text id="app.navigation.tabs.saved" /></span>
                     </ButtonItem>
-                </Link>
+                </ConditionalLink>
                 {import.meta.env.DEV && (
                     <Link to="/dev">
                         <ButtonItem active={pathname === "/dev"}>
@@ -115,7 +126,7 @@ function HomeSidebar(props: Props) {
                     }
                     
                     return (
-                        <Link to={`/channel/${x._id}`}>
+                        <ConditionalLink active={x._id === channel} to={`/channel/${x._id}`}>
                             <ChannelButton
                                 user={user}
                                 channel={x}
@@ -123,7 +134,7 @@ function HomeSidebar(props: Props) {
                                 alertCount={x.alertCount}
                                 active={x._id === channel}
                             />
-                        </Link>
+                        </ConditionalLink>
                     );
                 })}
                 <PaintCounter />
diff --git a/src/components/navigation/left/ServerListSidebar.tsx b/src/components/navigation/left/ServerListSidebar.tsx
index c7e2fc91836bb47bee83228de961d6907acfe7f3..4f25f7ddd37c6918440b2a3603f224d08a35be4a 100644
--- a/src/components/navigation/left/ServerListSidebar.tsx
+++ b/src/components/navigation/left/ServerListSidebar.tsx
@@ -8,9 +8,11 @@ import { PlusCircle } from "@styled-icons/feather";
 import PaintCounter from "../../../lib/PaintCounter";
 import { attachContextMenu } from 'preact-context-menu';
 import { connectState } from "../../../redux/connector";
+import { useLocation, useParams } from "react-router-dom";
 import { Unreads } from "../../../redux/reducers/unreads";
+import ConditionalLink from "../../../lib/ConditionalLink";
 import { Channel, Servers } from "revolt.js/dist/api/objects";
-import { Link, useLocation, useParams } from "react-router-dom";
+import { LastOpened } from "../../../redux/reducers/last_opened";
 import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
 import { useIntermediate } from "../../../context/intermediate/Intermediate";
 import { useChannels, useForceUpdate, useServers } from "../../../context/revoltjs/hooks";
@@ -104,9 +106,10 @@ const ServerEntry = styled.div<{ active: boolean, invert?: boolean }>`
 
 interface Props {
     unreads: Unreads;
+    lastOpened: LastOpened;
 }
 
-export function ServerListSidebar({ unreads }: Props) {
+export function ServerListSidebar({ unreads, lastOpened }: Props) {
     const ctx = useForceUpdate();
     const activeServers = useServers(undefined, ctx) as Servers.Server[];
     const channels = (useChannels(undefined, ctx) as Channel[])
@@ -148,31 +151,36 @@ export function ServerListSidebar({ unreads }: Props) {
     }
 
     if (alertCount > 0) homeUnread = 'mention';
+    const homeActive = typeof server === 'undefined' && !path.startsWith('/invite');
 
     return (
         <ServersBase>
             <ServerList>
-                <Link to={`/`}>
-                    <ServerEntry invert
-                        active={typeof server === 'undefined' && !path.startsWith('/invite')}>
+                <ConditionalLink active={homeActive} to={lastOpened.home ? `/channel/${lastOpened.home}` : '/'}>
+                    <ServerEntry invert active={homeActive}>
                         <Icon size={36} unread={homeUnread}>
                             <img src={logoSVG} />
                         </Icon>
                     </ServerEntry>
-                </Link>
+                </ConditionalLink>
                 <LineDivider />
                 {
-                    servers.map(entry =>
-                        <Link to={`/server/${entry!._id}`}>
-                            <ServerEntry
-                                active={entry!._id === server?._id}
-                                onContextMenu={attachContextMenu('Menu', { server: entry!._id })}>
-                                <Icon size={36} unread={entry.unread}>
-                                    <ServerIcon size={32} target={entry} />
-                                </Icon>
-                            </ServerEntry>
-                        </Link>
-                    )
+                    servers.map(entry => {
+                        const active = entry!._id === server?._id;
+                        const id = lastOpened[entry!._id];
+                        
+                        return (
+                            <ConditionalLink active={active} to={`/server/${entry!._id}` + (id ? `/channel/${id}` : '')}>
+                                <ServerEntry
+                                    active={active}
+                                    onContextMenu={attachContextMenu('Menu', { server: entry!._id })}>
+                                    <Icon size={36} unread={entry.unread}>
+                                        <ServerIcon size={32} target={entry} />
+                                    </Icon>
+                                </ServerEntry>
+                            </ConditionalLink>
+                        )
+                    })
                 }
                 <IconButton onClick={() => openScreen({ id: 'special_input', type: 'create_server' })}>
                     <PlusCircle size={36} />
@@ -187,7 +195,8 @@ export default connectState(
     ServerListSidebar,
     state => {
         return {
-            unreads: state.unreads
+            unreads: state.unreads,
+            lastOpened: state.lastOpened
         };
     }
 );
diff --git a/src/components/navigation/left/ServerSidebar.tsx b/src/components/navigation/left/ServerSidebar.tsx
index 03f175c351ff9cf2dacc173a9505433e0607d512..d987af1eef083561a8dc40347e2636a6ab098d47 100644
--- a/src/components/navigation/left/ServerSidebar.tsx
+++ b/src/components/navigation/left/ServerSidebar.tsx
@@ -15,6 +15,8 @@ import PaintCounter from "../../../lib/PaintCounter";
 import styled from "styled-components";
 import { attachContextMenu } from 'preact-context-menu';
 import ServerHeader from "../../common/ServerHeader";
+import { useEffect } from "preact/hooks";
+import ConditionalLink from "../../../lib/ConditionalLink";
 
 interface Props {
     unreads: Unreads;
@@ -51,24 +53,37 @@ function ServerSidebar(props: Props & WithDispatcher) {
         .map(x => mapChannelWithUnread(x, props.unreads));
     
     const channel = channels.find(x => x?._id === channel_id);
+    if (channel_id && !channel) return <Redirect to={`/server/${server_id}`} />;
     if (channel) useUnreads({ ...props, channel }, ctx);
 
+    useEffect(() => {
+        if (!channel_id) return;
+
+        props.dispatcher({
+            type: 'LAST_OPENED_SET',
+            parent: server_id!,
+            child: channel_id!
+        });
+    }, [ channel_id ]);
+
     return (
         <ServerBase>
             <ServerHeader server={server} ctx={ctx} />
             <ConnectionStatus />
             <ServerList onContextMenu={attachContextMenu('Menu', { server_list: server._id })}>
                 {channels.map(entry => {
+                    const active = channel?._id === entry._id;
+
                     return (
-                        <Link to={`/server/${server._id}/channel/${entry._id}`}>
+                        <ConditionalLink active={active} to={`/server/${server._id}/channel/${entry._id}`}>
                             <ChannelButton
                                 key={entry._id}
                                 channel={entry}
-                                active={channel?._id === entry._id}
+                                active={active}
                                 alert={entry.unread}
                                 compact
                             />
-                        </Link>
+                        </ConditionalLink>
                     );
                 })}
             </ServerList>
diff --git a/src/context/Settings.tsx b/src/context/Settings.tsx
index 92737e41f5187eed1dec8e4a6911c7b5f1838ca3..58e05deb220e21309d9690083867e5c436d2ef63 100644
--- a/src/context/Settings.tsx
+++ b/src/context/Settings.tsx
@@ -24,11 +24,9 @@ interface Props {
 }
 
 function Settings({ settings, children }: Props) {
-    console.info(settings.notification);
     const play = useMemo(() => {
         const enabled: SoundOptions = defaultsDeep(settings.notification ?? {}, DEFAULT_SOUNDS);
         return (sound: Sounds) => {
-            console.info('check if we can play sound', enabled[sound]);
             if (enabled[sound]) {
                 playSound(sound);
             }
diff --git a/src/lib/ConditionalLink.tsx b/src/lib/ConditionalLink.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b739219dcd380a3e7a47e1862841bcef5b7e6d9e
--- /dev/null
+++ b/src/lib/ConditionalLink.tsx
@@ -0,0 +1,15 @@
+import { Link, LinkProps } from "react-router-dom";
+
+type Props = LinkProps & JSX.HTMLAttributes<HTMLAnchorElement> & {
+    active: boolean
+};
+
+export default function ConditionalLink(props: Props) {
+    const { active, ...linkProps } = props;
+
+    if (active) {
+        return <a>{ props.children }</a>;
+    } else {
+        return <Link {...linkProps} />;
+    }
+}
diff --git a/src/pages/channels/actions/HeaderActions.tsx b/src/pages/channels/actions/HeaderActions.tsx
index 6916361bc4d1868b172211ca727c7c7213e7b4b0..368f603fc4c949c764973d7ce0976f1ffe0b18e2 100644
--- a/src/pages/channels/actions/HeaderActions.tsx
+++ b/src/pages/channels/actions/HeaderActions.tsx
@@ -35,7 +35,7 @@ export default function HeaderActions({ channel, toggleSidebar }: ChannelHeaderP
                 </>
             ) }
             <VoiceActions channel={channel} />
-            { channel.channel_type === "Group" && !isTouchscreenDevice && (
+            { (channel.channel_type === "Group" || channel.channel_type === "TextChannel") && !isTouchscreenDevice && (
                 <IconButton onClick={toggleSidebar}>
                     <SidebarIcon size={22} />
                 </IconButton>
diff --git a/src/pages/channels/messaging/MessageArea.tsx b/src/pages/channels/messaging/MessageArea.tsx
index 11cc849bc80747f54d7b94fa7e4f4ae72776b0ac..9753abcdc6821a0d1d4241a5ebcdf030b8aa0634 100644
--- a/src/pages/channels/messaging/MessageArea.tsx
+++ b/src/pages/channels/messaging/MessageArea.tsx
@@ -12,6 +12,7 @@ import { IntermediateContext } from "../../../context/intermediate/Intermediate"
 import { ClientStatus, StatusContext } from "../../../context/revoltjs/RevoltClient";
 import { useContext, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
 import { defer } from "../../../lib/defer";
+import { internalEmit } from "../../../lib/eventEmitter";
 
 const Area = styled.div`
     height: 100%;
@@ -246,6 +247,7 @@ export function MessageArea({ id }: Props) {
         function keyUp(e: KeyboardEvent) {
             if (e.key === "Escape" && !focusTaken) {
                 SingletonMessageRenderer.jumpToBottom(id, true);
+                internalEmit("TextArea", "focus", "message");
             }
         }
 
diff --git a/src/pages/channels/messaging/MessageEditor.tsx b/src/pages/channels/messaging/MessageEditor.tsx
index 3d93a7531a95f95bc6deb802c7906cdb064555b5..b46a10ab2c9899c830474dfd59a818d7613c36fa 100644
--- a/src/pages/channels/messaging/MessageEditor.tsx
+++ b/src/pages/channels/messaging/MessageEditor.tsx
@@ -1,9 +1,10 @@
 import styled from "styled-components";
-import { useContext, useState } from "preact/hooks";
+import { useContext, useEffect, useState } from "preact/hooks";
 import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
 import { MessageObject } from "../../../context/revoltjs/util";
 import { AppContext } from "../../../context/revoltjs/RevoltClient";
 import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
+import { IntermediateContext } from "../../../context/intermediate/Intermediate";
 
 const EditorBase = styled.div`
     display: flex;
@@ -38,6 +39,7 @@ interface Props {
 
 export default function MessageEditor({ message, finish }: Props) {
     const [ content, setContent ] = useState(message.content as string ?? '');
+    const { focusTaken } = useContext(IntermediateContext);
     const client = useContext(AppContext);
 
     async function save() {
@@ -55,6 +57,18 @@ export default function MessageEditor({ message, finish }: Props) {
         }
     }
 
+    // ? Stop editing when pressing ESC.
+    useEffect(() => {
+        function keyUp(e: KeyboardEvent) {
+            if (e.key === "Escape" && !focusTaken) {
+                finish();
+            }
+        }
+
+        document.body.addEventListener("keyup", keyUp);
+        return () => document.body.removeEventListener("keyup", keyUp);
+    }, [focusTaken]);
+
     return (
         <EditorBase>
             <TextAreaAutoSize
diff --git a/src/redux/index.ts b/src/redux/index.ts
index 6099d9e77480d71f2cad869d4e33f9055b43f250..33e6bbdca61960d7406ecfa865594b954db4cdb3 100644
--- a/src/redux/index.ts
+++ b/src/redux/index.ts
@@ -12,6 +12,7 @@ import { SyncOptions } from "./reducers/sync";
 import { Settings } from "./reducers/settings";
 import { QueuedMessage } from "./reducers/queue";
 import { ExperimentOptions } from "./reducers/experiments";
+import { LastOpened } from "./reducers/last_opened";
 
 export type State = {
     config: Core.RevoltNodeConfiguration,
@@ -24,6 +25,7 @@ export type State = {
     drafts: Drafts;
     sync: SyncOptions;
     experiments: ExperimentOptions;
+    lastOpened: LastOpened;
 };
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -51,6 +53,7 @@ store.subscribe(() => {
         drafts,
         sync,
         experiments,
+        lastOpened
     } = store.getState() as State;
 
     localForage.setItem("state", {
@@ -63,5 +66,6 @@ store.subscribe(() => {
         drafts,
         sync,
         experiments,
+        lastOpened
     });
 });
diff --git a/src/redux/reducers/index.ts b/src/redux/reducers/index.ts
index a5e81c65267ec5a0b36ce48b08d673f1ae25fb46..6c84f87fa76e405ad008e322275bc2e2bbecb620 100644
--- a/src/redux/reducers/index.ts
+++ b/src/redux/reducers/index.ts
@@ -11,6 +11,7 @@ import { typing, TypingAction } from "./typing";
 import { drafts, DraftAction } from "./drafts";
 import { sync, SyncAction } from "./sync";
 import { experiments, ExperimentsAction } from "./experiments";
+import { lastOpened, LastOpenedAction } from "./last_opened";
 
 export default combineReducers({
     config,
@@ -23,6 +24,7 @@ export default combineReducers({
     drafts,
     sync,
     experiments,
+    lastOpened
 });
 
 export type Action =
@@ -36,6 +38,7 @@ export type Action =
     | DraftAction
     | SyncAction
     | ExperimentsAction
+    | LastOpenedAction
     | { type: "__INIT"; state: State };
 
 export type WithDispatcher = { dispatcher: (action: Action) => void };
diff --git a/src/redux/reducers/last_opened.ts b/src/redux/reducers/last_opened.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0b29a156acba4cefe70d7aae7f653464184db98d
--- /dev/null
+++ b/src/redux/reducers/last_opened.ts
@@ -0,0 +1,29 @@
+export interface LastOpened {
+    [key: string]: string
+}
+
+export type LastOpenedAction =
+    | { type: undefined }
+    | {
+        type: "LAST_OPENED_SET";
+        parent: string;
+        child: string;
+      }
+    | {
+          type: "RESET";
+      };
+
+export function lastOpened(state = {} as LastOpened, action: LastOpenedAction): LastOpened {
+    switch (action.type) {
+        case "LAST_OPENED_SET": {
+            return {
+                ...state,
+                [action.parent]: action.child
+            }
+        }
+        case "RESET":
+            return {};
+        default:
+            return state;
+    }
+}