Upgraded react-query to v5

pull/2526/head
Anderson Shindy Oki 5 months ago committed by GitHub
parent eee8659ce1
commit 4d3c1f4b9d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,10 +1,11 @@
// eslint-disable-next-line no-restricted-imports
import { dependencies } from "../package.json";
const vendors = [
"react",
"react-router-dom",
"react-dom",
"react-query",
"@tanstack/react-query",
"axios",
"socket.io-client",
];

@ -15,10 +15,10 @@
"@mantine/hooks": "^7.10.1",
"@mantine/modals": "^7.10.1",
"@mantine/notifications": "^7.10.1",
"@tanstack/react-query": "^5.40.1",
"axios": "^1.6.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-query": "^3.39.3",
"react-router-dom": "^6.23.1",
"socket.io-client": "^4.7.5"
},
@ -29,6 +29,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@tanstack/react-query-devtools": "^5.40.1",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^15.0.5",
"@testing-library/user-event": "^14.5.2",
@ -3331,6 +3332,61 @@
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"node_modules/@tanstack/query-core": {
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.40.0.tgz",
"integrity": "sha512-eD8K8jsOIq0Z5u/QbvOmfvKKE/XC39jA7yv4hgpl/1SRiU+J8QCIwgM/mEHuunQsL87dcvnHqSVLmf9pD4CiaA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/query-devtools": {
"version": "5.37.1",
"resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.37.1.tgz",
"integrity": "sha512-XcG4IIHIv0YQKrexTqo2zogQWR1Sz672tX2KsfE9kzB+9zhx44vRKH5si4WDILE1PIWQpStFs/NnrDQrBAUQpg==",
"dev": true,
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/react-query": {
"version": "5.40.1",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.40.1.tgz",
"integrity": "sha512-gOcmu+gpFd2taHrrgMM9RemLYYEDYfsCqszxCC0xtx+csDa4R8t7Hr7SfWXQP13S2sF+mOxySo/+FNXJFYBqcA==",
"license": "MIT",
"dependencies": {
"@tanstack/query-core": "5.40.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^18.0.0"
}
},
"node_modules/@tanstack/react-query-devtools": {
"version": "5.40.1",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.40.1.tgz",
"integrity": "sha512-/AN2UsbuL+28/KSlBkVHq/4chHTEp4l2UWTKWixXbn4pprLQrZGmQTAKN4tYxZDuNwNZY5+Zp67pDfXj+F/UBA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tanstack/query-devtools": "5.37.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"@tanstack/react-query": "^5.40.1",
"react": "^18 || ^19"
}
},
"node_modules/@testing-library/dom": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.0.0.tgz",
@ -4726,15 +4782,8 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/big-integer": {
"version": "1.6.52",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
"integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
"engines": {
"node": ">=0.6"
}
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/binary-extensions": {
"version": "2.3.0",
@ -4752,6 +4801,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -4769,21 +4819,6 @@
"node": ">=8"
}
},
"node_modules/broadcast-channel": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
"integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
"dependencies": {
"@babel/runtime": "^7.7.2",
"detect-node": "^2.1.0",
"js-sha3": "0.8.0",
"microseconds": "0.2.0",
"nano-time": "1.0.0",
"oblivious-set": "1.0.0",
"rimraf": "3.0.2",
"unload": "2.2.0"
}
},
"node_modules/browserslist": {
"version": "4.23.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
@ -5029,7 +5064,8 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
"node_modules/confusing-browser-globals": {
"version": "1.0.11",
@ -5412,11 +5448,6 @@
"node": ">=6"
}
},
"node_modules/detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
},
"node_modules/detect-node-es": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
@ -6492,7 +6523,8 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
},
"node_modules/fsevents": {
"version": "2.3.3",
@ -6622,6 +6654,7 @@
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -6931,6 +6964,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@ -6939,7 +6973,8 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"node_modules/internal-slot": {
"version": "1.0.7",
@ -7601,11 +7636,6 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/js-sha3": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -7965,15 +7995,6 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/match-sorter": {
"version": "6.3.4",
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz",
"integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==",
"dependencies": {
"@babel/runtime": "^7.23.8",
"remove-accents": "0.5.0"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -8002,11 +8023,6 @@
"node": ">=8.6"
}
},
"node_modules/microseconds": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
"integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@ -8048,6 +8064,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -8099,14 +8116,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/nano-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
"integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==",
"dependencies": {
"big-integer": "^1.6.16"
}
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@ -8294,15 +8303,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/oblivious-set": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
"integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"dependencies": {
"wrappy": "1"
}
@ -8424,6 +8429,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -8857,31 +8863,6 @@
"react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-query": {
"version": "3.39.3",
"resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
"integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==",
"dependencies": {
"@babel/runtime": "^7.5.5",
"broadcast-channel": "^3.4.1",
"match-sorter": "^6.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-refresh": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
@ -9213,11 +9194,6 @@
"jsesc": "bin/jsesc"
}
},
"node_modules/remove-accents": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
"integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A=="
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@ -9264,6 +9240,7 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
@ -10154,15 +10131,6 @@
"node": ">= 4.0.0"
}
},
"node_modules/unload": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz",
"integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==",
"dependencies": {
"@babel/runtime": "^7.6.2",
"detect-node": "^2.0.4"
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
@ -10974,7 +10942,8 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
"node_modules/ws": {
"version": "8.16.0",

@ -19,10 +19,10 @@
"@mantine/hooks": "^7.10.1",
"@mantine/modals": "^7.10.1",
"@mantine/notifications": "^7.10.1",
"@tanstack/react-query": "^5.40.1",
"axios": "^1.6.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-query": "^3.39.3",
"react-router-dom": "^6.23.1",
"socket.io-client": "^4.7.5"
},
@ -33,6 +33,7 @@
"@fortawesome/free-regular-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@tanstack/react-query-devtools": "^5.40.1",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^15.0.5",
"@testing-library/user-event": "^14.5.2",

@ -1,9 +1,10 @@
import { useEffect } from "react";
import {
QueryClient,
useMutation,
useQuery,
useQueryClient,
} from "react-query";
} from "@tanstack/react-query";
import { usePaginationQuery } from "@/apis/queries/hooks";
import { QueryKeys } from "@/apis/queries/keys";
import api from "@/apis/raw";
@ -26,28 +27,36 @@ const cacheEpisodes = (client: QueryClient, episodes: Item.Episode[]) => {
export function useEpisodesByIds(ids: number[]) {
const client = useQueryClient();
return useQuery(
[QueryKeys.Series, QueryKeys.Episodes, ids],
() => api.episodes.byEpisodeId(ids),
{
onSuccess: (data) => {
cacheEpisodes(client, data);
},
},
);
const query = useQuery({
queryKey: [QueryKeys.Series, QueryKeys.Episodes, ids],
queryFn: () => api.episodes.byEpisodeId(ids),
});
useEffect(() => {
if (query.isSuccess && query.data) {
cacheEpisodes(client, query.data);
}
}, [query.isSuccess, query.data, client]);
return query;
}
export function useEpisodesBySeriesId(id: number) {
const client = useQueryClient();
return useQuery(
[QueryKeys.Series, id, QueryKeys.Episodes, QueryKeys.All],
() => api.episodes.bySeriesId([id]),
{
onSuccess: (data) => {
cacheEpisodes(client, data);
},
},
);
const query = useQuery({
queryKey: [QueryKeys.Series, id, QueryKeys.Episodes, QueryKeys.All],
queryFn: () => api.episodes.bySeriesId([id]),
});
useEffect(() => {
if (query.isSuccess && query.data) {
cacheEpisodes(client, query.data);
}
}, [query.isSuccess, query.data, client]);
return query;
}
export function useEpisodeWantedPagination() {
@ -57,17 +66,18 @@ export function useEpisodeWantedPagination() {
}
export function useEpisodeBlacklist() {
return useQuery(
[QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
() => api.episodes.blacklist(),
);
return useQuery({
queryKey: [QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
queryFn: () => api.episodes.blacklist(),
});
}
export function useEpisodeAddBlacklist() {
const client = useQueryClient();
return useMutation(
[QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
(param: {
return useMutation({
mutationKey: [QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
mutationFn: (param: {
seriesId: number;
episodeId: number;
form: FormType.AddBlacklist;
@ -75,35 +85,32 @@ export function useEpisodeAddBlacklist() {
const { seriesId, episodeId, form } = param;
return api.episodes.addBlacklist(seriesId, episodeId, form);
},
{
onSuccess: (_, { seriesId, episodeId }) => {
client.invalidateQueries([
QueryKeys.Series,
QueryKeys.Episodes,
QueryKeys.Blacklist,
]);
client.invalidateQueries([QueryKeys.Series, seriesId]);
},
onSuccess: (_, { seriesId }) => {
client.invalidateQueries({
queryKey: [QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
});
client.invalidateQueries({
queryKey: [QueryKeys.Series, seriesId],
});
},
);
});
}
export function useEpisodeDeleteBlacklist() {
const client = useQueryClient();
return useMutation(
[QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
(param: { all?: boolean; form?: FormType.DeleteBlacklist }) =>
return useMutation({
mutationKey: [QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
mutationFn: (param: { all?: boolean; form?: FormType.DeleteBlacklist }) =>
api.episodes.deleteBlacklist(param.all, param.form),
{
onSuccess: (_, param) => {
client.invalidateQueries([
QueryKeys.Series,
QueryKeys.Episodes,
QueryKeys.Blacklist,
]);
},
onSuccess: (_) => {
client.invalidateQueries({
queryKey: [QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
});
},
);
});
}
export function useEpisodeHistoryPagination() {
@ -115,12 +122,20 @@ export function useEpisodeHistoryPagination() {
}
export function useEpisodeHistory(episodeId?: number) {
return useQuery(
[QueryKeys.Series, QueryKeys.Episodes, QueryKeys.History, episodeId],
() => {
return useQuery({
queryKey: [
QueryKeys.Series,
QueryKeys.Episodes,
QueryKeys.History,
episodeId,
],
queryFn: () => {
if (episodeId) {
return api.episodes.historyBy(episodeId);
}
return [];
},
);
});
}

@ -1,4 +1,4 @@
import { useQuery } from "react-query";
import { useQuery } from "@tanstack/react-query";
import { QueryKeys } from "@/apis/queries/keys";
import api from "@/apis/raw";
@ -8,14 +8,19 @@ export function useHistoryStats(
provider: System.Provider | null,
language: Language.Info | null,
) {
return useQuery(
[QueryKeys.System, QueryKeys.History, { time, action, provider, language }],
() =>
return useQuery({
queryKey: [
QueryKeys.System,
QueryKeys.History,
{ time, action, provider, language },
],
queryFn: () =>
api.history.stats(
time,
action ?? undefined,
provider?.name,
language?.code2,
),
);
});
}

@ -1,23 +1,19 @@
import { useQuery } from "react-query";
import { useQuery } from "@tanstack/react-query";
import { QueryKeys } from "@/apis/queries/keys";
import api from "@/apis/raw";
export function useLanguages(history?: boolean) {
return useQuery(
[QueryKeys.System, QueryKeys.Languages, history ?? false],
() => api.system.languages(history),
{
staleTime: Infinity,
},
);
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.Languages, history ?? false],
queryFn: () => api.system.languages(history),
staleTime: Infinity,
});
}
export function useLanguageProfiles() {
return useQuery(
[QueryKeys.System, QueryKeys.LanguagesProfiles],
() => api.system.languagesProfileList(),
{
staleTime: Infinity,
},
);
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.LanguagesProfiles],
queryFn: () => api.system.languagesProfileList(),
staleTime: Infinity,
});
}

@ -1,9 +1,10 @@
import { useEffect } from "react";
import {
QueryClient,
useMutation,
useQuery,
useQueryClient,
} from "react-query";
} from "@tanstack/react-query";
import { usePaginationQuery } from "@/apis/queries/hooks";
import { QueryKeys } from "@/apis/queries/keys";
import api from "@/apis/raw";
@ -16,31 +17,47 @@ const cacheMovies = (client: QueryClient, movies: Item.Movie[]) => {
export function useMoviesByIds(ids: number[]) {
const client = useQueryClient();
return useQuery([QueryKeys.Movies, ...ids], () => api.movies.movies(ids), {
onSuccess: (data) => {
cacheMovies(client, data);
},
const query = useQuery({
queryKey: [QueryKeys.Movies, ...ids],
queryFn: () => api.movies.movies(ids),
});
useEffect(() => {
if (query.isSuccess && query.data) {
cacheMovies(client, query.data);
}
}, [query.isSuccess, query.data, client]);
return query;
}
export function useMovieById(id: number) {
return useQuery([QueryKeys.Movies, id], async () => {
const response = await api.movies.movies([id]);
return response.length > 0 ? response[0] : undefined;
return useQuery({
queryKey: [QueryKeys.Movies, id],
queryFn: async () => {
const response = await api.movies.movies([id]);
return response.length > 0 ? response[0] : undefined;
},
});
}
export function useMovies() {
const client = useQueryClient();
return useQuery(
[QueryKeys.Movies, QueryKeys.All],
() => api.movies.movies(),
{
onSuccess: (data) => {
cacheMovies(client, data);
},
},
);
const query = useQuery({
queryKey: [QueryKeys.Movies, QueryKeys.All],
queryFn: () => api.movies.movies(),
});
useEffect(() => {
if (query.isSuccess && query.data) {
cacheMovies(client, query.data);
}
}, [query.isSuccess, query.data, client]);
return query;
}
export function useMoviesPagination() {
@ -51,32 +68,36 @@ export function useMoviesPagination() {
export function useMovieModification() {
const client = useQueryClient();
return useMutation(
[QueryKeys.Movies],
(form: FormType.ModifyItem) => api.movies.modify(form),
{
onSuccess: (_, form) => {
form.id.forEach((v) => {
client.invalidateQueries([QueryKeys.Movies, v]);
return useMutation({
mutationKey: [QueryKeys.Movies],
mutationFn: (form: FormType.ModifyItem) => api.movies.modify(form),
onSuccess: (_, form) => {
form.id.forEach((v) => {
client.invalidateQueries({
queryKey: [QueryKeys.Movies, v],
});
// TODO: query less
client.invalidateQueries([QueryKeys.Movies]);
},
});
// TODO: query less
client.invalidateQueries({
queryKey: [QueryKeys.Movies],
});
},
);
});
}
export function useMovieAction() {
const client = useQueryClient();
return useMutation(
[QueryKeys.Actions, QueryKeys.Movies],
(form: FormType.MoviesAction) => api.movies.action(form),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.Movies]);
},
return useMutation({
mutationKey: [QueryKeys.Actions, QueryKeys.Movies],
mutationFn: (form: FormType.MoviesAction) => api.movies.action(form),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.Movies],
});
},
);
});
}
export function useMovieWantedPagination() {
@ -86,40 +107,48 @@ export function useMovieWantedPagination() {
}
export function useMovieBlacklist() {
return useQuery([QueryKeys.Movies, QueryKeys.Blacklist], () =>
api.movies.blacklist(),
);
return useQuery({
queryKey: [QueryKeys.Movies, QueryKeys.Blacklist],
queryFn: () => api.movies.blacklist(),
});
}
export function useMovieAddBlacklist() {
const client = useQueryClient();
return useMutation(
[QueryKeys.Movies, QueryKeys.Blacklist],
(param: { id: number; form: FormType.AddBlacklist }) => {
return useMutation({
mutationKey: [QueryKeys.Movies, QueryKeys.Blacklist],
mutationFn: (param: { id: number; form: FormType.AddBlacklist }) => {
const { id, form } = param;
return api.movies.addBlacklist(id, form);
},
{
onSuccess: (_, { id }) => {
client.invalidateQueries([QueryKeys.Movies, QueryKeys.Blacklist]);
client.invalidateQueries([QueryKeys.Movies, id]);
},
onSuccess: (_, { id }) => {
client.invalidateQueries({
queryKey: [QueryKeys.Movies, QueryKeys.Blacklist],
});
client.invalidateQueries({
queryKey: [QueryKeys.Movies, id],
});
},
);
});
}
export function useMovieDeleteBlacklist() {
const client = useQueryClient();
return useMutation(
[QueryKeys.Movies, QueryKeys.Blacklist],
(param: { all?: boolean; form?: FormType.DeleteBlacklist }) =>
return useMutation({
mutationKey: [QueryKeys.Movies, QueryKeys.Blacklist],
mutationFn: (param: { all?: boolean; form?: FormType.DeleteBlacklist }) =>
api.movies.deleteBlacklist(param.all, param.form),
{
onSuccess: (_, param) => {
client.invalidateQueries([QueryKeys.Movies, QueryKeys.Blacklist]);
},
onSuccess: (_, param) => {
client.invalidateQueries({
queryKey: [QueryKeys.Movies, QueryKeys.Blacklist],
});
},
);
});
}
export function useMovieHistoryPagination() {
@ -131,9 +160,15 @@ export function useMovieHistoryPagination() {
}
export function useMovieHistory(radarrId?: number) {
return useQuery([QueryKeys.Movies, QueryKeys.History, radarrId], () => {
if (radarrId) {
return api.movies.historyBy(radarrId);
}
return useQuery({
queryKey: [QueryKeys.Movies, QueryKeys.History, radarrId],
queryFn: () => {
if (radarrId) {
return api.movies.historyBy(radarrId);
}
return [];
},
});
}

@ -1,66 +1,82 @@
import { useMutation, useQuery, useQueryClient } from "react-query";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { QueryKeys } from "@/apis/queries/keys";
import api from "@/apis/raw";
export function useSystemProviders(history?: boolean) {
return useQuery(
[QueryKeys.System, QueryKeys.Providers, history ?? false],
() => api.providers.providers(history),
);
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.Providers, history ?? false],
queryFn: () => api.providers.providers(history),
});
}
export function useMoviesProvider(radarrId?: number) {
return useQuery(
[QueryKeys.System, QueryKeys.Providers, QueryKeys.Movies, radarrId],
() => {
return useQuery({
queryKey: [
QueryKeys.System,
QueryKeys.Providers,
QueryKeys.Movies,
radarrId,
],
queryFn: () => {
if (radarrId) {
return api.providers.movies(radarrId);
}
return [];
},
{
staleTime: 0,
},
);
staleTime: 0,
});
}
export function useEpisodesProvider(episodeId?: number) {
return useQuery(
[QueryKeys.System, QueryKeys.Providers, QueryKeys.Episodes, episodeId],
() => {
return useQuery({
queryKey: [
QueryKeys.System,
QueryKeys.Providers,
QueryKeys.Episodes,
episodeId,
],
queryFn: () => {
if (episodeId) {
return api.providers.episodes(episodeId);
}
return [];
},
{
staleTime: 0,
},
);
staleTime: 0,
});
}
export function useResetProvider() {
const client = useQueryClient();
return useMutation(
[QueryKeys.System, QueryKeys.Providers],
() => api.providers.reset(),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.System, QueryKeys.Providers]);
},
return useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Providers],
mutationFn: () => api.providers.reset(),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Providers],
});
},
);
});
}
export function useDownloadEpisodeSubtitles() {
const client = useQueryClient();
return useMutation(
[
return useMutation({
mutationKey: [
QueryKeys.System,
QueryKeys.Providers,
QueryKeys.Subtitles,
QueryKeys.Episodes,
],
(param: {
mutationFn: (param: {
seriesId: number;
episodeId: number;
form: FormType.ManualDownload;
@ -70,30 +86,33 @@ export function useDownloadEpisodeSubtitles() {
param.episodeId,
param.form,
),
{
onSuccess: (_, param) => {
client.invalidateQueries([QueryKeys.Series, param.seriesId]);
},
onSuccess: (_, param) => {
client.invalidateQueries({
queryKey: [QueryKeys.Series, param.seriesId],
});
},
);
});
}
export function useDownloadMovieSubtitles() {
const client = useQueryClient();
return useMutation(
[
return useMutation({
mutationKey: [
QueryKeys.System,
QueryKeys.Providers,
QueryKeys.Subtitles,
QueryKeys.Movies,
],
(param: { radarrId: number; form: FormType.ManualDownload }) =>
mutationFn: (param: { radarrId: number; form: FormType.ManualDownload }) =>
api.providers.downloadMovieSubtitle(param.radarrId, param.form),
{
onSuccess: (_, param) => {
client.invalidateQueries([QueryKeys.Movies, param.radarrId]);
},
onSuccess: (_, param) => {
client.invalidateQueries({
queryKey: [QueryKeys.Movies, param.radarrId],
});
},
);
});
}

@ -1,9 +1,10 @@
import { useEffect } from "react";
import {
QueryClient,
useMutation,
useQuery,
useQueryClient,
} from "react-query";
} from "@tanstack/react-query";
import { usePaginationQuery } from "@/apis/queries/hooks";
import { QueryKeys } from "@/apis/queries/keys";
import api from "@/apis/raw";
@ -16,31 +17,47 @@ function cacheSeries(client: QueryClient, series: Item.Series[]) {
export function useSeriesByIds(ids: number[]) {
const client = useQueryClient();
return useQuery([QueryKeys.Series, ...ids], () => api.series.series(ids), {
onSuccess: (data) => {
cacheSeries(client, data);
},
const query = useQuery({
queryKey: [QueryKeys.Series, ...ids],
queryFn: () => api.series.series(ids),
});
useEffect(() => {
if (query.isSuccess && query.data) {
cacheSeries(client, query.data);
}
}, [query.isSuccess, query.data, client]);
return query;
}
export function useSeriesById(id: number) {
return useQuery([QueryKeys.Series, id], async () => {
const response = await api.series.series([id]);
return response.length > 0 ? response[0] : undefined;
return useQuery({
queryKey: [QueryKeys.Series, id],
queryFn: async () => {
const response = await api.series.series([id]);
return response.length > 0 ? response[0] : undefined;
},
});
}
export function useSeries() {
const client = useQueryClient();
return useQuery(
[QueryKeys.Series, QueryKeys.All],
() => api.series.series(),
{
onSuccess: (data) => {
cacheSeries(client, data);
},
},
);
const query = useQuery({
queryKey: [QueryKeys.Series, QueryKeys.All],
queryFn: () => api.series.series(),
});
useEffect(() => {
if (query.isSuccess && query.data) {
cacheSeries(client, query.data);
}
}, [query.isSuccess, query.data, client]);
return query;
}
export function useSeriesPagination() {
@ -51,29 +68,33 @@ export function useSeriesPagination() {
export function useSeriesModification() {
const client = useQueryClient();
return useMutation(
[QueryKeys.Series],
(form: FormType.ModifyItem) => api.series.modify(form),
{
onSuccess: (_, form) => {
form.id.forEach((v) => {
client.invalidateQueries([QueryKeys.Series, v]);
return useMutation({
mutationKey: [QueryKeys.Series],
mutationFn: (form: FormType.ModifyItem) => api.series.modify(form),
onSuccess: (_, form) => {
form.id.forEach((v) => {
client.invalidateQueries({
queryKey: [QueryKeys.Series, v],
});
client.invalidateQueries([QueryKeys.Series]);
},
});
client.invalidateQueries({
queryKey: [QueryKeys.Series],
});
},
);
});
}
export function useSeriesAction() {
const client = useQueryClient();
return useMutation(
[QueryKeys.Actions, QueryKeys.Series],
(form: FormType.SeriesAction) => api.series.action(form),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.Series]);
},
return useMutation({
mutationKey: [QueryKeys.Actions, QueryKeys.Series],
mutationFn: (form: FormType.SeriesAction) => api.series.action(form),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.Series],
});
},
);
});
}

@ -1,16 +1,28 @@
import { useIsMutating } from "react-query";
import { useIsMutating } from "@tanstack/react-query";
import { QueryKeys } from "@/apis/queries/keys";
export function useIsAnyActionRunning() {
return useIsMutating([QueryKeys.Actions]) > 0;
return (
useIsMutating({
mutationKey: [QueryKeys.Actions],
}) > 0
);
}
export function useIsMovieActionRunning() {
return useIsMutating([QueryKeys.Actions, QueryKeys.Movies]) > 0;
return (
useIsMutating({
mutationKey: [QueryKeys.Actions, QueryKeys.Movies],
}) > 0
);
}
export function useIsSeriesActionRunning() {
return useIsMutating([QueryKeys.Actions, QueryKeys.Series]) > 0;
return (
useIsMutating({
mutationKey: [QueryKeys.Actions, QueryKeys.Series],
}) > 0
);
}
export function useIsAnyMutationRunning() {

@ -1,4 +1,4 @@
import { useMutation, useQuery, useQueryClient } from "react-query";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { QueryKeys } from "@/apis/queries/keys";
import api from "@/apis/raw";
@ -8,23 +8,29 @@ export function useSubtitleAction() {
action: string;
form: FormType.ModifySubtitle;
}
return useMutation(
[QueryKeys.Subtitles],
(param: Param) => api.subtitles.modify(param.action, param.form),
{
onSuccess: (_, param) => {
client.invalidateQueries([QueryKeys.History]);
// TODO: Query less
const { type, id } = param.form;
if (type === "episode") {
client.invalidateQueries([QueryKeys.Series, id]);
} else {
client.invalidateQueries([QueryKeys.Movies, id]);
}
},
return useMutation({
mutationKey: [QueryKeys.Subtitles],
mutationFn: (param: Param) =>
api.subtitles.modify(param.action, param.form),
onSuccess: (_, param) => {
client.invalidateQueries({
queryKey: [QueryKeys.History],
});
// TODO: Query less
const { type, id } = param.form;
if (type === "episode") {
client.invalidateQueries({
queryKey: [QueryKeys.Series, id],
});
} else {
client.invalidateQueries({
queryKey: [QueryKeys.Movies, id],
});
}
},
);
});
}
export function useEpisodeSubtitleModification() {
@ -36,42 +42,48 @@ export function useEpisodeSubtitleModification() {
form: T;
}
const download = useMutation(
[QueryKeys.Subtitles, QueryKeys.Episodes],
(param: Param<FormType.Subtitle>) =>
const download = useMutation({
mutationKey: [QueryKeys.Subtitles, QueryKeys.Episodes],
mutationFn: (param: Param<FormType.Subtitle>) =>
api.episodes.downloadSubtitles(
param.seriesId,
param.episodeId,
param.form,
),
{
onSuccess: (_, param) => {
client.invalidateQueries([QueryKeys.Series, param.seriesId]);
},
onSuccess: (_, param) => {
client.invalidateQueries({
queryKey: [QueryKeys.Series, param.seriesId],
});
},
);
});
const remove = useMutation(
[QueryKeys.Subtitles, QueryKeys.Episodes],
(param: Param<FormType.DeleteSubtitle>) =>
const remove = useMutation({
mutationKey: [QueryKeys.Subtitles, QueryKeys.Episodes],
mutationFn: (param: Param<FormType.DeleteSubtitle>) =>
api.episodes.deleteSubtitles(param.seriesId, param.episodeId, param.form),
{
onSuccess: (_, param) => {
client.invalidateQueries([QueryKeys.Series, param.seriesId]);
},
onSuccess: (_, param) => {
client.invalidateQueries({
queryKey: [QueryKeys.Series, param.seriesId],
});
},
);
});
const upload = useMutation(
[QueryKeys.Subtitles, QueryKeys.Episodes],
(param: Param<FormType.UploadSubtitle>) =>
const upload = useMutation({
mutationKey: [QueryKeys.Subtitles, QueryKeys.Episodes],
mutationFn: (param: Param<FormType.UploadSubtitle>) =>
api.episodes.uploadSubtitles(param.seriesId, param.episodeId, param.form),
{
onSuccess: (_, { seriesId }) => {
client.invalidateQueries([QueryKeys.Series, seriesId]);
},
onSuccess: (_, { seriesId }) => {
client.invalidateQueries({
queryKey: [QueryKeys.Series, seriesId],
});
},
);
});
return { download, remove, upload };
}
@ -84,46 +96,54 @@ export function useMovieSubtitleModification() {
form: T;
}
const download = useMutation(
[QueryKeys.Subtitles, QueryKeys.Movies],
(param: Param<FormType.Subtitle>) =>
const download = useMutation({
mutationKey: [QueryKeys.Subtitles, QueryKeys.Movies],
mutationFn: (param: Param<FormType.Subtitle>) =>
api.movies.downloadSubtitles(param.radarrId, param.form),
{
onSuccess: (_, param) => {
client.invalidateQueries([QueryKeys.Movies, param.radarrId]);
},
onSuccess: (_, param) => {
client.invalidateQueries({
queryKey: [QueryKeys.Movies, param.radarrId],
});
},
);
});
const remove = useMutation({
mutationKey: [QueryKeys.Subtitles, QueryKeys.Movies],
const remove = useMutation(
[QueryKeys.Subtitles, QueryKeys.Movies],
(param: Param<FormType.DeleteSubtitle>) =>
mutationFn: (param: Param<FormType.DeleteSubtitle>) =>
api.movies.deleteSubtitles(param.radarrId, param.form),
{
onSuccess: (_, param) => {
client.invalidateQueries([QueryKeys.Movies, param.radarrId]);
},
onSuccess: (_, param) => {
client.invalidateQueries({
queryKey: [QueryKeys.Movies, param.radarrId],
});
},
);
});
const upload = useMutation(
[QueryKeys.Subtitles, QueryKeys.Movies],
(param: Param<FormType.UploadSubtitle>) =>
const upload = useMutation({
mutationKey: [QueryKeys.Subtitles, QueryKeys.Movies],
mutationFn: (param: Param<FormType.UploadSubtitle>) =>
api.movies.uploadSubtitles(param.radarrId, param.form),
{
onSuccess: (_, { radarrId }) => {
client.invalidateQueries([QueryKeys.Movies, radarrId]);
},
onSuccess: (_, { radarrId }) => {
client.invalidateQueries({
queryKey: [QueryKeys.Movies, radarrId],
});
},
);
});
return { download, remove, upload };
}
export function useSubtitleInfos(names: string[]) {
return useQuery([QueryKeys.Subtitles, QueryKeys.Infos, names], () =>
api.subtitles.info(names),
);
return useQuery({
queryKey: [QueryKeys.Subtitles, QueryKeys.Infos, names],
queryFn: () => api.subtitles.info(names),
});
}
export function useRefTracksByEpisodeId(
@ -131,11 +151,17 @@ export function useRefTracksByEpisodeId(
sonarrEpisodeId: number,
isEpisode: boolean,
) {
return useQuery(
[QueryKeys.Episodes, sonarrEpisodeId, QueryKeys.Subtitles, subtitlesPath],
() => api.subtitles.getRefTracksByEpisodeId(subtitlesPath, sonarrEpisodeId),
{ enabled: isEpisode },
);
return useQuery({
queryKey: [
QueryKeys.Episodes,
sonarrEpisodeId,
QueryKeys.Subtitles,
subtitlesPath,
],
queryFn: () =>
api.subtitles.getRefTracksByEpisodeId(subtitlesPath, sonarrEpisodeId),
enabled: isEpisode,
});
}
export function useRefTracksByMovieId(
@ -143,9 +169,15 @@ export function useRefTracksByMovieId(
radarrMovieId: number,
isMovie: boolean,
) {
return useQuery(
[QueryKeys.Movies, radarrMovieId, QueryKeys.Subtitles, subtitlesPath],
() => api.subtitles.getRefTracksByMovieId(subtitlesPath, radarrMovieId),
{ enabled: isMovie },
);
return useQuery({
queryKey: [
QueryKeys.Movies,
radarrMovieId,
QueryKeys.Subtitles,
subtitlesPath,
],
queryFn: () =>
api.subtitles.getRefTracksByMovieId(subtitlesPath, radarrMovieId),
enabled: isMovie,
});
}

@ -1,20 +1,18 @@
import { useMemo } from "react";
import { useMutation, useQuery, useQueryClient } from "react-query";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { QueryKeys } from "@/apis/queries/keys";
import api from "@/apis/raw";
import { Environment } from "@/utilities";
import { setAuthenticated } from "@/utilities/event";
export function useBadges() {
return useQuery(
[QueryKeys.System, QueryKeys.Badges],
() => api.badges.all(),
{
refetchOnWindowFocus: "always",
refetchInterval: 1000 * 60,
staleTime: 1000 * 10,
},
);
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.Badges],
queryFn: () => api.badges.all(),
refetchOnWindowFocus: "always",
refetchInterval: 1000 * 60,
staleTime: 1000 * 10,
});
}
export function useFileSystem(
@ -22,9 +20,10 @@ export function useFileSystem(
path: string,
enabled: boolean,
) {
return useQuery(
[QueryKeys.FileSystem, type, path],
() => {
return useQuery({
queryKey: [QueryKeys.FileSystem, type, path],
queryFn: () => {
if (type === "bazarr") {
return api.files.bazarr(path);
} else if (type === "radarr") {
@ -32,53 +31,63 @@ export function useFileSystem(
} else if (type === "sonarr") {
return api.files.sonarr(path);
}
return [];
},
{
enabled,
},
);
enabled,
});
}
export function useSystemSettings() {
return useQuery(
[QueryKeys.System, QueryKeys.Settings],
() => api.system.settings(),
{
staleTime: Infinity,
},
);
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.Settings],
queryFn: () => api.system.settings(),
staleTime: Infinity,
});
}
export function useSettingsMutation() {
const client = useQueryClient();
return useMutation(
[QueryKeys.System, QueryKeys.Settings],
(data: LooseObject) => api.system.updateSettings(data),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.System]);
client.invalidateQueries([QueryKeys.Series]);
client.invalidateQueries([QueryKeys.Episodes]);
client.invalidateQueries([QueryKeys.Movies]);
client.invalidateQueries([QueryKeys.Wanted]);
client.invalidateQueries([QueryKeys.Badges]);
},
return useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Settings],
mutationFn: (data: LooseObject) => api.system.updateSettings(data),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.System],
});
client.invalidateQueries({
queryKey: [QueryKeys.Series],
});
client.invalidateQueries({
queryKey: [QueryKeys.Episodes],
});
client.invalidateQueries({
queryKey: [QueryKeys.Movies],
});
client.invalidateQueries({
queryKey: [QueryKeys.Wanted],
});
client.invalidateQueries({
queryKey: [QueryKeys.Badges],
});
},
);
});
}
export function useServerSearch(query: string, enabled: boolean) {
return useQuery(
[QueryKeys.System, QueryKeys.Search, query],
() => api.system.search(query),
{
enabled,
},
);
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.Search, query],
queryFn: () => api.system.search(query),
enabled,
});
}
export function useSystemLogs() {
return useQuery([QueryKeys.System, QueryKeys.Logs], () => api.system.logs(), {
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.Logs],
queryFn: () => api.system.logs(),
refetchOnWindowFocus: "always",
refetchInterval: 1000 * 60,
staleTime: 1000 * 10,
@ -87,171 +96,187 @@ export function useSystemLogs() {
export function useDeleteLogs() {
const client = useQueryClient();
return useMutation(
[QueryKeys.System, QueryKeys.Logs],
() => api.system.deleteLogs(),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.System, QueryKeys.Logs]);
},
return useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Logs],
mutationFn: () => api.system.deleteLogs(),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Logs],
});
},
);
});
}
export function useSystemAnnouncements() {
return useQuery(
[QueryKeys.System, QueryKeys.Announcements],
() => api.system.announcements(),
{
refetchOnWindowFocus: "always",
refetchInterval: 1000 * 60,
staleTime: 1000 * 10,
},
);
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.Announcements],
queryFn: () => api.system.announcements(),
refetchOnWindowFocus: "always",
refetchInterval: 1000 * 60,
staleTime: 1000 * 10,
});
}
export function useSystemAnnouncementsAddDismiss() {
const client = useQueryClient();
return useMutation(
[QueryKeys.System, QueryKeys.Announcements],
(param: { hash: string }) => {
return useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Announcements],
mutationFn: (param: { hash: string }) => {
const { hash } = param;
return api.system.addAnnouncementsDismiss(hash);
},
{
onSuccess: (_, { hash }) => {
client.invalidateQueries([QueryKeys.System, QueryKeys.Announcements]);
client.invalidateQueries([QueryKeys.System, QueryKeys.Badges]);
},
onSuccess: (_, { hash }) => {
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Announcements],
});
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Badges],
});
},
);
});
}
export function useSystemTasks() {
return useQuery(
[QueryKeys.System, QueryKeys.Tasks],
() => api.system.tasks(),
{
refetchOnWindowFocus: "always",
refetchInterval: 1000 * 60,
staleTime: 1000 * 10,
},
);
return useQuery({
queryKey: [QueryKeys.System, QueryKeys.Tasks],
queryFn: () => api.system.tasks(),
refetchOnWindowFocus: "always",
refetchInterval: 1000 * 60,
staleTime: 1000 * 10,
});
}
export function useRunTask() {
const client = useQueryClient();
return useMutation(
[QueryKeys.System, QueryKeys.Tasks],
(id: string) => api.system.runTask(id),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.System, QueryKeys.Tasks]);
client.invalidateQueries([QueryKeys.System, QueryKeys.Backups]);
},
return useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Tasks],
mutationFn: (id: string) => api.system.runTask(id),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Tasks],
});
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Backups],
});
},
);
});
}
export function useSystemBackups() {
return useQuery([QueryKeys.System, "backups"], () => api.system.backups());
return useQuery({
queryKey: [QueryKeys.System, "backups"],
queryFn: () => api.system.backups(),
});
}
export function useCreateBackups() {
const client = useQueryClient();
return useMutation(
[QueryKeys.System, QueryKeys.Backups],
() => api.system.createBackups(),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.System, QueryKeys.Backups]);
},
return useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Backups],
mutationFn: () => api.system.createBackups(),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Backups],
});
},
);
});
}
export function useRestoreBackups() {
const client = useQueryClient();
return useMutation(
[QueryKeys.System, QueryKeys.Backups],
(filename: string) => api.system.restoreBackups(filename),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.System, QueryKeys.Backups]);
},
return useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Backups],
mutationFn: (filename: string) => api.system.restoreBackups(filename),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Backups],
});
},
);
});
}
export function useDeleteBackups() {
const client = useQueryClient();
return useMutation(
[QueryKeys.System, QueryKeys.Backups],
(filename: string) => api.system.deleteBackups(filename),
{
onSuccess: () => {
client.invalidateQueries([QueryKeys.System, QueryKeys.Backups]);
},
return useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Backups],
mutationFn: (filename: string) => api.system.deleteBackups(filename),
onSuccess: () => {
client.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Backups],
});
},
);
});
}
export function useSystemStatus() {
return useQuery([QueryKeys.System, "status"], () => api.system.status());
return useQuery({
queryKey: [QueryKeys.System, "status"],
queryFn: () => api.system.status(),
});
}
export function useSystemHealth() {
return useQuery([QueryKeys.System, "health"], () => api.system.health());
return useQuery({
queryKey: [QueryKeys.System, "health"],
queryFn: () => api.system.health(),
});
}
export function useSystemReleases() {
return useQuery([QueryKeys.System, "releases"], () => api.system.releases());
return useQuery({
queryKey: [QueryKeys.System, "releases"],
queryFn: () => api.system.releases(),
});
}
export function useSystem() {
const client = useQueryClient();
const { mutate: logout, isLoading: isLoggingOut } = useMutation(
[QueryKeys.System, QueryKeys.Actions],
() => api.system.logout(),
{
onSuccess: () => {
setAuthenticated(false);
client.clear();
},
const { mutate: logout, isPending: isLoggingOut } = useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Actions],
mutationFn: () => api.system.logout(),
onSuccess: () => {
setAuthenticated(false);
client.clear();
},
);
});
const { mutate: login, isLoading: isLoggingIn } = useMutation(
[QueryKeys.System, QueryKeys.Actions],
(param: { username: string; password: string }) =>
const { mutate: login, isPending: isLoggingIn } = useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Actions],
mutationFn: (param: { username: string; password: string }) =>
api.system.login(param.username, param.password),
{
onSuccess: () => {
// TODO: Hard-coded value
window.location.replace(Environment.baseUrl);
},
onSuccess: () => {
// TODO: Hard-coded value
window.location.replace(Environment.baseUrl);
},
);
});
const { mutate: shutdown, isLoading: isShuttingDown } = useMutation(
[QueryKeys.System, QueryKeys.Actions],
() => api.system.shutdown(),
{
onSuccess: () => {
client.clear();
},
const { mutate: shutdown, isPending: isShuttingDown } = useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Actions],
mutationFn: () => api.system.shutdown(),
onSuccess: () => {
client.clear();
},
);
});
const { mutate: restart, isPending: isRestarting } = useMutation({
mutationKey: [QueryKeys.System, QueryKeys.Actions],
mutationFn: () => api.system.restart(),
const { mutate: restart, isLoading: isRestarting } = useMutation(
[QueryKeys.System, QueryKeys.Actions],
() => api.system.restart(),
{
onSuccess: () => {
client.clear();
},
onSuccess: () => {
client.clear();
},
);
});
return useMemo(
() => ({

@ -4,7 +4,7 @@ import {
useQuery,
useQueryClient,
UseQueryResult,
} from "react-query";
} from "@tanstack/react-query";
import { GetItemId, useOnValueChange } from "@/utilities";
import { usePageSize } from "@/utilities/storage";
import { QueryKeys } from "./keys";
@ -39,31 +39,31 @@ export function usePaginationQuery<
const start = page * pageSize;
const results = useQuery(
[...queryKey, QueryKeys.Range, { start, size: pageSize }],
() => {
const results = useQuery({
queryKey: [...queryKey, QueryKeys.Range, { start, size: pageSize }],
queryFn: () => {
const param: Parameter.Range = {
start,
length: pageSize,
};
return queryFn(param);
},
{
onSuccess: ({ data }) => {
if (cacheIndividual) {
data.forEach((item) => {
const id = GetItemId(item);
if (id) {
client.setQueryData([...queryKey, id], item);
}
});
}
},
},
);
});
const { data } = results;
useEffect(() => {
if (results.isSuccess && results.data && cacheIndividual) {
results.data.data.forEach((item) => {
const id = GetItemId(item);
if (id) {
client.setQueryData([...queryKey, id], item);
}
});
}
}, [results.isSuccess, results.data, client, cacheIndividual, queryKey]);
const totalCount = data?.total ?? 0;
const pageCount = Math.ceil(totalCount / pageSize);

@ -1,4 +1,4 @@
import { QueryClient } from "react-query";
import { QueryClient } from "@tanstack/react-query";
const queryClient = new QueryClient({
defaultOptions: {
@ -6,7 +6,11 @@ const queryClient = new QueryClient({
refetchOnWindowFocus: false,
retry: false,
staleTime: 1000 * 60,
keepPreviousData: true,
networkMode: "offlineFirst",
placeholderData: (previousData: object) => previousData,
},
mutations: {
networkMode: "offlineFirst",
},
},
});

@ -1,5 +1,5 @@
import { useCallback, useState } from "react";
import { UseMutationResult } from "react-query";
import { UseMutationResult } from "@tanstack/react-query";
import { Action } from "@/components/inputs";
import { ActionProps } from "@/components/inputs/Action";

@ -1,6 +1,6 @@
import { useCallback, useState } from "react";
import { UseMutationResult } from "react-query";
import { Button, ButtonProps } from "@mantine/core";
import { UseMutationResult } from "@tanstack/react-query";
type MutateButtonProps<DATA, VAR> = Omit<
ButtonProps,

@ -1,6 +1,6 @@
import { FunctionComponent, ReactNode } from "react";
import { UseQueryResult } from "react-query";
import { LoadingOverlay } from "@mantine/core";
import { UseQueryResult } from "@tanstack/react-query";
import { LoadingProvider } from "@/contexts";
interface QueryOverlayProps {

@ -1,7 +1,7 @@
import { FunctionComponent, useMemo } from "react";
import { UseMutationResult } from "react-query";
import { Button, Divider, Group, LoadingOverlay, Stack } from "@mantine/core";
import { useForm } from "@mantine/form";
import { UseMutationResult } from "@tanstack/react-query";
import { useLanguageProfiles } from "@/apis/hooks";
import { MultiSelector, Selector } from "@/components/inputs";
import { useModals, withModal } from "@/modules/modals";
@ -21,7 +21,7 @@ const ItemEditForm: FunctionComponent<Props> = ({
onCancel,
}) => {
const { data, isFetching } = useLanguageProfiles();
const { isLoading, mutate } = mutation;
const { isPending, mutate } = mutation;
const modals = useModals();
const profileOptions = useSelectorOptions(
@ -47,7 +47,7 @@ const ItemEditForm: FunctionComponent<Props> = ({
(v) => v.code2,
);
const isOverlayVisible = isLoading || isFetching || item === null;
const isOverlayVisible = isPending || isFetching || item === null;
return (
<form

@ -1,5 +1,4 @@
import { useCallback, useMemo, useState } from "react";
import { UseQueryResult } from "react-query";
import { Column } from "react-table";
import {
Alert,
@ -18,6 +17,7 @@ import {
faInfoCircle,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { UseQueryResult } from "@tanstack/react-query";
import { isString } from "lodash";
import { Action, PageTable } from "@/components";
import Language from "@/components/bazarr/Language";

@ -1,4 +1,4 @@
import { onlineManager } from "react-query";
import { onlineManager } from "@tanstack/react-query";
import { debounce, forIn, remove, uniq } from "lodash";
import { io, Socket } from "socket.io-client";
import { Environment, isDevEnv, isTestEnv } from "@/utilities";

@ -40,13 +40,13 @@ export function createDefaultReducer(): SocketIO.Reducer[] {
update: (ids) => {
LOG("info", "Invalidating series", ids);
ids.forEach((id) => {
queryClient.invalidateQueries([QueryKeys.Series, id]);
queryClient.invalidateQueries({ queryKey: [QueryKeys.Series, id] });
});
},
delete: (ids) => {
LOG("info", "Invalidating series", ids);
ids.forEach((id) => {
queryClient.invalidateQueries([QueryKeys.Series, id]);
queryClient.invalidateQueries({ queryKey: [QueryKeys.Series, id] });
});
},
},
@ -55,13 +55,13 @@ export function createDefaultReducer(): SocketIO.Reducer[] {
update: (ids) => {
LOG("info", "Invalidating movies", ids);
ids.forEach((id) => {
queryClient.invalidateQueries([QueryKeys.Movies, id]);
queryClient.invalidateQueries({ queryKey: [QueryKeys.Movies, id] });
});
},
delete: (ids) => {
LOG("info", "Invalidating movies", ids);
ids.forEach((id) => {
queryClient.invalidateQueries([QueryKeys.Movies, id]);
queryClient.invalidateQueries({ queryKey: [QueryKeys.Movies, id] });
});
},
},
@ -78,10 +78,9 @@ export function createDefaultReducer(): SocketIO.Reducer[] {
id,
]);
if (episode !== undefined) {
queryClient.invalidateQueries([
QueryKeys.Series,
episode.sonarrSeriesId,
]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Series, episode.sonarrSeriesId],
});
}
});
},
@ -93,10 +92,9 @@ export function createDefaultReducer(): SocketIO.Reducer[] {
id,
]);
if (episode !== undefined) {
queryClient.invalidateQueries([
QueryKeys.Series,
episode.sonarrSeriesId,
]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Series, episode.sonarrSeriesId],
});
}
});
},
@ -105,83 +103,106 @@ export function createDefaultReducer(): SocketIO.Reducer[] {
key: "episode-wanted",
update: (ids) => {
// Find a better way to update wanted
queryClient.invalidateQueries([QueryKeys.Episodes, QueryKeys.Wanted]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Episodes, QueryKeys.Wanted],
});
},
delete: () => {
queryClient.invalidateQueries([QueryKeys.Episodes, QueryKeys.Wanted]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Episodes, QueryKeys.Wanted],
});
},
},
{
key: "movie-wanted",
update: (ids) => {
// Find a better way to update wanted
queryClient.invalidateQueries([QueryKeys.Movies, QueryKeys.Wanted]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Movies, QueryKeys.Wanted],
});
},
delete: () => {
queryClient.invalidateQueries([QueryKeys.Movies, QueryKeys.Wanted]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Movies, QueryKeys.Wanted],
});
},
},
{
key: "settings",
any: () => {
queryClient.invalidateQueries([QueryKeys.System]);
queryClient.invalidateQueries({ queryKey: [QueryKeys.System] });
},
},
{
key: "languages",
any: () => {
queryClient.invalidateQueries([QueryKeys.System, QueryKeys.Languages]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Languages],
});
},
},
{
key: "badges",
any: () => {
queryClient.invalidateQueries([QueryKeys.System, QueryKeys.Badges]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Badges],
});
},
},
{
key: "movie-history",
any: () => {
queryClient.invalidateQueries([QueryKeys.Movies, QueryKeys.History]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Movies, QueryKeys.History],
});
},
},
{
key: "movie-blacklist",
any: () => {
queryClient.invalidateQueries([QueryKeys.Movies, QueryKeys.Blacklist]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Movies, QueryKeys.Blacklist],
});
},
},
{
key: "episode-history",
any: () => {
queryClient.invalidateQueries([QueryKeys.Episodes, QueryKeys.History]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Episodes, QueryKeys.History],
});
},
},
{
key: "episode-blacklist",
any: () => {
queryClient.invalidateQueries([
QueryKeys.Episodes,
QueryKeys.Blacklist,
]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Episodes, QueryKeys.Blacklist],
});
},
},
{
key: "reset-episode-wanted",
any: () => {
queryClient.invalidateQueries([QueryKeys.Episodes, QueryKeys.Wanted]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Episodes, QueryKeys.Wanted],
});
},
},
{
key: "reset-movie-wanted",
any: () => {
queryClient.invalidateQueries([QueryKeys.Movies, QueryKeys.Wanted]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.Movies, QueryKeys.Wanted],
});
},
},
{
key: "task",
any: () => {
queryClient.invalidateQueries([QueryKeys.System, QueryKeys.Tasks]);
queryClient.invalidateQueries({
queryKey: [QueryKeys.System, QueryKeys.Tasks],
});
},
},
];

