From 168c1f9d5bc480df27a509d8f31dbc2e1ce3663d Mon Sep 17 00:00:00 2001 From: leoeooz <62527408+f1rep0wr@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:04:52 -0500 Subject: [PATCH 1/2] @ feat(orders): add quick blacklist button to Warframe Market orders Add a per-order button in the Orders tab that blacklists the item for all trade modes and removes its listing from Warframe Market in one action. Reuses the existing deleteById command and settings-update flow. Closes #111 @ --- public/lang/en.json | 17 +++++++++++ .../warframe_market/Tabs/Orders/index.tsx | 24 +++++++++++---- .../warframe_market/Tabs/Orders/modals.tsx | 14 ++++++++- .../warframe_market/Tabs/Orders/mutations.ts | 29 ++++++++++++++++++- 4 files changed, 77 insertions(+), 7 deletions(-) diff --git a/public/lang/en.json b/public/lang/en.json index ff4ebe33..5cfbff2c 100644 --- a/public/lang/en.json +++ b/public/lang/en.json @@ -364,6 +364,16 @@ "message": "The order has been successfully deleted." } }, + "blacklist_order": { + "error": { + "title": "Blacklist Error", + "message": "An error occurred while trying to blacklist the item." + }, + "success": { + "title": "Blacklist Success", + "message": "The item has been blacklisted and its listing removed." + } + }, "delete_all_orders": { "error": { "title": "Delete All Orders Error", @@ -473,6 +483,12 @@ "cancel": "Cancel", "confirm": "Confirm" }, + "blacklist_item": { + "title": "Blacklist item?", + "message": "This will remove your listing from Warframe Market and add the item to your blacklist. This action cannot be undone.", + "cancel": "Cancel", + "confirm": "Blacklist" + }, "delete_multiple_items": { "title": "Are you sure?", "message": "Are you sure you want to delete these {{count}} items? This action cannot be undone.", @@ -2101,6 +2117,7 @@ "refresh_tooltip": "Refresh the order list", "delete_all_tooltip": "Delete all orders", "delete_tooltip": "Delete this order", + "blacklist_tooltip": "Blacklist item and remove listing", "info_tooltip": "View order details", "sell_manual": { "buy_tooltip": "Bought manually", diff --git a/src/pages/warframe_market/Tabs/Orders/index.tsx b/src/pages/warframe_market/Tabs/Orders/index.tsx index 99637f6a..9fee01b2 100644 --- a/src/pages/warframe_market/Tabs/Orders/index.tsx +++ b/src/pages/warframe_market/Tabs/Orders/index.tsx @@ -51,18 +51,20 @@ export const OrderPanel = ({ isActive }: OrderPanelProps) => { const { refetchQueries, paginationQuery, statusCountsQuery } = useStockQueries({ queryData, isActive }); // Mutations - const { refreshOrdersMutation, deleteAllOrdersMutation, deleteStockMutation, createStockMutation, sellStockMutation } = useStockMutations({ - refetchQueries, - setLoadingRows, - }); + const { refreshOrdersMutation, deleteAllOrdersMutation, deleteStockMutation, createStockMutation, sellStockMutation, blacklistOrderMutation } = + useStockMutations({ + refetchQueries, + setLoadingRows, + }); // Modals - const { OpenDeleteAllModal, OpenInfoModal, OpenDeleteModal, HandleModalOrder } = useStockModals({ + const { OpenDeleteAllModal, OpenInfoModal, OpenDeleteModal, OpenBlacklistModal, HandleModalOrder } = useStockModals({ createStockMutation, sellStockMutation, useTranslateBasePrompt, deleteStockMutation, deleteAllOrdersMutation, + blacklistOrderMutation, }); const handleRefresh = (_data: any) => { refetchQueries(true); @@ -304,6 +306,18 @@ export const OrderPanel = ({ isActive }: OrderPanelProps) => { OpenInfoModal(order); }} /> + { + e.stopPropagation(); + OpenBlacklistModal(order); + }} + /> Promise; }; + blacklistOrderMutation: { + mutateAsync: (order: WFMarketTypes.Order) => Promise; + }; deleteAllOrdersMutation: { mutateAsync: (order_type?: WFMarketTypes.OrderType) => Promise; }; @@ -20,7 +23,7 @@ interface ModalHooks { }; } -export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, createStockMutation, sellStockMutation }: ModalHooks) => { +export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, createStockMutation, sellStockMutation, blacklistOrderMutation }: ModalHooks) => { const OpenSellModal = (order: WFMarketTypes.Order) => { modals.openContextModal({ modal: "prompt", @@ -111,6 +114,14 @@ export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, c onConfirm: async () => await deleteStockMutation.mutateAsync(id), }); }; + const OpenBlacklistModal = (order: WFMarketTypes.Order) => { + modals.openConfirmModal({ + title: useTranslateCommon("prompts.blacklist_item.title"), + children: {useTranslateCommon("prompts.blacklist_item.message")}, + labels: { confirm: useTranslateCommon("prompts.blacklist_item.confirm"), cancel: useTranslateCommon("prompts.blacklist_item.cancel") }, + onConfirm: () => blacklistOrderMutation.mutateAsync(order), + }); + }; const OpenDeleteAllModal = () => { modals.openContextModal({ modal: "prompt", @@ -145,6 +156,7 @@ export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, c return { HandleModalOrder, OpenDeleteModal, + OpenBlacklistModal, OpenDeleteAllModal, OpenInfoModal, }; diff --git a/src/pages/warframe_market/Tabs/Orders/mutations.ts b/src/pages/warframe_market/Tabs/Orders/mutations.ts index 224343da..c699f959 100644 --- a/src/pages/warframe_market/Tabs/Orders/mutations.ts +++ b/src/pages/warframe_market/Tabs/Orders/mutations.ts @@ -1,9 +1,11 @@ -import { WFMarketTypes } from "$types"; +import { TauriTypes, WFMarketTypes } from "$types"; import api from "@api/index"; +import { useAppContext } from "@contexts/app.context"; import { createGenericMutation, MutationHooks } from "@utils/genericMutation.helper"; export const useStockMutations = ({ refetchQueries, setLoadingRows }: MutationHooks) => { const hooks = { refetchQueries, setLoadingRows }; + const { settings } = useAppContext(); const refreshOrdersMutation = createGenericMutation( { @@ -73,11 +75,36 @@ export const useStockMutations = ({ refetchQueries, setLoadingRows }: MutationHo hooks, ); + const blacklistOrderMutation = createGenericMutation( + { + mutationFn: async (order: WFMarketTypes.Order) => { + if (!settings) throw new Error("Settings are not loaded"); + const wfm_id = order.properties?.wfm_id || order.itemId; + const allModes = [TauriTypes.TradeMode.Buy, TauriTypes.TradeMode.Sell, TauriTypes.TradeMode.Wishlist]; + const blacklist = settings.live_scraper.stock_item.blacklist || []; + const updatedBlacklist = [...blacklist.filter((b) => b.wfm_id !== wfm_id), { wfm_id, disabled_for: allModes }]; + await api.app.updateSettings({ + ...settings, + live_scraper: { + ...settings.live_scraper, + stock_item: { ...settings.live_scraper.stock_item, blacklist: updatedBlacklist }, + }, + }); + return api.order.deleteById(order.id); + }, + successKey: "blacklist_order", + errorKey: "blacklist_order", + getLoadingId: (order: WFMarketTypes.Order) => `${order.id}`, + }, + hooks, + ); + return { refreshOrdersMutation, deleteAllOrdersMutation, createStockMutation, sellStockMutation, deleteStockMutation, + blacklistOrderMutation, }; }; From e9733ab313b9aed0c7617f9daa0bc0ff469ec898 Mon Sep 17 00:00:00 2001 From: Kenya-DK Date: Mon, 6 Jul 2026 10:53:36 +0200 Subject: [PATCH 2/2] feat(orders): Complete quick blacklist functionality and refresh settings This commit finalizes the quick blacklist feature by integrating the action into a modal flow and ensuring that application settings are immediately refreshed after an item is blacklisted. This provides prompt feedback and consistency across the UI. Additionally, it corrects the property name (`wfmId`) used when updating the blacklist configuration in user settings, resolving a potential issue with item identification. --- .../warframe_market/Tabs/Orders/index.tsx | 12 +++++++++- .../warframe_market/Tabs/Orders/modals.tsx | 22 ++++++++++++++----- .../warframe_market/Tabs/Orders/mutations.ts | 2 +- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/pages/warframe_market/Tabs/Orders/index.tsx b/src/pages/warframe_market/Tabs/Orders/index.tsx index 9fee01b2..298679bc 100644 --- a/src/pages/warframe_market/Tabs/Orders/index.tsx +++ b/src/pages/warframe_market/Tabs/Orders/index.tsx @@ -6,7 +6,17 @@ import { Loading } from "@components/Shared/Loading"; import { PaginationFooter } from "@components/Shared/PaginationFooter"; import { PreviewCard } from "@components/Shared/PreviewCard/PreviewCard"; import { TextTranslate } from "@components/Shared/TextTranslate"; -import { faArrowDown, faArrowUp, faCartShopping, faInfoCircle, faPen, faRefresh, faSackDollar, faTrashCan } from "@fortawesome/free-solid-svg-icons"; +import { + faArrowDown, + faArrowUp, + faBan, + faCartShopping, + faInfoCircle, + faPen, + faRefresh, + faSackDollar, + faTrashCan, +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useHasAlert } from "@hooks/useHasAlert.hook"; import { useTauriEvent } from "@hooks/useTauriEvent.hook"; diff --git a/src/pages/warframe_market/Tabs/Orders/modals.tsx b/src/pages/warframe_market/Tabs/Orders/modals.tsx index 815b435b..d45a5a5a 100644 --- a/src/pages/warframe_market/Tabs/Orders/modals.tsx +++ b/src/pages/warframe_market/Tabs/Orders/modals.tsx @@ -1,8 +1,9 @@ -import { modals } from "@mantine/modals"; -import { Text } from "@mantine/core"; -import { WFMarketTypes } from "$types"; -import { useTranslateCommon, useTranslateEnums } from "@hooks/useTranslate.hook"; +import { TauriTypes, WFMarketTypes } from "$types"; +import { SendTauriEvent } from "@api/index"; import { ItemDetailsModal, Operations } from "@components/Modals/ItemDetails"; +import { useTranslateCommon, useTranslateEnums } from "@hooks/useTranslate.hook"; +import { Text } from "@mantine/core"; +import { modals } from "@mantine/modals"; interface ModalHooks { useTranslateBasePrompt: (key: string, context?: { [key: string]: any }) => string; @@ -23,7 +24,13 @@ interface ModalHooks { }; } -export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, createStockMutation, sellStockMutation, blacklistOrderMutation }: ModalHooks) => { +export const useStockModals = ({ + deleteStockMutation, + deleteAllOrdersMutation, + createStockMutation, + sellStockMutation, + blacklistOrderMutation, +}: ModalHooks) => { const OpenSellModal = (order: WFMarketTypes.Order) => { modals.openContextModal({ modal: "prompt", @@ -119,7 +126,10 @@ export const useStockModals = ({ deleteStockMutation, deleteAllOrdersMutation, c title: useTranslateCommon("prompts.blacklist_item.title"), children: {useTranslateCommon("prompts.blacklist_item.message")}, labels: { confirm: useTranslateCommon("prompts.blacklist_item.confirm"), cancel: useTranslateCommon("prompts.blacklist_item.cancel") }, - onConfirm: () => blacklistOrderMutation.mutateAsync(order), + onConfirm: async () => { + await blacklistOrderMutation.mutateAsync(order); + SendTauriEvent(TauriTypes.Events.RefreshSettings); + }, }); }; const OpenDeleteAllModal = () => { diff --git a/src/pages/warframe_market/Tabs/Orders/mutations.ts b/src/pages/warframe_market/Tabs/Orders/mutations.ts index c699f959..075867f9 100644 --- a/src/pages/warframe_market/Tabs/Orders/mutations.ts +++ b/src/pages/warframe_market/Tabs/Orders/mutations.ts @@ -82,7 +82,7 @@ export const useStockMutations = ({ refetchQueries, setLoadingRows }: MutationHo const wfm_id = order.properties?.wfm_id || order.itemId; const allModes = [TauriTypes.TradeMode.Buy, TauriTypes.TradeMode.Sell, TauriTypes.TradeMode.Wishlist]; const blacklist = settings.live_scraper.stock_item.blacklist || []; - const updatedBlacklist = [...blacklist.filter((b) => b.wfm_id !== wfm_id), { wfm_id, disabled_for: allModes }]; + const updatedBlacklist = [...blacklist.filter((b) => b.wfmId !== wfm_id), { wfmId: wfm_id, disabled_for: allModes }]; await api.app.updateSettings({ ...settings, live_scraper: {