diff --git a/src/equicordplugins/translatePlus/index.tsx b/src/equicordplugins/translatePlus/index.tsx
index c7a73165..3eb882d5 100644
--- a/src/equicordplugins/translatePlus/index.tsx
+++ b/src/equicordplugins/translatePlus/index.tsx
@@ -18,19 +18,16 @@
 
 import "./style.css";
 
-import { addChatBarButton, removeChatBarButton } from "@api/ChatButtons";
 import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
 import { addAccessory, removeAccessory } from "@api/MessageAccessories";
-import { addPreSendListener, removePreSendListener } from "@api/MessageEvents";
 import { addButton, removeButton } from "@api/MessagePopover";
 import { Devs, EquicordDevs } from "@utils/constants";
 import definePlugin from "@utils/types";
 import { ChannelStore, Menu } from "@webpack/common";
 
 import { settings } from "./settings";
-import { translate } from "./utils/misc";
-import { TranslateChatBarIcon, TranslateIcon } from "./utils/TranslateIcon";
-import { handleTranslate, TranslationAccessory } from "./utils/TranslationAccessory";
+import { Accessory, handleTranslate } from "./utils/accessory";
+import { Icon } from "./utils/icon";
 
 const messageCtxPatch: NavContextMenuPatchCallback = (children, { message }) => {
     if (!message.content) return;
@@ -40,61 +37,37 @@ const messageCtxPatch: NavContextMenuPatchCallback = (children, { message }) =>
 
     group.splice(group.findIndex(c => c?.props?.id === "copy-text") + 1, 0, (
         <Menu.MenuItem
-            id="vc-trans"
+            id="ec-trans"
             label="Translate"
-            icon={TranslateIcon}
-            action={async () => {
-                const trans = await translate("received", message.content);
-                handleTranslate(message.id, trans);
-            }}
+            icon={Icon}
+            action={() => handleTranslate(message)}
         />
     ));
 };
 
 export default definePlugin({
     name: "Translate+",
-    description: "Translate messages with Google Translate and Toki Pona AI",
+    description: "Vencord's translate plugin but with support for artistic languages!",
+    dependencies: ["MessageAccessoriesAPI"],
     authors: [Devs.Ven, EquicordDevs.Prince527],
-    dependencies: ["MessageAccessoriesAPI", "MessagePopoverAPI", "MessageEventsAPI", "ChatInputButtonAPI"],
     settings,
     contextMenus: {
         "message": messageCtxPatch
     },
-    // not used, just here in case some other plugin wants it or w/e
-    translate,
 
     start() {
-        addAccessory("vc-translation", props => <TranslationAccessory message={props.message} />);
+        addAccessory("ec-translation", props => <Accessory message={props.message} />);
 
-        addChatBarButton("vc-translate", TranslateChatBarIcon);
-
-        addButton("vc-translate", message => {
-            if (!message.content) return null;
-
-            return {
-                label: "Translate",
-                icon: TranslateIcon,
-                message,
-                channel: ChannelStore.getChannel(message.channel_id),
-                onClick: async () => {
-                    const trans = await translate("received", message.content);
-                    handleTranslate(message.id, trans);
-                }
-            };
-        });
-
-        this.preSend = addPreSendListener(async (_, message) => {
-            if (!settings.store.autoTranslate) return;
-            if (!message.content) return;
-
-            message.content = (await translate("sent", message.content)).text;
-        });
+        addButton("ec-translate", message => ({
+            label: "Translate",
+            icon: Icon,
+            message: message,
+            channel: ChannelStore.getChannel(message.channel_id),
+            onClick: () => handleTranslate(message),
+        }));
     },
-
     stop() {
-        removePreSendListener(this.preSend);
-        removeChatBarButton("vc-translate");
-        removeButton("vc-translate");
-        removeAccessory("vc-translation");
-    },
+        removeButton("ec-translate");
+        removeAccessory("ec-translation");
+    }
 });