@ -1,5 +1,4 @@
import { FunctionComponent, useCallback, useMemo } from "react";
import { useMutation } from "react-query";
import {
Button,
Divider,
@ -9,6 +8,7 @@ import {
Textarea,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import { useMutation } from "@tanstack/react-query";
import { isObject } from "lodash";
import api from "@/apis/raw";
import { Selector } from "@/components";
@ -63,7 +63,9 @@ const NotificationForm: FunctionComponent<Props> = ({
},
});
const test = useMutation((url: string) => api.system.testNotification(url));
const test = useMutation({
mutationFn: (url: string) => api.system.testNotification(url),
});
return (
<form

@ -25,7 +25,7 @@ const Layout: FunctionComponent<Props> = (props) => {
const { children, name } = props;
const { data: settings, isLoading, isRefetching } = useSystemSettings();
const { mutate, isLoading: isMutating } = useSettingsMutation();
const { mutate, isPending: isMutating } = useSettingsMutation();
const form = useForm<FormValues>({
initialValues: {

@ -28,7 +28,7 @@ const LayoutModal: FunctionComponent<Props> = (props) => {
const { children, callbackModal } = props;
const { data: settings, isLoading, isRefetching } = useSystemSettings();
const { mutate, isLoading: isMutating } = useSettingsMutation();
const { mutate, isPending: isMutating } = useSettingsMutation();
const form = useForm<FormValues>({
initialValues: {

@ -10,7 +10,7 @@ import Table from "./table";
const SystemBackupsView: FunctionComponent = () => {
const backups = useSystemBackups();
const { mutate: backup, isLoading: isResetting } = useCreateBackups();
const { mutate: backup, isPending: isResetting } = useCreateBackups();
useDocumentTitle("Backups - Bazarr (System)");

@ -19,7 +19,7 @@ const SystemLogsView: FunctionComponent = () => {
const logs = useSystemLogs();
const { isFetching, data, refetch } = logs;
const { mutate, isLoading } = useDeleteLogs();
const { mutate, isPending } = useDeleteLogs();
const download = useCallback(() => {
window.open(`${Environment.baseUrl}/bazarr.log`);
@ -98,14 +98,14 @@ const SystemLogsView: FunctionComponent = () => {
Download
</Toolbox.Button>
<Toolbox.Button
loading={isLoading}
loading={isPending}
icon={faTrash}
onClick={() => mutate()}
>
Empty
</Toolbox.Button>
<Toolbox.Button
loading={isLoading}
loading={isPending}
icon={faFilter}
onClick={openFilterModal}
rightSection={

@ -12,7 +12,7 @@ const SystemProvidersView: FunctionComponent = () => {
const { isFetching, data, refetch } = providers;
const { mutate: reset, isLoading: isResetting } = useResetProvider();
const { mutate: reset, isPending: isResetting } = useResetProvider();
useDocumentTitle("Providers - Bazarr (System)");

@ -42,7 +42,7 @@ const WantedMoviesView: FunctionComponent = () => {
<Group gap="sm">
{value.map((item, idx) => (
<Badge
color={download.isLoading ? "gray" : undefined}
color={download.isPending ? "gray" : undefined}
leftSection={<FontAwesomeIcon icon={faSearch} />}
key={BuildKey(idx, item.code2)}
style={{ cursor: "pointer" }}

@ -50,7 +50,7 @@ const WantedSeriesView: FunctionComponent = () => {
<Group gap="sm">
{value.map((item, idx) => (
<Badge
color={download.isLoading ? "gray" : undefined}
color={download.isPending ? "gray" : undefined}
leftSection={<FontAwesomeIcon icon={faSearch} />}
key={BuildKey(idx, item.code2)}
style={{ cursor: "pointer" }}

@ -1,9 +1,9 @@
import { useCallback, useMemo, useState } from "react";
import { UseMutationResult } from "react-query";
import { useNavigate } from "react-router-dom";
import { Column, useRowSelect } from "react-table";
import { Box, Container } from "@mantine/core";
import { faCheck, faUndo } from "@fortawesome/free-solid-svg-icons";
import { UseMutationResult } from "@tanstack/react-query";
import { uniqBy } from "lodash";
import { useIsAnyMutationRunning, useLanguageProfiles } from "@/apis/hooks";
import { SimpleTable, Toolbox } from "@/components";

@ -1,7 +1,7 @@
import { FunctionComponent, PropsWithChildren } from "react";
import { QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
import { Notifications } from "@mantine/notifications";
import { QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import queryClient from "@/apis/queries";
import ThemeProvider from "@/App/ThemeProvider";
import { ModalsProvider } from "@/modules/modals";

Loading…
Cancel
Save