/**
 * @name MessagePeek
 * @version 1.2.7
 * @description See the last message in a Channel like on mobile
 * @author domi.btnr
 * @authorId 354191516979429376
 * @invite gp2ExK5vc7
 * @donate https://paypal.me/domibtnr
 * @source https://github.com/domi-btnr/BetterDiscordStuff/tree/development/MessagePeek
 */

'use strict';

/* @manifest */
const manifest = {
    "$schema": "../common/Schemas/manifest.schema.json",
    "name": "MessagePeek",
    "version": "1.2.7",
    "description": "See the last message in a Channel like on mobile",
    "author": "domi.btnr",
    "authorId": "354191516979429376",
    "invite": "gp2ExK5vc7",
    "donate": "https://paypal.me/domibtnr",
    "source": "https://github.com/domi-btnr/BetterDiscordStuff/tree/development/MessagePeek",
    "changelog": {
        "date": "2026-09-05",
        "changes": [{
                "type": "fixed",
                "title": "Fixed",
                "items": [
                    "Updated the Plugin to work with the latest Discord update"
                ]
            },
            {
                "type": "progress",
                "title": "Known broken Features",
                "items": [
                    "Removed the option to show timestamps in the DM list as it doesn't work and I don't have the time to fix it right now"
                ]
            }
        ]
    }
};

/* @api */
const {
    Components,
    Data,
    DOM,
    Hooks,
    Patcher,
    ReactUtils,
    UI,
    Utils,
    Webpack
} = new BdApi(manifest.name);

/* react */
var React = BdApi.React;

/* ../common/Changelog/footer.tsx */
const {
    Text
} = Components;

function Footer({
    manifest
}) {
    if (!manifest.invite && !manifest.source) return null;
    let issuesUrl;
    if (manifest.source) {
        const url = new URL(manifest.source);
        const [, owner, repo] = url.pathname.split("/");
        url.pathname = `/${owner}/${repo}/issues`;
        issuesUrl = url.toString();
    }
    return React.createElement(Text, null, "Need support?", " ", manifest.invite && React.createElement(React.Fragment, null, "Join the", " ", React.createElement("a", {
        onClick: () => UI.showInviteModal(manifest.invite),
        style: {
            textDecoration: "underline"
        }
    }, "Discord Server"), manifest.source && " or "), manifest.source && React.createElement(React.Fragment, null, "Check for Issues on", " ", React.createElement("a", {
        href: issuesUrl,
        target: "_blank",
        rel: "noreferrer",
        style: {
            textDecoration: "underline"
        }
    }, "GitHub")));
}

/* ../common/Changelog/index.tsx */
function showChangelog(manifest) {
    if (Data.load("lastVersion") === manifest.version) return;
    if (!manifest.changelog) return;
    const {
        date,
        title,
        subtitle,
        ...changelog
    } = manifest.changelog;
    if (!changelog.changes?.length && !changelog.blurb && !changelog.video && !changelog.banner) return;
    const i18n = Webpack.getByKeys("getLocale");
    const formatter = new Intl.DateTimeFormat(i18n.getLocale(), {
        month: "long",
        day: "numeric",
        year: "numeric"
    });
    UI.showChangelogModal({
        title: title ?? `What's New - ${manifest.name}`,
        subtitle: subtitle ?? `${date ? formatter.format(new Date(date)) + " - " : ""}v${manifest.version}`,
        ...changelog,
        footer: React.createElement(Footer, {
            manifest
        })
    });
    Data.save("lastVersion", manifest.version);
}

/* @styles */

var Styles = {
    sheets: [],
    _element: null,
    load() {
        DOM.addStyle(this.sheets.join("\n"));
    },
    unload() {
        DOM.removeStyle();
    }
};

/* ../common/ErrorBoundary/style.scss */
Styles.sheets.push("/* ../common/ErrorBoundary/style.scss */", `.errorBoundary {
  align-items: center;
  background: #473c41;
  border: 2px solid #f04747;
  border-radius: 5px;
  padding: 5px;
  margin: 10px;
  color: #fff;
  font-size: 16px;
}
.errorBoundary .errorText {
  display: flex;
  flex-direction: column;
  gap: 5px;
}`);

