ps99-api 2.3.2 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.idea/node-ps99-api.iml +1 -0
  2. package/README.md +1 -1
  3. package/dist/responses/collection/achievement.d.ts +2 -0
  4. package/dist/responses/collection/guild-battle.d.ts +2 -4
  5. package/dist/responses/collection/rank.d.ts +1 -0
  6. package/dist/responses/collection/seed.d.ts +1 -0
  7. package/dist/responses/exists.d.ts +2 -0
  8. package/example-web/react2/public/service-worker.js +6 -6
  9. package/example-web/react2/src/App.tsx +8 -2
  10. package/example-web/react2/src/components/AchievementsComponent.tsx +23 -30
  11. package/example-web/react2/src/components/BoostsComponent.tsx +6 -13
  12. package/example-web/react2/src/components/BoothsComponent.tsx +52 -20
  13. package/example-web/react2/src/components/BoxesComponent.tsx +17 -24
  14. package/example-web/react2/src/components/BuffsComponent.tsx +35 -13
  15. package/example-web/react2/src/components/CharmsComponent.tsx +25 -30
  16. package/example-web/react2/src/components/CurrencyComponent.tsx +37 -44
  17. package/example-web/react2/src/components/DynamicCollectionConfigData.tsx +23 -4
  18. package/example-web/react2/src/components/EggsComponent.tsx +39 -44
  19. package/example-web/react2/src/components/EnchantsComponent.tsx +43 -34
  20. package/example-web/react2/src/components/FishingRodsComponent.tsx +23 -30
  21. package/example-web/react2/src/components/Footer.tsx +80 -16
  22. package/example-web/react2/src/components/FruitsComponent.tsx +18 -25
  23. package/example-web/react2/src/components/GenericFetchComponent.tsx +31 -21
  24. package/example-web/react2/src/components/GuildBattlesComponent.tsx +86 -65
  25. package/example-web/react2/src/components/HomePage.tsx +3 -1
  26. package/example-web/react2/src/components/HoverboardsComponent.tsx +100 -36
  27. package/example-web/react2/src/components/LootboxesComponent.tsx +8 -15
  28. package/example-web/react2/src/components/MasteryComponent.tsx +17 -24
  29. package/example-web/react2/src/components/MerchantsComponent.tsx +16 -23
  30. package/example-web/react2/src/components/MiscItemsComponent.tsx +32 -25
  31. package/example-web/react2/src/components/PetsComponent.tsx +74 -44
  32. package/example-web/react2/src/components/PotionsComponent.tsx +37 -36
  33. package/example-web/react2/src/components/RandomEventsComponent.tsx +30 -35
  34. package/example-web/react2/src/components/RanksComponent.tsx +58 -67
  35. package/example-web/react2/src/components/RarityComponent.tsx +7 -14
  36. package/example-web/react2/src/components/RebirthsComponent.tsx +20 -26
  37. package/example-web/react2/src/components/SecretRoomsComponent.tsx +6 -13
  38. package/example-web/react2/src/components/SeedsComponent.tsx +15 -22
  39. package/example-web/react2/src/components/ShovelsComponent.tsx +9 -16
  40. package/example-web/react2/src/components/SprinklersComponent.tsx +11 -18
  41. package/example-web/react2/src/components/UltimatesComponent.tsx +17 -24
  42. package/example-web/react2/src/components/UpgradesComponent.tsx +49 -54
  43. package/example-web/react2/src/components/WateringCansComponent.tsx +15 -19
  44. package/example-web/react2/src/components/WorldsComponent.tsx +16 -23
  45. package/example-web/react2/src/components/XPPotionsComponent.tsx +12 -19
  46. package/example-web/react2/src/components/ZoneFlagsComponent.tsx +15 -22
  47. package/example-web/react2/src/components/ZonesComponent.tsx +69 -69
  48. package/package.json +1 -1
  49. package/src/responses/collection/achievement.ts +2 -0
  50. package/src/responses/collection/guild-battle.ts +2 -4
  51. package/src/responses/collection/rank.ts +1 -0
  52. package/src/responses/collection/seed.ts +1 -0
  53. package/src/responses/exists.ts +2 -0