diff --git a/src/equicordplugins/translatePlus/misc/languages.ts b/src/equicordplugins/translatePlus/misc/languages.ts
index 75454f59..20b0448d 100644
--- a/src/equicordplugins/translatePlus/misc/languages.ts
+++ b/src/equicordplugins/translatePlus/misc/languages.ts
@@ -31,9 +31,9 @@ copy(Object.fromEntries(
 ))
 */
 
-export type Language = keyof typeof Languages;
+export type languages = keyof typeof languages;
 
-export const Languages = {
+export const languages = {
     "auto": "Detect language",
     "af": "Afrikaans",
     "sq": "Albanian",
@@ -68,6 +68,7 @@ export const Languages = {
     "ee": "Ewe",
     "tl": "Filipino",
     "tp": "Toki Pona",
+    "sh": "Shavian",
     "fi": "Finnish",
     "fr": "French",
     "fy": "Frisian",
diff --git a/src/equicordplugins/translatePlus/misc/types.ts b/src/equicordplugins/translatePlus/misc/types.ts
new file mode 100644
index 00000000..dde38179
--- /dev/null
+++ b/src/equicordplugins/translatePlus/misc/types.ts
@@ -0,0 +1,19 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { classNameFactory } from "@api/Styles";
+
+export const cl = classNameFactory("eq-trans-");
+
+export interface Translation {
+    text: string;
+    src: string;
+}
+
+export type IconProps = {
+    width?: number;
+    height?: number;
+};
diff --git a/src/equicordplugins/translatePlus/settings.ts b/src/equicordplugins/translatePlus/settings.ts
index 17e386f3..3fd2f030 100644
--- a/src/equicordplugins/translatePlus/settings.ts
+++ b/src/equicordplugins/translatePlus/settings.ts
@@ -1,69 +1,35 @@
 /*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2023 Vendicated and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
-*/
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
 
 import { definePluginSettings } from "@api/Settings";
 import { OptionType } from "@utils/types";
 
 export const settings = definePluginSettings({
-    receivedInput: {
+    target: {
         type: OptionType.STRING,
-        description: "Input language for received messages",
-        default: "auto",
-        hidden: true
-    },
-    receivedOutput: {
-        type: OptionType.STRING,
-        description: "Output language for received messages",
+        description: "Target language",
         default: "en",
-        hidden: true
+        restartNeeded: true
     },
-    sentInput: {
-        type: OptionType.STRING,
-        description: "Input language for sent messages",
-        default: "auto",
-        hidden: true
-    },
-    sentOutput: {
-        type: OptionType.STRING,
-        description: "Output language for sent messages",
-        default: "en",
-        hidden: true
-    },
-    autoTranslate: {
+    toki: {
         type: OptionType.BOOLEAN,
-        description: "Automatically translate your messages before sending. You can also shift/right click the translate button to toggle this",
-        default: false
+        description: "Enable Toki Pona",
+        default: true,
+        restartNeeded: true
     },
-    showChatBarButton: {
+    sitelen: {
         type: OptionType.BOOLEAN,
-        description: "Show translate button in chat bar",
-        default: true
+        description: "Enable Sitelen Pona",
+        default: true,
+        restartNeeded: true
     },
-    tokiPonaAPI: {
-        type: OptionType.STRING,
-        description: "An API to translate messages to Toki Pona",
-        default: "https://aiapi.serversmp.xyz/toki"
-    },
-    tokiPonaAuth: {
-        type: OptionType.STRING,
-        description: "An API key to use with the Toki Pona API",
-        default: ""
+    shavian: {
+        type: OptionType.BOOLEAN,
+        description: "Enable Shavian",
+        default: true,
+        restartNeeded: true
     }
-}).withPrivateSettings<{
-    showAutoTranslateAlert: boolean;
-}>();
+});
diff --git a/src/equicordplugins/translatePlus/style.css b/src/equicordplugins/translatePlus/style.css
index e9085b4e..e81dad64 100644
--- a/src/equicordplugins/translatePlus/style.css
+++ b/src/equicordplugins/translatePlus/style.css
@@ -1,41 +1,20 @@
-.vc-trans-modal-content {
-    padding: 1em;
-}
-
-.vc-trans-modal-header {
-    justify-content: space-between;
-    align-content: center;
-}
-
-.vc-trans-modal-header h1 {
-    margin: 0;
-}
-
-.vc-trans-accessory {
+.eq-trans-accessory {
     color: var(--text-muted);
     margin-top: 0.5em;
     font-style: italic;
     font-weight: 400;
 }
 
-.vc-trans-accessory svg {
+.eq-trans-accessory svg {
     margin-right: 0.25em;
 }
 
-.vc-trans-dismiss {
+.eq-trans-dismiss {
     all: unset;
     cursor: pointer;
     color: var(--text-link);
 }
 
-.vc-trans-dismiss:is(:hover, :focus) {
+.eq-trans-dismiss:is(:hover, :focus) {
     text-decoration: underline;
-}
-
-.vc-trans-auto-translate {
-    color: var(--green-360);
-}
-
-.vc-trans-chat-button {
-    scale: 1.085;
-}
+}
\ No newline at end of file
diff --git a/src/equicordplugins/translatePlus/utils/TranslateIcon.tsx b/src/equicordplugins/translatePlus/utils/TranslateIcon.tsx
deleted file mode 100644
index e8171ccb..00000000
--- a/src/equicordplugins/translatePlus/utils/TranslateIcon.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2023 Vendicated and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
-*/
-
-import { ChatBarButton } from "@api/ChatButtons";
-import { Margins } from "@utils/margins";
-import { classes } from "@utils/misc";
-import { openModal } from "@utils/modal";
-import { Alerts, Forms } from "@webpack/common";
-
-import { settings } from "../settings";
-import { cl } from "./misc";
-import { TranslateModal } from "./TranslateModal";
-
-export function TranslateIcon({ height = 24, width = 24, className }: { height?: number; width?: number; className?: string; }) {
-    return (
-        <svg
-            viewBox="0 96 960 960"
-            height={height}
-            width={width}
-            className={classes(cl("icon"), className)}
-        >
-            <path fill="currentColor" d="m475 976 181-480h82l186 480h-87l-41-126H604l-47 126h-82Zm151-196h142l-70-194h-2l-70 194Zm-466 76-55-55 204-204q-38-44-67.5-88.5T190 416h87q17 33 37.5 62.5T361 539q45-47 75-97.5T487 336H40v-80h280v-80h80v80h280v80H567q-22 69-58.5 135.5T419 598l98 99-30 81-127-122-200 200Z" />
-        </svg>
-    );
-}
-
-export const TranslateChatBarIcon: ChatBarButton = ({ isMainChat }) => {
-    const { autoTranslate, showChatBarButton } = settings.use(["autoTranslate", "showChatBarButton"]);
-
-    if (!isMainChat || !showChatBarButton) return null;
-
-    const toggle = () => {
-        const newState = !autoTranslate;
-        settings.store.autoTranslate = newState;
-        if (newState && settings.store.showAutoTranslateAlert !== false)
-            Alerts.show({
-                title: "Vencord Auto-Translate Enabled",
-                body: <>
-                    <Forms.FormText>
-                        You just enabled auto translate (by right clicking the Translate icon). Any message you send will automatically be translated before being sent.
-                    </Forms.FormText>
-                    <Forms.FormText className={Margins.top16}>
-                        If this was an accident, disable it again, or it will change your message content before sending.
-                    </Forms.FormText>
-                </>,
-                cancelText: "Disable Auto-Translate",
-                confirmText: "Got it",
-                secondaryConfirmText: "Don't show again",
-                onConfirmSecondary: () => settings.store.showAutoTranslateAlert = false,
-                onCancel: () => settings.store.autoTranslate = false
-            });
-    };
-
-    return (
-        <ChatBarButton
-            tooltip="Open Translate Modal"
-            onClick={e => {
-                if (e.shiftKey) return toggle();
-
-                openModal(props => (
-                    <TranslateModal rootProps={props} />
-                ));
-            }}
-            onContextMenu={() => toggle()}
-            buttonProps={{
-                "aria-haspopup": "dialog"
-            }}
-        >
-            <TranslateIcon className={cl({ "auto-translate": autoTranslate, "chat-button": true })} />
-        </ChatBarButton>
-    );
-};
diff --git a/src/equicordplugins/translatePlus/utils/TranslateModal.tsx b/src/equicordplugins/translatePlus/utils/TranslateModal.tsx
deleted file mode 100644
index 04cd1d7b..00000000
--- a/src/equicordplugins/translatePlus/utils/TranslateModal.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2023 Vendicated and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
-*/
-
-import { Margins } from "@utils/margins";
-import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot } from "@utils/modal";
-import { Forms, SearchableSelect, Switch, useMemo } from "@webpack/common";
-
-import { Languages } from "../misc/languages";
-import { settings } from "../settings";
-import { cl } from "./misc";
-
-const LanguageSettingKeys = ["receivedInput", "receivedOutput", "sentInput", "sentOutput"] as const;
-
-function LanguageSelect({ settingsKey, includeAuto }: { settingsKey: typeof LanguageSettingKeys[number]; includeAuto: boolean; }) {
-    const currentValue = settings.use([settingsKey])[settingsKey];
-
-    const options = useMemo(
-        () => {
-            const options = Object.entries(Languages).map(([value, label]) => ({ value, label }));
-            if (!includeAuto)
-                options.shift();
-
-            return options;
-        }, []
-    );
-
-    return (
-        <section className={Margins.bottom16}>
-            <Forms.FormTitle tag="h3">
-                {settings.def[settingsKey].description}
-            </Forms.FormTitle>
-
-            <SearchableSelect
-                options={options}
-                value={options.find(o => o.value === currentValue)}
-                placeholder={"Select a language"}
-                maxVisibleItems={5}
-                closeOnSelect={true}
-                onChange={v => settings.store[settingsKey] = v}
-            />
-        </section>
-    );
-}
-
-function AutoTranslateToggle() {
-    const value = settings.use(["autoTranslate"]).autoTranslate;
-
-    return (
-        <Switch
-            value={value}
-            onChange={v => settings.store.autoTranslate = v}
-            note={settings.def.autoTranslate.description}
-            hideBorder
-        >
-            Auto Translate
-        </Switch>
-    );
-}
-
-
-export function TranslateModal({ rootProps }: { rootProps: ModalProps; }) {
-    return (
-        <ModalRoot {...rootProps}>
-            <ModalHeader className={cl("modal-header")}>
-                <Forms.FormTitle tag="h2">
-                    Translate
-                </Forms.FormTitle>
-                <ModalCloseButton onClick={rootProps.onClose} />
-            </ModalHeader>
-
-            <ModalContent className={cl("modal-content")}>
-                {LanguageSettingKeys.map(s => (
-                    <LanguageSelect
-                        key={s}
-                        settingsKey={s}
-                        includeAuto={s.endsWith("Input")}
-                    />
-                ))}
-
-                <Forms.FormDivider className={Margins.bottom16} />
-
-                <AutoTranslateToggle />
-            </ModalContent>
-        </ModalRoot>
-    );
-}
diff --git a/src/equicordplugins/translatePlus/utils/TranslationAccessory.tsx b/src/equicordplugins/translatePlus/utils/TranslationAccessory.tsx
deleted file mode 100644
index 94778bc7..00000000
--- a/src/equicordplugins/translatePlus/utils/TranslationAccessory.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2023 Vendicated and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
-*/
-
-import { Parser, useEffect, useState } from "@webpack/common";
-import { Message } from "discord-types/general";
-
-import { Languages } from "../misc/languages";
-import { cl, TranslationValue } from "./misc";
-import { TranslateIcon } from "./TranslateIcon";
-
-const TranslationSetters = new Map<string, (v: TranslationValue) => void>();
-
-export function handleTranslate(messageId: string, data: TranslationValue) {
-    TranslationSetters.get(messageId)!(data);
-}
-
-function Dismiss({ onDismiss }: { onDismiss: () => void; }) {
-    return (
-        <button
-            onClick={onDismiss}
-            className={cl("dismiss")}
-        >
-            Dismiss
-        </button>
-    );
-}
-
-export function TranslationAccessory({ message }: { message: Message; }) {
-    const [translation, setTranslation] = useState<TranslationValue>();
-
-    useEffect(() => {
-        // Ignore MessageLinkEmbeds messages
-        if ((message as any).vencordEmbeddedBy) return;
-
-        TranslationSetters.set(message.id, setTranslation);
-
-        return () => void TranslationSetters.delete(message.id);
-    }, []);
-
-    if (!translation) return null;
-
-    return (
-        <span className={cl("accessory")}>
-            <TranslateIcon width={16} height={16} />
-            {Parser.parse(translation.text)}
-            {" "}
-            (translated from {Languages[translation.src] ?? translation.src} - <Dismiss onDismiss={() => setTranslation(undefined)} />)
-        </span>
-    );
-}
diff --git a/src/equicordplugins/translatePlus/utils/accessory.tsx b/src/equicordplugins/translatePlus/utils/accessory.tsx
new file mode 100644
index 00000000..7d473b19
--- /dev/null
+++ b/src/equicordplugins/translatePlus/utils/accessory.tsx
@@ -0,0 +1,42 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { Parser, useEffect, useState } from "@webpack/common";
+import { Message } from "discord-types/general";
+
+import { languages } from "../misc/languages";
+import { cl, Translation } from "../misc/types";
+import { Icon } from "./icon";
+import { translate } from "./translator";
+
+const setters = new Map();
+
+export function Accessory({ message }: { message: Message; }) {
+    const [translation, setTranslation] = useState<Translation | undefined>(undefined);
+
+    useEffect(() => {
+        if ((message as any).vencordEmbeddedBy) return;
+
+        setters.set(message.id, setTranslation);
+
+        return () => void setters.delete(message.id);
+    }, []);
+
+    if (!translation) return null;
+
+    return (
+        <span className={cl("accessory")}>
+            <Icon width={16} height={16} />
+            {Parser.parse(translation.text)}
+            {" "}
+            (translated from {languages[translation.src] ?? translation.src} - <button onClick={() => setTranslation(undefined)} className={cl("dismiss")}>Dismiss</button>)
+        </span>
+    );
+}
+
+export async function handleTranslate(message: Message) {
+    setters.get(message.id)!(await translate(message.content));
+}
diff --git a/src/equicordplugins/translatePlus/utils/icon.tsx b/src/equicordplugins/translatePlus/utils/icon.tsx
new file mode 100644
index 00000000..6c644e0b
--- /dev/null
+++ b/src/equicordplugins/translatePlus/utils/icon.tsx
@@ -0,0 +1,17 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { cl, IconProps } from "../misc/types";
+
+export function Icon({ width = 24, height = 24 }: IconProps) {
+    return (
+        <svg viewBox="0 96 960 960" height={width} width={height} className={cl("icon")}>
+            <path fill="currentColor" d="m475 976 181-480h82l186 480h-87l-41-126H604l-47 126h-82Zm151-196h142l-70-194h-2l-70 194Zm-466 76-55-55 204-204q-38-44-67.5-88.5T190 416h87q17 33 37.5 62.5T361 539q45-47 75-97.5T487 336H40v-80h280v-80h80v80h280v80H567q-22 69-58.5 135.5T419 598l98 99-30 81-127-122-200 200Z" />
+            <path fill="currentColor" d="m 830.17456,136.43701 c -11.54729,0 -20.84473,8.71252 -20.84473,19.53369 v 66.21826 h -66.21826 c -10.82122,0 -19.53369,9.29373 -19.53369,20.84107 0,11.54734 8.71247,20.84473 19.53369,20.84473 h 66.21826 v 66.21826 c 0,10.8212 9.29742,19.53369 20.84473,19.53369 11.54731,0 20.84106,-8.71249 20.84106,-19.53369 v -66.21826 h 66.21827 c 10.82124,0 19.53369,-9.29737 19.53369,-20.84473 0,-11.54736 -8.71245,-20.84107 -19.53369,-20.84107 H 851.01562 V 155.9707 c 0,-10.82117 -9.29377,-19.53369 -20.84106,-19.53369 z" />
+            <rect fill="currentColor" width="0.42110577" height="2.1055288" x="848.52814" y="112.42313" ry="0.2105529" />
+        </svg>
+    );
+}
diff --git a/src/equicordplugins/translatePlus/utils/misc.ts b/src/equicordplugins/translatePlus/utils/misc.ts
deleted file mode 100644
index bdb984b6..00000000
--- a/src/equicordplugins/translatePlus/utils/misc.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2023 Vendicated and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
-*/
-
-import { classNameFactory } from "@api/Styles";
-
-import { settings } from "../settings";
-
-export const cl = classNameFactory("vc-trans-");
-
-interface TranslationData {
-    src: string;
-    sentences: {
-        // 🏳️‍⚧️
-        trans: string;
-    }[];
-}
-
-export interface TranslationValue {
-    src: string;
-    text: string;
-}
-
-const dictonary = /\b(?:leko|weka|pan|lete|linja|lipu|suli|nimi|akesi|misikeke|selo|ike|sijelo|sona|lili|pimeja|ante|jo|loje|telo|walo|kijetesantakalu|kasi|waso|wile|utala|lukin|sina|lape|ma|pilin|jasima|la|olin|pipi|meso|lawa|pi|pakala|oko|tan|ken|jaki|unpa|esun|seme|sitelen|len|kule|soko|open|ala|tenpo|lon|sinpin|pini|kokosila|mama|musi|monsi|mewika|taso|ona|mun|kiwen|tomo|mute|mi|nena|palisa|meli|laso|wawa|ale|kipisi|kulupu|ilo|lupa|nanpa|en|mu|jelo|kili|tonsi|moku|ni|kama|pu|poki|monsuta|sin|lasina|poka|soweli|sewi|elena|epiku|moli|pona|lanpan|alasa|anu|kute|uta|luka|suno|sama|awen|namako|suwi|noka|seli|mije|sike|jan|pali|tawa|inli|nasa|mani|wan|insa|nijon|nasin|kalama|ijo|toki|anpa|kala|kepeken|ko|kon|pana|tu|supa|kin|usawi|yupekosi)\b/gm;
-
-function isTokiPona(string) {
-    const words = string.split(/\s+/);
-
-    const matches = string.match(dictonary) || [];
-
-    const percentage = (matches.length / words.length) * 100;
-
-    return percentage >= 50;
-}
-
-export async function translate(kind: "received" | "sent", text: string): Promise<TranslationValue> {
-    let output;
-
-    if (isTokiPona(text)) {
-        const [api, auth] = [settings.store.tokiPonaAPI, settings.store.tokiPonaAuth];
-
-        const translate = await (await fetch(api, {
-            method: "POST",
-            headers: {
-                "Accept": "application/json",
-                "Content-Type": "application/json",
-                "Authorization": `Basic ${auth}`
-            },
-            body: JSON.stringify({
-                text: text,
-                src: "tl",
-                target: "en"
-            })
-        })).json();
-
-        output = {
-            src: "tp",
-            text: translate.translation[0]
-        };
-    } else {
-        const [sourceLang, targetLang] = [settings.store[kind + "Input"], settings.store[kind + "Output"]];
-
-        const translate = await (await fetch(`https://translate.googleapis.com/translate_a/single?${new URLSearchParams({ client: "gtx", sl: sourceLang, tl: targetLang, dt: "t", dj: "1", source: "input", q: text })}`)).json();
-
-        output = {
-            src: translate.src,
-            text: translate.sentences.map(s => s.trans).filter(Boolean).join("")
-        };
-    }
-
-    return output;
-}
diff --git a/src/equicordplugins/translatePlus/utils/translator.ts b/src/equicordplugins/translatePlus/utils/translator.ts
new file mode 100644
index 00000000..4598909e
--- /dev/null
+++ b/src/equicordplugins/translatePlus/utils/translator.ts
@@ -0,0 +1,135 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 Vendicated and contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import { settings } from "../settings";
+
+function isTokiPona(text: string) {
+    const dictionary = /\b(?:leko|weka|pan|lete|linja|lipu|suli|nimi|akesi|misikeke|selo|ike|sijelo|sona|lili|pimeja|ante|jo|loje|telo|walo|kijetesantakalu|kasi|waso|wile|utala|lukin|sina|lape|ma|pilin|jasima|la|olin|pipi|meso|lawa|pi|pakala|oko|tan|ken|jaki|unpa|esun|seme|sitelen|len|kule|soko|open|ala|tenpo|lon|sinpin|pini|kokosila|mama|musi|monsi|mewika|taso|ona|mun|kiwen|tomo|mute|mi|nena|palisa|meli|laso|wawa|ale|kipisi|kulupu|ilo|lupa|nanpa|en|mu|jelo|kili|tonsi|moku|ni|kama|pu|poki|monsuta|sin|lasina|poka|soweli|sewi|elena|epiku|moli|pona|lanpan|alasa|anu|kute|uta|luka|suno|sama|awen|namako|suwi|noka|seli|mije|sike|jan|pali|tawa|inli|nasa|mani|wan|insa|nijon|nasin|kalama|ijo|toki|anpa|kala|kepeken|ko|kon|pana|tu|supa|kin|usawi|yupekosi)\b/gm;
+
+    return (text.match(dictionary) || []).length >= text.split(/\s+/).length * 0.5;
+}
+
+function isSitelen(text: string) {
+    const dictionary = /(?:󱤀|󱤁|󱤂|󱤃|󱤄|󱤅|󱤆|󱤇|󱤈|󱤉|󱤊|󱤋|󱤌|󱤍|󱤎|󱤏|󱤐|󱤑|󱤒|󱤓|󱤔|󱤕|󱤖|󱤗|󱤘|󱤙|󱤚|󱤛|󱤜|󱤝|󱤞|󱤟|󱤠|󱤡|󱤢|󱤣|󱤤|󱤥|󱤦|󱤧|󱤨|󱤩|󱤪|󱤫|󱤬|󱤭|󱤮|󱤯|󱤰|󱤱|󱤲|󱤳|󱤴|󱤵|󱤶|󱤷|󱤸|󱤹|󱤺|󱤻|󱤼|󱤽|󱤾|󱤿|󱥀|󱥁|󱥂|󱥃|󱥄|󱥅|󱥆|󱥇|󱥈|󱥉|󱥊|󱥋|󱥌|󱥍|󱥎|󱥏|󱥐|󱥑|󱥒|󱥓|󱥔|󱥕|󱥖|󱥗|󱥘|󱥙|󱥚|󱥛|󱥜|󱥝|󱥞|󱥟|󱥠|󱥡|󱥢|󱥣|󱥤|󱥥|󱥦|󱥧|󱥨|󱥩|󱥪|󱥫|󱥬|󱥭|󱥮|󱥯|󱥰|󱥱|󱥲|󱥳|󱥴|󱥵|󱥶|󱥷|󱦠|󱦡|󱦢|󱦣|󱥸|󱥹|󱥺|󱥻|󱥼|󱥽|󱥾|󱥿|󱦀|󱦁|󱦂|󱦃|󱦄|󱦅|󱦆|󱦇|󱦈|󱦐|󱦑|󱦒|󱦓|󱦔|󱦕|󱦖|󱦗|󱦘|󱦙|󱦚|󱦛|󱦜|󱦝)/gm;
+
+    return dictionary.test(text);
+}
+
+function isShavian(text: string) {
+    const shavianRegex = /[\u{10450}-\u{1047F}]+/u;
+
+    return shavianRegex.test(text);
+}
+
+async function translateShavian(message: string) {
+    const dictionary = await (await fetch("https://forkprince.github.io/TranslatePlus/shavian.json")).json();
+
+    const punctuationMap = {
+        '"': "\"",
+        "«": "\"",
+        "»": "\"",
+        ",": ",",
+        "!": "!",
+        "?": "?",
+        ".": ".",
+        "(": "(",
+        ")": ")",
+        "/": "/",
+        ";": ";",
+        ":": ":"
+    };
+
+    let translated = "";
+    const words = message.split(/\s+/);
+
+    for (let word of words) {
+        let punctuationBefore = "", punctuationAfter = "";
+
+        if (word[0] in punctuationMap) {
+            punctuationBefore = punctuationMap[word[0]];
+            word = word.slice(1);
+        }
+
+        if (word[word.length - 1] in punctuationMap) {
+            punctuationAfter = punctuationMap[word[word.length - 1]];
+            word = word.slice(0, -1);
+        }
+
+        translated += punctuationBefore;
+
+        if (word in dictionary) translated += dictionary[word];
+        else translated += word;
+
+        translated += punctuationAfter + " ";
+    }
+
+    return translated.trim();
+}
+
+async function translateSitelen(message: string) {
+    message = Array.from(message).join(" ");
+
+    const dictionary = await (await fetch("https://forkprince.github.io/TranslatePlus/sitelen-pona.json")).json();
+
+    const sorted = Object.keys(dictionary).sort((a, b) => b.length - a.length);
+
+    const pattern = new RegExp(`(${sorted.join("|")})`, "g");
+
+    const translate = message.replace(pattern, match => dictionary[match]);
+
+    return translate;
+}
+
+async function google(target: string, text: string) {
+    const translate = await (await fetch(`https://translate.googleapis.com/translate_a/single?${new URLSearchParams({ client: "gtx", sl: "auto", tl: target, dt: "t", dj: "1", source: "input", q: text })}`)).json();
+
+    return {
+        src: translate.src,
+        text: translate.sentences.map(s => s.trans).filter(Boolean).join("")
+    };
+}
+
+export async function translate(text: string): Promise<any> {
+    const { target, toki, sitelen, shavian } = settings.store;
+
+    const output = { src: "", text: "" };
+
+    if ((isTokiPona(text) || isSitelen(text)) && (toki || sitelen)) {
+        if (isSitelen(text) && sitelen) text = await translateSitelen(text);
+
+        console.log(text);
+
+        const translate = await (await fetch("https://aiapi.serversmp.xyz/toki", {
+            method: "POST",
+            headers: {
+                "Accept": "application/json",
+                "Content-Type": "application/json"
+            },
+            body: JSON.stringify({
+                text: text,
+                src: "tl",
+                target: "en"
+            })
+        })).json();
+
+        console.log(translate);
+
+        output.src = "tp";
+        output.text = target === "en" ? translate.translation[0] : (await google(target, translate.translation[0])).text;
+    } else if (isShavian(text) && shavian) {
+        const translate = await translateShavian(text);
+
+        output.src = "sh";
+        output.text = target === "en" ? translate : (await google(target, translate)).text;
+    } else {
+        const translate = await google(target, text);
+
+        output.src = translate.src;
+        output.text = translate.text;
+    }
+
+    return output;
+}