/* ../common/ErrorBoundary/index.tsx */
const ErrorIcon = (props) => React.createElement("svg", {
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 24 24",
    fill: "#ddd",
    width: "24",
    height: "24",
    ...props
}, React.createElement("path", {
    d: "M0 0h24v24H0z",
    fill: "none"
}), React.createElement("path", {
    d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"
}));
class ErrorBoundary extends React.Component {
    state = {
        hasError: false,
        error: null,
        info: null
    };
    componentDidCatch(error, info) {
        this.setState({
            error,
            info,
            hasError: true
        });
        console.error(
            `[ErrorBoundary:${this.props.id}] HI OVER HERE!! SHOW THIS SCREENSHOT TO THE DEVELOPER.
`,
            error
        );
    }
    render() {
        if (this.state.hasError) {
            return this.props.mini ? React.createElement(ErrorIcon, {
                fill: "#f04747"
            }) : React.createElement("div", {
                className: "errorBoundary"
            }, React.createElement("div", {
                className: "errorText"
            }, React.createElement("span", null, "An error has occured while rendering ", this.props.id, "."), React.createElement("span", null, "Open console (", React.createElement("code", null, "CTRL + SHIFT + i / CMD + SHIFT + i"), ') - Select the "Console" tab and screenshot the big red error.')));
        } else return this.props.children;
    }
}

/* ../common/Settings/store.ts */
const Dispatcher = Webpack.getByKeys("dispatch", "subscribe", {
    searchExports: true
});
const Flux = Webpack.getByKeys("Store");
const Settings = new class Settings2 extends Flux.Store {
    constructor() {
        super(Dispatcher, {});
    }
    _settings = Data.load("SETTINGS") ?? {};
    get(key, def) {
        return this._settings[key] ?? def;
    }
    set(key, value) {
        this._settings[key] = value;
        Data.save("SETTINGS", this._settings);
        this.emitChange();
    }
}();

/* ../common/Settings/items/dropdown.tsx */
const {
    SettingItem: SettingItem$2
} = Components;
const Select = Webpack.getByStrings('selectionMode:"single",onSelectionChange:', "isSelected:", {
    searchExports: true
});

function DropdownItem(props) {
    return React.createElement(ErrorBoundary, {
        id: props.id
    }, React.createElement(SettingItem$2, {
        ...props
    }, React.createElement(
        Select, {
            closeOnSelect: true,
            options: props.options,
            serialize: (v) => String(v),
            select: (v) => Settings.set(props.id, v),
            isSelected: (v) => Settings.get(props.id, props.value) === v
        }
    )));
}

/* ../common/Settings/items/slider.tsx */
const {
    SettingItem: SettingItem$1
} = Components;
const Slider = Webpack.getByStrings("stickToMarkers");

function SliderItem(props) {
    const value = Hooks.useStateFromStores([Settings], () => Settings.get(props.id, props.value));
    return React.createElement(ErrorBoundary, {
        id: props.id
    }, React.createElement(SettingItem$1, {
        ...props
    }, React.createElement(
        Slider, {
            ...props,
            handleSize: 10,
            initialValue: value,
            defaultValue: props.defaultValue,
            minValue: props.minValue,
            maxValue: props.maxValue,
            onValueChange: (value2) => Settings.set(props.id, Math.round(value2)),
            onValueRender: (value2) => Math.round(value2)
        }
    )));
}

/* ../common/Settings/items/switch.tsx */
const {
    SettingItem,
    SwitchInput
} = Components;

function SwitchItem(props) {
    const value = Hooks.useStateFromStores([Settings], () => Settings.get(props.id, props.value));
    return React.createElement(ErrorBoundary, {
        id: props.id
    }, React.createElement(SettingItem, {
        ...props,
        inline: true
    }, React.createElement(SwitchInput, {
        value,
        onChange: (v) => Settings.set(props.id, v)
    })));
}

/* ../common/Settings/panel.tsx */
function SettingsPanel({
    items,
    components: customComponents
}) {
    const ComponentMap = {
        dropdown: DropdownItem,
        switch: SwitchItem,
        slider: SliderItem,
        ...customComponents
    };
    return items.map((item) => {
        const Component = ComponentMap[item.type];
        return Component ? React.createElement(Component, {
            key: item.id,
            ...item
        }) : null;
    });
}

/* components/styles.scss */
Styles.sheets.push("/* components/styles.scss */", `a[href^="/channels/@me/"] [class^=layout] {
  min-height: 42px;
  max-height: 50px;
  height: unset;
}`);

/* components/messagePeek.jsx */
const MessageStore = Webpack.getStore("MessageStore");
const Parser = Webpack.getByKeys("parseTopic");
const i18n = Webpack.getByKeys("getLocale");