@@ -1,61 +1,56 @@
1
1
  import React from "react";
2
2
  import { CollectionConfigData } from "ps99-api";
3
- import { GenericFetchComponent } from "./GenericFetchComponent";
4
3
  import ImageComponent from "./ImageComponent";
5
4
 
6
5
  const EggsComponent: React.FC<{
7
- configData?: CollectionConfigData<"Eggs">;
6
+ configData: CollectionConfigData<"Eggs">;
8
7
  }> = ({ configData }) => {
9
8
  return (
10
- <GenericFetchComponent<CollectionConfigData<"Eggs">>
11
- collectionName="Eggs"
12
- configData={configData}
13
- render={(data) => (
9
+ <div>
10
+ <h2>{configData.name}</h2>
11
+ <ImageComponent src={configData.icon} alt={configData.name} />
12
+ <p>Currency: {configData.currency}</p>
13
+ <p>Override Cost: {configData.overrideCost}</p>
14
+ {configData.isCustomEgg && <p>Custom Egg: Yes</p>}
15
+ {configData.bestEgg && <p>Best Egg: Yes</p>}
16
+ {configData.disableGold && <p>Disable Gold: Yes</p>}
17
+ {configData.disableRainbow && <p>Disable Rainbow: Yes</p>}
18
+ {configData.disableShiny && <p>Disable Shiny: Yes</p>}
19
+ {configData.disableModifiers && <p>Disable Modifiers: Yes</p>}
20
+ {configData.goldChance && <p>Gold Chance: {configData.goldChance}</p>}
21
+ {configData.rainbowChance && (
22
+ <p>Rainbow Chance: {configData.rainbowChance}</p>
23
+ )}
24
+ {configData.shinyChance && <p>Shiny Chance: {configData.shinyChance}</p>}
25
+ {configData.rarity && (
26
+ <div>
27
+ <p>Rarity: {configData.rarity.DisplayName}</p>
28
+ <p>Rarity Number: {configData.rarity.RarityNumber}</p>
29
+ </div>
30
+ )}
31
+ <h3>Pets:</h3>
32
+ <ul>
33
+ {configData.pets.map((pet, index) => (
34
+ <li key={index}>
35
+ <p>Name: {pet[0]}</p>
36
+ <p>Chance: {pet[1]}</p>
37
+ {pet[2] && <p>Tier: {pet[2]}</p>}
38
+ </li>
39
+ ))}
40
+ </ul>
41
+ {configData.productIds && (
14
42
  <div>
15
- <h2>{data.name}</h2>
16
- <ImageComponent src={data.icon} alt={data.name} />
17
- <p>Currency: {data.currency}</p>
18
- <p>Override Cost: {data.overrideCost}</p>
19
- {data.isCustomEgg && <p>Custom Egg: Yes</p>}
20
- {data.bestEgg && <p>Best Egg: Yes</p>}
21
- {data.disableGold && <p>Disable Gold: Yes</p>}
22
- {data.disableRainbow && <p>Disable Rainbow: Yes</p>}
23
- {data.disableShiny && <p>Disable Shiny: Yes</p>}
24
- {data.disableModifiers && <p>Disable Modifiers: Yes</p>}
25
- {data.goldChance && <p>Gold Chance: {data.goldChance}</p>}
26
- {data.rainbowChance && <p>Rainbow Chance: {data.rainbowChance}</p>}
27
- {data.shinyChance && <p>Shiny Chance: {data.shinyChance}</p>}
28
- {data.rarity && (
29
- <div>
30
- <p>Rarity: {data.rarity.DisplayName}</p>
31
- <p>Rarity Number: {data.rarity.RarityNumber}</p>
32
- </div>
33
- )}
34
- <h3>Pets:</h3>
43
+ <h3>Product IDs:</h3>
35
44
  <ul>
36
- {data.pets.map((pet, index) => (
37
- <li key={index}>
38
- <p>Name: {pet[0]}</p>
39
- <p>Chance: {pet[1]}</p>
40
- {pet[2] && <p>Tier: {pet[2]}</p>}
45
+ {Object.entries(configData.productIds).map(([key, value]) => (
46
+ <li key={key}>
47
+ {key}: {value}
41
48
  </li>
42
49
  ))}
43
50
  </ul>
44
- {data.productIds && (
45
- <div>
46
- <h3>Product IDs:</h3>
47
- <ul>
48
- {Object.entries(data.productIds).map(([key, value]) => (
49
- <li key={key}>
50
- {key}: {value}
51
- </li>
52
- ))}
53
- </ul>
54
- </div>
55
- )}
56
51
  </div>
57
52
  )}
58
- />
53
+ </div>
59
54
  );
60
55
  };
61
56
 
@@ -1,45 +1,54 @@
1
1
  import React from "react";
2
2
  import { CollectionConfigData } from "ps99-api";
3
- import { GenericFetchComponent } from "./GenericFetchComponent";
4
3
  import ImageComponent from "./ImageComponent";
5
4
 
6
5
  const EnchantsComponent: React.FC<{
7
- configData?: CollectionConfigData<"Enchants">;
6
+ configData: CollectionConfigData<"Enchants">;
8
7
  }> = ({ configData }) => {
9
8
  return (
10
- <GenericFetchComponent<CollectionConfigData<"Enchants">>
11
- collectionName="Enchants"
12
- configData={configData}
13
- render={(data) => (
14
- <div>
15
- <h2>Enchantment</h2>
16
- {data.PageIcon && (
17
- <ImageComponent src={data.PageIcon} alt="Page Icon" />
18
- )}
19
- <p>Base Tier: {data.BaseTier}</p>
20
- <p>Max Tier: {data.MaxTier}</p>
21
- <p>Max Page: {data.MaxPage}</p>
22
- {data.DiminishPowerThreshold && (
23
- <p>Diminish Power Threshold: {data.DiminishPowerThreshold}</p>
24
- )}
25
- {data.EmpoweredBoost && <p>Empowered Boost: {data.EmpoweredBoost}</p>}
26
- {data.ProductId && <p>Product ID: {data.ProductId}</p>}
27
- <h3>Tiers:</h3>
28
- <ul>
29
- {data.Tiers.map((tier, index) => (
30
- <li key={index}>
31
- <ImageComponent src={tier.Icon} alt={tier.DisplayName} />
32
- <p>Display Name: {tier.DisplayName}</p>
33
- <p>Description: {tier.Desc}</p>
34
- <p>Power: {tier.Power}</p>
35
- <p>Rarity: {tier.Rarity.DisplayName}</p>
36
- <p>Rarity Number: {tier.Rarity.RarityNumber}</p>
37
- </li>
38
- ))}
39
- </ul>
40
- </div>
9
+ <div>
10
+ <h2>Enchantment</h2>
11
+ <p>Base Tier: {configData.BaseTier}</p>
12
+ <p>Max Tier: {configData.MaxTier}</p>
13
+ <p>Max Page: {configData.MaxPage}</p>
14
+ {configData.DiminishPowerThreshold && (
15
+ <p>Diminish Power Threshold: {configData.DiminishPowerThreshold}</p>
41
16
  )}
42
- />
17
+ {configData.EmpoweredBoost && (
18
+ <p>Empowered Boost: {configData.EmpoweredBoost}</p>
19
+ )}
20
+ {configData.ProductId && <p>Product ID: {configData.ProductId}</p>}
21
+ <h3>Tiers:</h3>
22
+ <div style={{ display: "flex", flexWrap: "wrap", gap: "1em" }}>
23
+ {configData.Tiers.map((tier, index) => (
24
+ <div
25
+ key={index}
26
+ style={{
27
+ border: "1px solid #ccc",
28
+ borderRadius: "8px",
29
+ padding: "1em",
30
+ width: "calc(33% - 1em)",
31
+ boxSizing: "border-box",
32
+ }}
33
+ >
34
+ <ImageComponent src={tier.Icon} alt={tier.DisplayName} />
35
+ <h4>{tier.DisplayName}</h4>
36
+ <p>
37
+ <strong>Description:</strong> {tier.Desc}
38
+ </p>
39
+ <p>
40
+ <strong>Power:</strong> {tier.Power}
41
+ </p>
42
+ <p>
43
+ <strong>Rarity:</strong> {tier.Rarity.DisplayName}
44
+ </p>
45
+ <p>
46
+ <strong>Rarity Number:</strong> {tier.Rarity.RarityNumber}
47
+ </p>
48
+ </div>
49
+ ))}
50
+ </div>
51
+ </div>
43
52
  );
44
53
  };
45
54
 
@@ -1,41 +1,34 @@
1
1
  import React from "react";
2
2
  import { CollectionConfigData } from "ps99-api";
3
- import { GenericFetchComponent } from "./GenericFetchComponent";
4
3
  import ImageComponent from "./ImageComponent";
5
4
 
6
5
  const FishingRodsComponent: React.FC<{
7
- configData?: CollectionConfigData<"FishingRods">;
6
+ configData: CollectionConfigData<"FishingRods">;
8
7
  }> = ({ configData }) => {
9
8
  return (
10
- <GenericFetchComponent<CollectionConfigData<"FishingRods">>
11
- collectionName="FishingRods"
12
- configData={configData}
13
- render={(data) => (
14
- <div>
15
- <h2>{data.DisplayName}</h2>
16
- <ImageComponent src={data.Icon} alt={data.DisplayName} />
17
- <p>Fishing Chance: {data.FishingChance}</p>
18
- <p>Fishing Currency Multiplier: {data.FishingCurrencyMultiplier}</p>
19
- <p>Minimum Fishing Time: {data.MinFishingTime} seconds</p>
20
- <p>
21
- Fishing Game Speed Multiplier: {data.FishingGameSpeedMultiplier}
22
- </p>
23
- <p>Bar Size: {data.BarSize}</p>
24
- <p>Associated Item ID: {data.AssociatedItemID}</p>
25
- {data.MerchantSalePrice && (
26
- <p>Merchant Sale Price: {data.MerchantSalePrice}</p>
27
- )}
28
- <h3>Fishing Odds:</h3>
29
- <ul>
30
- {data.FishingOdds.map((odds, index) => (
31
- <li key={index}>
32
- {odds[0]}: {odds[1]}%
33
- </li>
34
- ))}
35
- </ul>
36
- </div>
9
+ <div>
10
+ <h2>{configData.DisplayName}</h2>
11
+ <ImageComponent src={configData.Icon} alt={configData.DisplayName} />
12
+ <p>Fishing Chance: {configData.FishingChance}</p>
13
+ <p>Fishing Currency Multiplier: {configData.FishingCurrencyMultiplier}</p>
14
+ <p>Minimum Fishing Time: {configData.MinFishingTime} seconds</p>
15
+ <p>
16
+ Fishing Game Speed Multiplier: {configData.FishingGameSpeedMultiplier}
17
+ </p>
18
+ <p>Bar Size: {configData.BarSize}</p>
19
+ <p>Associated Item ID: {configData.AssociatedItemID}</p>
20
+ {configData.MerchantSalePrice && (
21
+ <p>Merchant Sale Price: {configData.MerchantSalePrice}</p>
37
22
  )}
38
- />
23
+ <h3>Fishing Odds:</h3>
24
+ <ul>
25
+ {configData.FishingOdds.map((odds, index) => (
26
+ <li key={index}>
27
+ {odds[0]}: {odds[1]}%
28
+ </li>
29
+ ))}
30
+ </ul>
31
+ </div>
39
32
  );
40
33
  };
41
34
 
@@ -1,12 +1,56 @@
1
- import React from "react";
1
+ import React, { useState, useEffect } from "react";
2
+ import { useOnlineStatus } from "../hooks/useOnlineStatus";
2
3
 
3
4
  const Footer: React.FC = () => {
5
+ const isOnline = useOnlineStatus();
6
+ const [lastUpdate, setLastUpdate] = useState<string | null>(null);
7
+ const [loading, setLoading] = useState(false);
8
+
9
+ const updateLastUpdate = () => {
10
+ setLastUpdate(new Date().toLocaleString());
11
+ };
12
+
13
+ useEffect(() => {
14
+ const fetchData = async () => {
15
+ setLoading(true);
16
+ // Simulate a fetch call to update lastUpdate time
17
+ await new Promise((resolve) => setTimeout(resolve, 1000));
18
+ updateLastUpdate();
19
+ setLoading(false);
20
+ };
21
+
22
+ fetchData();
23
+
24
+ window.addEventListener("online", updateLastUpdate);
25
+ window.addEventListener("offline", updateLastUpdate);
26
+
27
+ return () => {
28
+ window.removeEventListener("online", updateLastUpdate);
29
+ window.removeEventListener("offline", updateLastUpdate);
30
+ };
31
+ }, []);
32
+
4
33
  return (
5
34
  <footer
6
- style={{ textAlign: "center", padding: "1em", background: "#f8f9fa" }}
35
+ style={{
36
+ textAlign: "center",
37
+ padding: "1em",
38
+ background: "#f8f9fa",
39
+ borderTop: "1px solid #ccc",
40
+ }}
7
41
  >
8
- <div>
9
- <a href="https://badge.fury.io/js/ps99-api">
42
+ <div
43
+ style={{
44
+ display: "flex",
45
+ justifyContent: "center",
46
+ alignItems: "center",
47
+ marginBottom: "1em",
48
+ }}
49
+ >
50
+ <a
51
+ href="https://badge.fury.io/js/ps99-api"
52
+ style={{ display: "flex", alignItems: "center" }}
53
+ >
10
54
  <img
11
55
  src="https://badge.fury.io/js/ps99-api.svg"
12
56
  alt="npm version"
@@ -14,25 +58,45 @@ const Footer: React.FC = () => {
14
58
  />
15
59
  </a>
16
60
  &nbsp;
17
- <a href="https://github.com/joekiller/node-ps99-api">
61
+ <a
62
+ href="https://github.com/joekiller/node-ps99-api"
63
+ style={{ display: "flex", alignItems: "center" }}
64
+ >
18
65
  <img
19
66
  src="https://img.shields.io/badge/source-github-blue?logo=github"
20
67
  alt="GitHub source"
21
68
  height="18"
22
69
  />
23
70
  </a>
71
+ &nbsp;
72
+ <div style={{ display: "flex", alignItems: "center", height: "18px" }}>
73
+ {isOnline ? (
74
+ <span style={{ color: "green", lineHeight: "18px" }}>● Online</span>
75
+ ) : (
76
+ <span style={{ color: "red", lineHeight: "18px" }}>● Offline</span>
77
+ )}
78
+ </div>
79
+ </div>
80
+ <div style={{ marginBottom: "1em" }}>
81
+ {loading ? (
82
+ <span>♻️ Loading...</span>
83
+ ) : (
84
+ <span>Last update: {lastUpdate}</span>
85
+ )}
86
+ </div>
87
+ <div>
88
+ <p>
89
+ &copy; {new Date().getFullYear()} Joseph "
90
+ <a
91
+ href="https://joekiller.com"
92
+ target="_blank"
93
+ rel="noopener noreferrer"
94
+ >
95
+ joekiller
96
+ </a>
97
+ " Lawson. All rights reserved.
98
+ </p>
24
99
  </div>
25
- <p>
26
- &copy; {new Date().getFullYear()} Joseph "
27
- <a
28
- href="https://joekiller.com"
29
- target="_blank"
30
- rel="noopener noreferrer"
31
- >
32
- joekiller
33
- </a>
34
- " Lawson. All rights reserved.
35
- </p>
36
100
  </footer>
37
101
  );
38
102
  };
@@ -1,35 +1,28 @@
1
1
  import React from "react";
2
2
  import { CollectionConfigData } from "ps99-api";
3
- import { GenericFetchComponent } from "./GenericFetchComponent";
4
3
  import ImageComponent from "./ImageComponent";
5
4
 
6
5
  const FruitsComponent: React.FC<{
7
- configData?: CollectionConfigData<"Fruits">;
6
+ configData: CollectionConfigData<"Fruits">;
8
7
  }> = ({ configData }) => {
9
8
  return (
10
- <GenericFetchComponent<CollectionConfigData<"Fruits">>
11
- collectionName="Fruits"
12
- configData={configData}
13
- render={(data) => (
14
- <div>
15
- <h2>{data.DisplayName}</h2>
16
- <ImageComponent src={data.Icon} alt={data.DisplayName} />
17
- <p>Duration: {data.Duration} seconds</p>
18
- <p>Rarity: {data.Rarity.DisplayName}</p>
19
- <p>Rarity Number: {data.Rarity.RarityNumber}</p>
20
- {data.Desc && <p>Description: {data.Desc}</p>}
21
- {data.IgnoreFruitMachine && <p>Ignore Fruit Machine: Yes</p>}
22
- <h3>Boosts:</h3>
23
- <ul>
24
- {data.Boost.map((boost, index) => (
25
- <li key={index}>
26
- {boost.Type}: {boost.Amount}
27
- </li>
28
- ))}
29
- </ul>
30
- </div>
31
- )}
32
- />
9
+ <div>
10
+ <h2>{configData.DisplayName}</h2>
11
+ <ImageComponent src={configData.Icon} alt={configData.DisplayName} />
12
+ <p>Duration: {configData.Duration} seconds</p>
13
+ <p>Rarity: {configData.Rarity.DisplayName}</p>
14
+ <p>Rarity Number: {configData.Rarity.RarityNumber}</p>
15
+ {configData.Desc && <p>Description: {configData.Desc}</p>}
16
+ {configData.IgnoreFruitMachine && <p>Ignore Fruit Machine: Yes</p>}
17
+ <h3>Boosts:</h3>
18
+ <ul>
19
+ {configData.Boost.map((boost, index) => (
20
+ <li key={index}>
21
+ {boost.Type}: {boost.Amount}
22
+ </li>
23
+ ))}
24
+ </ul>
25
+ </div>
33
26
  );
34
27
  };
35
28
 
@@ -1,45 +1,55 @@
1
1
  import React, { useEffect, useState, ReactNode } from "react";
2
- import { useParams } from "react-router-dom";
3
2
  import { PetSimulator99API, ApiResponseBody, CollectionName } from "ps99-api";
4
3
 
5
4
  interface GenericFetchComponentProps<T> {
6
5
  collectionName: CollectionName;
6
+ configName: string;
7
7
  render: (data: T) => ReactNode;
8
- configData?: T;
9
8
  }
10
9
 
11
10
  export const GenericFetchComponent = <T,>({
12
11
  collectionName,
12
+ configName,
13
13
  render,
14
- configData,
15
14
  }: GenericFetchComponentProps<T>) => {
16
- const { configName } = useParams<{ configName: string }>();
17
- const [data, setData] = useState<T | null>(configData || null);
15
+ const [data, setData] = useState<T | null>(null);
18
16
  const [error, setError] = useState<string | null>(null);
19
17
 
20
18
  useEffect(() => {
21
- if (configData) return;
19
+ let isMounted = true;
22
20
 
23
21
  const fetchData = async () => {
24
- if (!configName) return;
25
- const api = new PetSimulator99API();
26
- const response: ApiResponseBody<any[]> =
27
- await api.getCollection(collectionName);
28
- if (response.status === "ok") {
29
- const item = response.data.find(
30
- (item) => item.configName === configName,
31
- );
32
- if (item) {
33
- setData(item.configData);
34
- } else {
35
- setError("Configuration not found");
22
+ try {
23
+ const api = new PetSimulator99API();
24
+ const response: ApiResponseBody<any[]> =
25
+ await api.getCollection(collectionName);
26
+ if (isMounted) {
27
+ if (response.status === "ok") {
28
+ const item = response.data.find(
29
+ (item) => item.configName === configName,
30
+ );
31
+ if (item) {
32
+ setData(item.configData);
33
+ } else {
34
+ setError("Configuration not found");
35
+ }
36
+ } else {
37
+ setError(response.error.message);
38
+ }
39
+ }
40
+ } catch (err) {
41
+ if (isMounted) {
42
+ setError(err.message);
36
43
  }
37
- } else {
38
- setError(response.error.message);
39
44
  }
40
45
  };
46
+
41
47
  fetchData();
42
- }, [collectionName, configName, configData]);
48
+
49
+ return () => {
50
+ isMounted = false;
51
+ };
52
+ }, [collectionName, configName]);
43
53
 
44
54
  if (error) {
45
55
  return <div>Error: {error}</div>;