function MessagePeek$1({
    channelId,
    timestampOnly
}) {
    if (!channelId) return null;
    const lastMessage = Hooks.useStateFromStores([MessageStore], () => MessageStore.getMessages(channelId)?.last());
    if (!lastMessage) return null;
    if (!timestampOnly) {
        const attachmentCount = lastMessage.attachments.length;
        const content = lastMessage.content || lastMessage.embeds?.[0]?.rawDescription || lastMessage.stickerItems.length && "Sticker" || attachmentCount && `${attachmentCount} attachment${attachmentCount > 1 ? "s" : ""}`;
        if (!content) return null;
        const charLimit = Settings.get("tooltipCharacterLimit", 256);
        const authorName = lastMessage.author.email && Settings.get("showYourselfAsYou", true) ? "You" : lastMessage.author["globalName"] || lastMessage.author["username"];
        return React.createElement(
            "div", {
                style: {
                    marginBottom: "2px",
                    marginTop: "-2px",
                    overflow: "hidden",
                    textOverflow: "ellipsis",
                    whiteSpace: "nowrap"
                }
            },
            React.createElement(
                Components.Tooltip, {
                    text: content.length > charLimit ? Parser.parse(content.slice(0, charLimit).trim() + "\u2026") : Parser.parse(content)
                },
                (props) => React.createElement(
                    "div", {
                        ...props,
                        style: {
                            fontSize: "12px",
                            fontWeight: "var(--font-weight-medium)",
                            lineHeight: "16px",
                            overflow: "hidden",
                            textOverflow: "ellipsis",
                            whiteSpace: "nowrap"
                        }
                    },
                    Settings.get("showAuthor", true) && `${authorName}: `,
                    Parser.parseInlineReply(content)
                )
            )
        );
    } else {
        const now = Date.now();
        const dateTimeFormatter = new Intl.DateTimeFormat(i18n.getLocale(), {
            day: "2-digit",
            month: "2-digit",
            year: "numeric",
            hour: "2-digit",
            minute: "2-digit"
        });
        const units = [{
                unit: "s",
                ms: 1e3
            },
            {
                unit: "m",
                ms: 1e3 * 60
            },
            {
                unit: "h",
                ms: 1e3 * 60 * 60
            },
            {
                unit: "d",
                ms: 1e3 * 60 * 60 * 24
            },
            {
                unit: "w",
                ms: 1e3 * 60 * 60 * 24 * 7
            },
            {
                unit: "mo",
                ms: 1e3 * 60 * 60 * 24 * 30
            },
            {
                unit: "y",
                ms: 1e3 * 60 * 60 * 24 * 365
            }
        ];
        const diffInMs = lastMessage.timestamp - now;
        let relativeTime = 0;
        let unit = "";
        for (let i = units.length - 1; i >= 0; i--) {
            const {
                unit: u,
                ms
            } = units[i];
            if (Math.abs(diffInMs) >= ms) {
                relativeTime = Math.floor(diffInMs / ms);
                unit = u;
                break;
            }
        }
        return React.createElement(Components.Tooltip, {
            text: dateTimeFormatter.format(lastMessage.timestamp)
        }, (props) => React.createElement(
            "div", {
                ...props,
                style: {
                    marginRight: "5px",
                    alignContent: "center",
                    color: "var(--channels-default)"
                }
            },
            `${Math.abs(relativeTime)}${unit}`
        ));
    }
}

/* settings.json */
var items = [{
        type: "switch",
        name: "Show in DMs",
        note: "",
        id: "showInDMs",
        value: true
    },
    {
        type: "switch",
        name: "Show in Guilds",
        note: "",
        id: "showInGuilds",
        value: true
    },
    {
        type: "switch",
        name: "Show Author",
        note: "Whether to show the name of the Author or not",
        id: "showAuthor",
        value: true
    },
    {
        type: "switch",
        name: "Show as \"You\"",
        note: "Whether to show your name or \"You\"",
        id: "showYourselfAsYou",
        value: true
    },
    {
        type: "switch",
        name: "Show Timestamp",
        note: "Whether to show the relative timestamp next to the Channel or not",
        id: "showTimestamp",
        value: true
    },
    {
        type: "slider",
        name: "Preload Limit",
        note: "How many DM channels to preload. This makes an API request for each channel, so be careful with this setting",
        id: "preloadLimit",
        minValue: 0,
        maxValue: 30,
        markers: [
            0,
            5,
            10,
            20,
            30
        ],
        stickToMarkers: false,
        defaultValue: 10
    },
    {
        type: "slider",
        name: "Tooltip Character Limit",
        note: "The maximum number of characters to show in the tooltip",
        id: "tooltipCharacterLimit",
        minValue: 64,
        maxValue: 1024,
        markers: [
            64,
            128,
            256,
            512,
            1024
        ],
        stickToMarkers: true,
        defaultValue: 256
    }
];
var SettingsItems = {
    items: items
};

/* index.jsx */
class MessagePeek {
    start() {
        if (Settings.get("preloadLimit", 10) > 30) Settings.set("preloadLimit", 10);
        showChangelog(manifest);
        this.patchDMs();
        this.patchGuildChannel();
        Styles.load();
    }
    stop() {
        Patcher.unpatchAll();
        Styles.unload();
    }
    async patchDMs() {
        const ChannelContext = React.createContext(null);
        const ChannelWrapper = await Webpack.waitForModule(
            Webpack.Filters.bySource("isMobile", 'location:"PrivateChannel"')
        );
        const NameWrapper = (await Webpack.waitForModule(Webpack.Filters.bySource("AvatarWithText"))).A;
        const ChannelClasses = await Webpack.waitForModule(Webpack.Filters.byKeys("channel", "decorator"));
        Patcher.after(ChannelWrapper, "Ay", (_, __, res) => {
            if (!Settings.get("showInDMs", true)) return;
            Patcher.after(res, "type", (_2, [props], res2) => {
                return React.createElement(ChannelContext.Provider, {
                    value: props.channel
                }, res2);
            });
        });
        Patcher.after(NameWrapper, "render", (_, __, res) => {
            const channel = React.useContext(ChannelContext);
            if (!channel) return res;
            const nameWrapper = Utils.findInTree(res, (e) => e?.props?.className?.startsWith("content__"), {
                walkable: ["children", "props"]
            });
            if (!nameWrapper) return res;
            nameWrapper.props.children.push(React.createElement(MessagePeek$1, {
                channelId: channel.id
            }));
        });
        const preload = Webpack.getByKeys("preload", "fetchChannel")?.preload;
        Webpack.getStore("ChannelStore").getSortedPrivateChannels().filter(
            (channel) => channel.lastMessageId && !Webpack.getStore("MessageStore").getMessages(channel.id)?.last()
        ).slice(0, Settings.get("preloadLimit", 10)).reduce((promise, channel, index) => {
            return promise.then(() => {
                preload("@me", channel.id);
                return new Promise((resolve) => setTimeout(resolve, 125 + index * 125));
            });
        }, Promise.resolve());
        const ChannelWrapperElement = document.querySelector(`h2 + .${ChannelClasses.channel}`);
        if (ChannelWrapperElement) {
            const ChannelWrapperInstance = ReactUtils.getOwnerInstance(ChannelWrapperElement);
            if (ChannelWrapperInstance) ChannelWrapperInstance.forceUpdate();
        }
    }
    async patchGuildChannel() {
        const ChannelWrapper = await Webpack.waitForModule(
            Webpack.Filters.byComponentType(Webpack.Filters.byStrings("channel", "unread", ".ALL_MESSAGES"))
        );
        Patcher.after(ChannelWrapper, "render", (_, [{
            channel
        }], res) => {
            if (!Settings.get("showInGuilds", true)) return;
            const nameWrapper = Utils.findInTree(res, (e) => e?.props?.className?.startsWith("name__"), {
                walkable: ["children", "props"]
            });
            if (!nameWrapper) return res;
            nameWrapper.props.children = [nameWrapper.props.children, React.createElement(MessagePeek$1, {
                channelId: channel.id
            })];
            if (!Settings.get("showTimestamp", true)) return;
            const innerWrapper = Utils.findInTree(res, (e) => e?.props?.className?.startsWith("linkTop"), {
                walkable: ["children", "props"]
            });
            if (!innerWrapper) return res;
            const children = innerWrapper.props.children;
            children.splice(children.length - 1, 0, React.createElement(MessagePeek$1, {
                channelId: channel.id,
                timestampOnly: true
            }));
        });
    }
    getSettingsPanel() {
        return React.createElement(SettingsPanel, {
            items: SettingsItems.items
        });
    }
}

module.exports = MessagePeek;