@jeremyckahn/farmhand 1.23.2 → 1.23.4

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 (169) hide show
  1. package/README.md +5 -0
  2. package/dist/assets/index-4ynbl-GC.js +392 -0
  3. package/dist/assets/index-4ynbl-GC.js.map +1 -0
  4. package/dist/assets/index-CaYdR-lC.css +1 -0
  5. package/dist/assets/jersey-10-latin-400-normal-DrL73VYW.woff2 +0 -0
  6. package/dist/assets/jersey-10-latin-ext-400-normal-uIKqQSaG.woff2 +0 -0
  7. package/dist/assets/jersey-20-latin-400-normal-bNi78tgO.woff2 +0 -0
  8. package/dist/assets/jersey-20-latin-ext-400-normal-BO3lmWef.woff2 +0 -0
  9. package/dist/assets/jersey-25-latin-400-normal-BuYJnnt7.woff2 +0 -0
  10. package/dist/assets/jersey-25-latin-ext-400-normal-CP5Jl3WN.woff2 +0 -0
  11. package/dist/index.html +2 -2
  12. package/dist/service-worker.js +1 -1
  13. package/dist/service-worker.js.map +1 -1
  14. package/package.json +7 -12
  15. package/src/common/services/randomNumber.test.ts +61 -1
  16. package/src/common/services/randomNumber.ts +36 -1
  17. package/src/common/utils.ts +22 -13
  18. package/src/components/AccountingView/AccountingView.tsx +7 -13
  19. package/src/components/Achievement/Achievement.tsx +2 -15
  20. package/src/components/AchievementsView/AchievementsView.tsx +2 -7
  21. package/src/components/AnimatedNumber/AnimatedNumber.tsx +0 -6
  22. package/src/components/AppBar/AppBar.tsx +21 -17
  23. package/src/components/Cellar/Cellar.tsx +0 -2
  24. package/src/components/Cellar/CellarInventoryTabPanel.tsx +0 -6
  25. package/src/components/Cellar/FermentationTabPanel.tsx +0 -6
  26. package/src/components/Cellar/Keg.tsx +0 -5
  27. package/src/components/Cellar/TabPanel/index.tsx +0 -7
  28. package/src/components/Cellar/WinemakingTabPanel.tsx +0 -6
  29. package/src/components/ContextPane/ContextPane.tsx +0 -6
  30. package/src/components/CowCard/Bloodline/Bloodline.tsx +0 -6
  31. package/src/components/CowCard/CowCard.tsx +7 -39
  32. package/src/components/CowCard/Subheader/Subheader.tsx +21 -44
  33. package/src/components/CowPen/Cow.tsx +5 -11
  34. package/src/components/CowPen/CowPen.test.tsx +4 -4
  35. package/src/components/CowPen/CowPen.tsx +5 -16
  36. package/src/components/CowPenContextMenu/CowPenContextMenu.tsx +2 -18
  37. package/src/components/CowPenContextMenu/TabPanel/index.tsx +0 -7
  38. package/src/components/Farmhand/Farmhand.context.tsx +4 -3
  39. package/src/components/Farmhand/Farmhand.tsx +11 -15
  40. package/src/components/Farmhand/FarmhandReducers.tsx +1 -2
  41. package/src/components/Farmhand/FarmhandService.test.ts +6 -9
  42. package/src/components/Farmhand/hooks/useFarmhandDayAdvancement.ts +2 -6
  43. package/src/components/Farmhand/hooks/useFarmhandNetwork.test.ts +2 -2
  44. package/src/components/Farmhand/hooks/useFarmhandNetwork.ts +15 -31
  45. package/src/components/Farmhand/useFarmhand.test.ts +7 -5
  46. package/src/components/Farmhand/useFarmhand.ts +24 -15
  47. package/src/components/FermentationRecipeList/FermentationRecipe.tsx +0 -5
  48. package/src/components/FermentationRecipeList/FermentationRecipeList.test.tsx +10 -11
  49. package/src/components/FermentationRecipeList/FermentationRecipeList.tsx +2 -3
  50. package/src/components/Field/Field.tsx +15 -50
  51. package/src/components/Forest/Forest.tsx +10 -7
  52. package/src/components/ForestPlot/ForestPlot.tsx +5 -5
  53. package/src/components/ForestQuickSelect/ForestQuickSelect.tsx +0 -12
  54. package/src/components/Home/Home.tsx +2 -7
  55. package/src/components/Home/SnowBackground.tsx +1 -1
  56. package/src/components/IngredientsList/IngredientsList.tsx +0 -7
  57. package/src/components/Inventory/Inventory.test.tsx +4 -4
  58. package/src/components/Inventory/Inventory.tsx +5 -12
  59. package/src/components/Item/Item.tsx +11 -29
  60. package/src/components/ItemList/ItemList.tsx +4 -11
  61. package/src/components/KeybindingsView/KeybindingsView.tsx +0 -2
  62. package/src/components/LogView/LogView.tsx +6 -28
  63. package/src/components/Navigation/DayAndProgressContainer.tsx +0 -8
  64. package/src/components/Navigation/Navigation.tsx +12 -33
  65. package/src/components/NotificationSystem/NotificationSystem.test.tsx +45 -3
  66. package/src/components/NotificationSystem/NotificationSystem.tsx +45 -32
  67. package/src/components/OnlinePeersView/OnlinePeer/OnlinePeer.test.tsx +2 -2
  68. package/src/components/OnlinePeersView/OnlinePeer/OnlinePeer.tsx +0 -11
  69. package/src/components/OnlinePeersView/OnlinePeersView.tsx +0 -10
  70. package/src/components/PixelIcon/createPixelIcon.test.tsx +59 -0
  71. package/src/components/PixelIcon/createPixelIcon.tsx +97 -0
  72. package/src/components/PixelIcon/icons.ts +445 -0
  73. package/src/components/PixelIcon/index.ts +3 -0
  74. package/src/components/Plot/Plot.tsx +3 -3
  75. package/src/components/PriceEventView/PriceEventView.tsx +0 -6
  76. package/src/components/ProgressBar/ProgressBar.tsx +9 -8
  77. package/src/components/QuantityInput/QuantityInput.tsx +6 -11
  78. package/src/components/QuickSelect/QuickSelect.tsx +0 -10
  79. package/src/components/Recipe/Recipe.tsx +0 -9
  80. package/src/components/RecipeList/RecipeList.tsx +0 -6
  81. package/src/components/SearchBar/SearchBar.tsx +4 -10
  82. package/src/components/SettingsView/RandomSeedInput.test.tsx +2 -4
  83. package/src/components/SettingsView/RandomSeedInput.tsx +5 -8
  84. package/src/components/SettingsView/SettingsView.test.tsx +21 -0
  85. package/src/components/SettingsView/SettingsView.tsx +24 -18
  86. package/src/components/Shop/Shop.tsx +0 -20
  87. package/src/components/Shop/TabPanel/index.tsx +0 -7
  88. package/src/components/Stage/Stage.tsx +11 -20
  89. package/src/components/StatsView/StatsView.tsx +0 -18
  90. package/src/components/TierPurchase/TierPurchase.tsx +0 -12
  91. package/src/components/Toolbelt/Toolbelt.tsx +5 -10
  92. package/src/components/UpdateNotifier/UpdateNotifier.tsx +33 -5
  93. package/src/components/UpgradePurchase/UpgradePurchase.tsx +0 -10
  94. package/src/components/WineRecipeList/WineRecipe.test.tsx +2 -2
  95. package/src/components/WineRecipeList/WineRecipe.tsx +0 -5
  96. package/src/components/WineRecipeList/WineRecipeList.tsx +2 -3
  97. package/src/components/Workshop/ForgeTabPanel.tsx +0 -8
  98. package/src/components/Workshop/KitchenTabPanel.tsx +0 -7
  99. package/src/components/Workshop/RecyclingTabPanel.tsx +0 -7
  100. package/src/components/Workshop/TabPanel/index.tsx +0 -7
  101. package/src/components/Workshop/WoodChipperTabPanel.tsx +0 -7
  102. package/src/components/Workshop/Workshop.tsx +0 -9
  103. package/src/components/Workshop/getUpgradesAvailable.ts +1 -1
  104. package/src/constants.ts +18 -13
  105. package/src/data/crops/grape.ts +13 -15
  106. package/src/data/maps.test.ts +3 -4
  107. package/src/data/maps.ts +27 -29
  108. package/src/enums.ts +47 -19
  109. package/src/factories/OreFactory.ts +2 -1
  110. package/src/farmhand.d.ts +6 -3
  111. package/src/game-logic/reducers/applyPrecipitation.ts +4 -4
  112. package/src/game-logic/reducers/generatePriceEvents.ts +6 -3
  113. package/src/game-logic/reducers/harvestForestPlot.ts +1 -2
  114. package/src/game-logic/reducers/makeFermentationRecipe.ts +2 -3
  115. package/src/game-logic/reducers/minePlot.test.ts +2 -2
  116. package/src/game-logic/reducers/minePlot.ts +1 -1
  117. package/src/game-logic/reducers/processCowFertilizerProduction.test.ts +16 -14
  118. package/src/game-logic/reducers/processFeedingCows.test.ts +2 -5
  119. package/src/game-logic/reducers/purchaseCow.ts +2 -7
  120. package/src/game-logic/reducers/showNotification.test.ts +20 -0
  121. package/src/game-logic/reducers/showNotification.ts +4 -2
  122. package/src/game-logic/reducers/updateAchievements.ts +1 -1
  123. package/src/game-logic/reducers/updateFinancialRecords.test.ts +21 -25
  124. package/src/game-logic/reducers/updateFinancialRecords.ts +2 -5
  125. package/src/game-logic/reducers/updateInventoryRecordsForNextDay.test.ts +12 -14
  126. package/src/handlers/ui-events.test.ts +44 -42
  127. package/src/handlers/ui-events.tsx +18 -3
  128. package/src/hooks/usePrefersReducedMotion.ts +10 -6
  129. package/src/index.tsx +0 -2
  130. package/src/mui-theme.ts +258 -37
  131. package/src/scripts/generate-crop-table.ts +3 -2
  132. package/src/setupTests.ts +18 -12
  133. package/src/strings.ts +1 -1
  134. package/src/styles/fonts.ts +73 -0
  135. package/src/styles/pixel.ts +151 -0
  136. package/src/styles/sx.ts +46 -33
  137. package/src/styles/tokens.ts +11 -0
  138. package/src/test-utils/index.ts +1 -0
  139. package/src/utils/chooseRandom.ts +4 -1
  140. package/src/utils/chooseRandomIndex.ts +6 -2
  141. package/src/utils/getCowImage.ts +22 -27
  142. package/src/utils/getMaxYieldOfFermentationRecipe.ts +2 -2
  143. package/src/utils/getPeerMetadata.ts +1 -1
  144. package/src/utils/getPlotImage.test.ts +14 -14
  145. package/src/utils/getPlotImage.ts +10 -10
  146. package/src/utils/getRandomUnlockedCrop.ts +5 -3
  147. package/src/utils/getRandomizedLifespan.test.ts +2 -8
  148. package/src/utils/getValueAdjustmentStream.test.ts +9 -0
  149. package/src/utils/getValueAdjustmentStream.ts +5 -0
  150. package/src/utils/isItemAFarmProduct.ts +2 -2
  151. package/src/utils/shouldPrecipitateToday.ts +3 -1
  152. package/src/utils/shouldStormToday.ts +2 -1
  153. package/src/utils/transformStateDataForImport.ts +3 -5
  154. package/dist/assets/francois-one-latin-400-normal-DD1rFI7H.woff2 +0 -0
  155. package/dist/assets/francois-one-latin-400-normal-DNXs7uOx.woff +0 -0
  156. package/dist/assets/francois-one-latin-ext-400-normal-CwRdWRZD.woff2 +0 -0
  157. package/dist/assets/francois-one-latin-ext-400-normal-JvkpT0Av.woff +0 -0
  158. package/dist/assets/francois-one-vietnamese-400-normal-BLIKeG5Y.woff2 +0 -0
  159. package/dist/assets/francois-one-vietnamese-400-normal-CuWeHlXs.woff +0 -0
  160. package/dist/assets/index-CNcrTYN-.css +0 -1
  161. package/dist/assets/index-DNPchtK9.js +0 -844
  162. package/dist/assets/index-DNPchtK9.js.map +0 -1
  163. package/dist/assets/public-sans-latin-400-normal-8Rpg0ruU.woff2 +0 -0
  164. package/dist/assets/public-sans-latin-400-normal-SBbinRkI.woff +0 -0
  165. package/dist/assets/public-sans-latin-ext-400-normal-B02wwOdZ.woff +0 -0
  166. package/dist/assets/public-sans-latin-ext-400-normal-mk90oQqJ.woff2 +0 -0
  167. package/dist/assets/public-sans-vietnamese-400-normal-BO1meqcx.woff +0 -0
  168. package/dist/assets/public-sans-vietnamese-400-normal-TxZB8OSn.woff2 +0 -0
  169. package/src/fontsource.d.ts +0 -3
@@ -21,13 +21,15 @@ const setWindowHeight = (height: number) => {
21
21
  }
22
22
 
23
23
  const getIsMenuOpen = () =>
24
- ((window as unknown) as { farmhand: { state: farmhand.state } }).farmhand
25
- .state.isMenuOpen
24
+ (window as unknown as { farmhand: { state: farmhand.state } }).farmhand.state
25
+ .isMenuOpen
26
26
 
27
27
  const setIsMenuOpen = (isMenuOpen: boolean) =>
28
- ((window as unknown) as {
29
- farmhand: { setState: (state: Partial<farmhand.state>) => void }
30
- }).farmhand.setState({ isMenuOpen })
28
+ (
29
+ window as unknown as {
30
+ farmhand: { setState: (state: Partial<farmhand.state>) => void }
31
+ }
32
+ ).farmhand.setState({ isMenuOpen })
31
33
 
32
34
  // Simulates a sidebar input having focus, e.g. mid-typing, without depending
33
35
  // on any particular Farmhand-rendered input existing in the current view.
@@ -5,10 +5,12 @@ import { v4 as uuid } from 'uuid'
5
5
 
6
6
  import * as reducers from '../../game-logic/reducers/index.js'
7
7
  import eventHandlers from '../../handlers/ui-events.js'
8
+ import { randomNumberService } from '../../common/services/randomNumber.js'
8
9
 
9
10
  import {
10
11
  DEFAULT_ROOM,
11
12
  INITIAL_STORAGE_LIMIT,
13
+ NOTIFICATION_DURATION_DEFAULT,
12
14
  STAGE_TITLE_MAP,
13
15
  STANDARD_LOAN_AMOUNT,
14
16
  } from '../../constants.js'
@@ -16,6 +18,7 @@ import { scarecrow } from '../../data/items.js'
16
18
  import {
17
19
  dialogView,
18
20
  fieldMode,
21
+ randomStream,
19
22
  stageFocusType,
20
23
  toolLevel,
21
24
  toolType,
@@ -125,6 +128,7 @@ export const useFarmhand = (props: FarmhandProps) => {
125
128
  latestNotification: null,
126
129
  newDayNotifications: [],
127
130
  notificationLog: [],
131
+ notificationDuration: NOTIFICATION_DURATION_DEFAULT,
128
132
  peers: {},
129
133
  peerRoom: null,
130
134
  pendingPeerMessages: [],
@@ -252,12 +256,8 @@ export const useFarmhand = (props: FarmhandProps) => {
252
256
  const instanceProxyRef = useRef<any>(null)
253
257
 
254
258
  // Call sub-hooks
255
- const {
256
- openDialogView,
257
- closeDialogView,
258
- focusNextView,
259
- focusPreviousView,
260
- } = useFarmhandNavigation(setState, viewList)
259
+ const { openDialogView, closeDialogView, focusNextView, focusPreviousView } =
260
+ useFarmhandNavigation(setState, viewList)
261
261
 
262
262
  // Mirrors the current view into the URL hash's `view` query param, using
263
263
  // pushState (not replaceState) so each in-app view change is a real,
@@ -351,15 +351,15 @@ export const useFarmhand = (props: FarmhandProps) => {
351
351
  nextDayStateRef
352
352
  )
353
353
 
354
- const {
355
- showInventoryFullNotifications,
356
- showRecipeLearnedNotifications,
357
- } = useFarmhandNotifications(state, boundReducersRef)
354
+ const { showInventoryFullNotifications, showRecipeLearnedNotifications } =
355
+ useFarmhandNotifications(state, boundReducersRef)
358
356
 
359
357
  // Instance proxy to mimic the legacy class "this" so ui-events.tsx can run unmodified
360
358
  // eslint-disable-next-line react-hooks/exhaustive-deps
361
359
  const instanceProxy = useMemo(
362
360
  () => ({
361
+ queueRandomNumbers: (stream: randomStream, numbers: number[]) =>
362
+ randomNumberService.queueRandomNumbers(stream, numbers),
363
363
  state,
364
364
  props,
365
365
  viewTitle,
@@ -394,8 +394,18 @@ export const useFarmhand = (props: FarmhandProps) => {
394
394
  boundReducersRef.current.purchaseItem(item, quantity),
395
395
  sellItem: (item: any, quantity: number) =>
396
396
  boundReducersRef.current.sellItem(item, quantity),
397
- showNotification: (msg: string, sev?: string, onClick?: () => void) =>
398
- boundReducersRef.current.showNotification(msg, sev, onClick),
397
+ showNotification: (
398
+ msg: string,
399
+ sev?: string,
400
+ onClick?: () => void,
401
+ actionLabel?: string
402
+ ) =>
403
+ boundReducersRef.current.showNotification(
404
+ msg,
405
+ sev,
406
+ onClick,
407
+ actionLabel
408
+ ),
399
409
  prependPendingPeerMessage: (msg: string, sev?: string) =>
400
410
  boundReducersRef.current.prependPendingPeerMessage(msg, sev),
401
411
  forRange: (
@@ -582,9 +592,8 @@ export const useFarmhand = (props: FarmhandProps) => {
582
592
  ...persistedState,
583
593
  })
584
594
  const { isCombineEnabled, newDayNotifications } = sanitizedState
585
- const restoredStageFocus = getValidatedStageFocusFromHash(
586
- sanitizedState
587
- )
595
+ const restoredStageFocus =
596
+ getValidatedStageFocusFromHash(sanitizedState)
588
597
 
589
598
  setState(previous => ({
590
599
  ...previous,
@@ -1,5 +1,4 @@
1
1
  import React, { useContext, useEffect, useState } from 'react'
2
- import { object } from 'prop-types'
3
2
  import Card from '@mui/material/Card/index.js'
4
3
  import CardHeader from '@mui/material/CardHeader/index.js'
5
4
  import CardActions from '@mui/material/CardActions/index.js'
@@ -141,7 +140,3 @@ export const FermentationRecipe = ({ item }: { item: farmhand.item }) => {
141
140
  </Card>
142
141
  )
143
142
  }
144
-
145
- FermentationRecipe.propTypes = {
146
- item: object.isRequired,
147
- }
@@ -30,7 +30,8 @@ const FermentationRecipeListStub = ({
30
30
  } = {}) => {
31
31
  const contextValue = createContextData()
32
32
 
33
- contextValue.gameState.levelEntitlements = levelEntitlements as farmhand.levelEntitlements
33
+ contextValue.gameState.levelEntitlements =
34
+ levelEntitlements as farmhand.levelEntitlements
34
35
  return (
35
36
  <FarmhandContext.Provider value={contextValue}>
36
37
  <FermentationRecipeList />
@@ -55,9 +56,8 @@ describe('FermentationRecipeList', () => {
55
56
 
56
57
  render(<FermentationRecipeListStub levelEntitlements={levelEntitlements} />)
57
58
 
58
- const cropsAvailableToFerment = getCropsAvailableToFerment(
59
- levelEntitlements
60
- )
59
+ const cropsAvailableToFerment =
60
+ getCropsAvailableToFerment(levelEntitlements)
61
61
 
62
62
  const header = screen.getByText(
63
63
  `Available Fermentation Recipes (${cropsAvailableToFerment.length} / ${totalFermentableItems})`
@@ -68,9 +68,8 @@ describe('FermentationRecipeList', () => {
68
68
 
69
69
  test('filters recipes based on search query', async () => {
70
70
  const levelEntitlements = getLevelEntitlements(100)
71
- const cropsAvailableToFerment = getCropsAvailableToFerment(
72
- levelEntitlements
73
- )
71
+ const cropsAvailableToFerment =
72
+ getCropsAvailableToFerment(levelEntitlements)
74
73
 
75
74
  render(<FermentationRecipeListStub levelEntitlements={levelEntitlements} />)
76
75
 
@@ -84,7 +83,8 @@ describe('FermentationRecipeList', () => {
84
83
 
85
84
  const filteredCrops = cropsAvailableToFerment.filter(item => {
86
85
  const itemWithName = item as farmhand.item & { name: string }
87
- const fermentationRecipeName = `Fermented ${itemWithName.name}`.toLowerCase()
86
+ const fermentationRecipeName =
87
+ `Fermented ${itemWithName.name}`.toLowerCase()
88
88
 
89
89
  return (
90
90
  fermentationRecipeName.includes('apple') ||
@@ -113,9 +113,8 @@ describe('FermentationRecipeList', () => {
113
113
 
114
114
  test('handles empty search query', async () => {
115
115
  const levelEntitlements = getLevelEntitlements(100)
116
- const cropsAvailableToFerment = getCropsAvailableToFerment(
117
- levelEntitlements
118
- )
116
+ const cropsAvailableToFerment =
117
+ getCropsAvailableToFerment(levelEntitlements)
119
118
 
120
119
  render(<FermentationRecipeListStub levelEntitlements={levelEntitlements} />)
121
120
 
@@ -28,7 +28,8 @@ export const FermentationRecipeList = () => {
28
28
 
29
29
  const filteredCrops = cropsAvailableToFerment.filter(item => {
30
30
  const itemWithName = item as farmhand.item & { name: string }
31
- const fermentationRecipeName = `${FERMENTED_CROP_NAME}${itemWithName.name}`.toLowerCase()
31
+ const fermentationRecipeName =
32
+ `${FERMENTED_CROP_NAME}${itemWithName.name}`.toLowerCase()
32
33
 
33
34
  return searchTerms.every(
34
35
  term =>
@@ -63,5 +64,3 @@ export const FermentationRecipeList = () => {
63
64
  </>
64
65
  )
65
66
  }
66
-
67
- FermentationRecipeList.propTypes = {}
@@ -1,5 +1,3 @@
1
- import ZoomInIcon from '@mui/icons-material/ZoomIn.js'
2
- import ZoomOutIcon from '@mui/icons-material/ZoomOut.js'
3
1
  import Fab from '@mui/material/Fab/index.js'
4
2
  import FormControl from '@mui/material/FormControl/index.js'
5
3
  import FormControlLabel from '@mui/material/FormControlLabel/index.js'
@@ -10,11 +8,12 @@ import Switch from '@mui/material/Switch/index.js'
10
8
  import Tooltip from '@mui/material/Tooltip/index.js'
11
9
  import Typography from '@mui/material/Typography/index.js'
12
10
  import classNames from 'classnames'
13
- import { array, bool, element, func, number, object, string } from 'prop-types'
14
11
  import React, { memo, useEffect, useState } from 'react'
15
12
  import { GlobalHotKeys } from 'react-hotkeys'
16
13
  import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch'
17
14
 
15
+ import { ZoomInIcon, ZoomOutIcon } from '../PixelIcon/index.js'
16
+
18
17
  import {
19
18
  basicLightningRod,
20
19
  superiorLightningRod,
@@ -271,10 +270,6 @@ export const FieldContentWrapper = ({
271
270
  )
272
271
  }
273
272
 
274
- FieldContentWrapper.propTypes = {
275
- fieldContent: element.isRequired,
276
- }
277
-
278
273
  export const FieldContent = ({
279
274
  columns = 0,
280
275
  experience,
@@ -339,20 +334,6 @@ export const FieldContent = ({
339
334
  </>
340
335
  )
341
336
 
342
- FieldContent.propTypes = {
343
- columns: number.isRequired,
344
- experience: number.isRequired,
345
- field: array.isRequired,
346
- fieldMode: string.isRequired,
347
- handleCombineEnabledChange: func.isRequired,
348
- hoveredPlot: object.isRequired,
349
- hoveredPlotRangeSize: number.isRequired,
350
- isCombineEnabled: bool.isRequired,
351
- purchasedCombine: number.isRequired,
352
- rows: number.isRequired,
353
- setHoveredPlot: func.isRequired,
354
- }
355
-
356
337
  const adjustableRangeFieldModes = new Set<string>([
357
338
  CLEANUP,
358
339
  FERTILIZE,
@@ -597,10 +578,11 @@ export const Field = (props: FieldProps) => {
597
578
  backgroundColor: colorYellow,
598
579
  cursor: 'pointer',
599
580
  },
600
- '&.harvest-mode.is-inventory-full .Plot.crop.can-be-harvested, &.cleanup-mode.is-inventory-full .Plot.is-replantable': {
601
- backgroundColor: colorRedDanger,
602
- cursor: 'not-allowed',
603
- },
581
+ '&.harvest-mode.is-inventory-full .Plot.crop.can-be-harvested, &.cleanup-mode.is-inventory-full .Plot.is-replantable':
582
+ {
583
+ backgroundColor: colorRedDanger,
584
+ cursor: 'not-allowed',
585
+ },
604
586
  '&.cleanup-mode .Plot.is-replantable': {
605
587
  backgroundColor: colorGreenOk,
606
588
  cursor: 'pointer',
@@ -609,14 +591,15 @@ export const Field = (props: FieldProps) => {
609
591
  backgroundColor: colorGreenOk,
610
592
  cursor: 'auto',
611
593
  },
612
- '&.set-sprinkler-mode:hover .Plot:hover, &.set-scarecrow-mode:hover .Plot:hover, &.set-lightning-rod-mode:hover .Plot:hover': {
613
- '&.is-empty img': { cursor: 'pointer', opacity: 0.5 },
614
- '&:not(.is-empty)': {
615
- backgroundColor: colorRedDanger,
616
- backgroundImage: 'none',
617
- cursor: 'not-allowed',
594
+ '&.set-sprinkler-mode:hover .Plot:hover, &.set-scarecrow-mode:hover .Plot:hover, &.set-lightning-rod-mode:hover .Plot:hover':
595
+ {
596
+ '&.is-empty img': { cursor: 'pointer', opacity: 0.5 },
597
+ '&:not(.is-empty)': {
598
+ backgroundColor: colorRedDanger,
599
+ backgroundImage: 'none',
600
+ cursor: 'not-allowed',
601
+ },
618
602
  },
619
- },
620
603
  '&.set-sprinkler-mode:hover .Plot:hover.is-empty img': {
621
604
  backgroundImage: `url(${sprinklerImg})`,
622
605
  },
@@ -699,24 +682,6 @@ export const Field = (props: FieldProps) => {
699
682
  )
700
683
  }
701
684
 
702
- Field.propTypes = {
703
- columns: number.isRequired,
704
- experience: number.isRequired,
705
- field: array.isRequired,
706
- fieldMode: string.isRequired,
707
- handleCombineEnabledChange: func.isRequired,
708
- handleFieldActionRangeChange: func.isRequired,
709
- hoveredPlotRangeSize: number.isRequired,
710
- inventory: array.isRequired,
711
- inventoryLimit: number.isRequired,
712
- isCombineEnabled: bool.isRequired,
713
- isMenuOpen: bool,
714
- purchasedCombine: number.isRequired,
715
- purchasedField: number.isRequired,
716
- rows: number.isRequired,
717
- selectedItemId: string.isRequired,
718
- }
719
-
720
685
  export default function Consumer(props: Partial<FieldProps>) {
721
686
  return (
722
687
  <FarmhandContext.Consumer>
@@ -41,8 +41,9 @@ export const Forest = () => {
41
41
  // Also caps by available width (2 * columns "slots": each column, each
42
42
  // gap, and one slot split across the two side paddings) so columnGap and
43
43
  // padding below - set to this same value - shrink along with the columns.
44
- const maxPlotSize = `max(${MIN_PLOT_SIZE}, min(160px, calc((100vh - ${CHROME_HEIGHT_PX}px) / ${rows +
45
- OVERHANG_ROW_MULTIPLE}), calc(100% / ${2 * Math.max(columns, 1)})))`
44
+ const maxPlotSize = `max(${MIN_PLOT_SIZE}, min(160px, calc((100vh - ${CHROME_HEIGHT_PX}px) / ${
45
+ rows + OVERHANG_ROW_MULTIPLE
46
+ }), calc(100% / ${2 * Math.max(columns, 1)})))`
46
47
 
47
48
  // The reserve itself, in the same unit as a plot. Applying this as
48
49
  // one-sided paddingTop on .Forest (below) shifts the flexbox
@@ -80,17 +81,19 @@ export const Forest = () => {
80
81
  // Paired with ForestPlot.tsx's translateX to give staggered rows a
81
82
  // symmetric FOREST_ROW_STAGGER_OVERLAP_PX overlap on both sides -
82
83
  // see that file's comment for the shared derivation.
83
- columnGap: `calc(${maxPlotSize} - ${2 *
84
- FOREST_ROW_STAGGER_OVERLAP_PX}px)`,
84
+ columnGap: `calc(${maxPlotSize} - ${
85
+ 2 * FOREST_ROW_STAGGER_OVERLAP_PX
86
+ }px)`,
85
87
  justifyContent: 'center',
86
88
  width: '100%',
87
89
  // ForestQuickSelect switches to a fixed right-side sidebar at this
88
90
  // breakpoint (see quickSelectSx) - reserve its width so centering
89
91
  // doesn't run the grid into it. Below this breakpoint the toolbelt
90
92
  // is a bottom bar instead, so no reservation is needed there.
91
- [`@media (orientation: landscape) and (min-height: ${breakpoints.largePhone}px)`]: {
92
- width: `calc(100% - ${layout.fieldSpaceForRightSideControls})`,
93
- },
93
+ [`@media (orientation: landscape) and (min-height: ${breakpoints.largePhone}px)`]:
94
+ {
95
+ width: `calc(100% - ${layout.fieldSpaceForRightSideControls})`,
96
+ },
94
97
  // Lower bound must be MIN_PLOT_SIZE, not 0, or columns shrink past
95
98
  // it to still fit the container.
96
99
  gridTemplateColumns: `repeat(${columns}, minmax(${MIN_PLOT_SIZE}, ${maxPlotSize}))`,
@@ -42,8 +42,8 @@ const getForestPlotBackgroundImage = (
42
42
  fertilizerType === STANDARD
43
43
  ? plotStates['mulched-plot']
44
44
  : fertilizerType === RAINBOW
45
- ? plotStates['rainbow-mulched-plot']
46
- : null
45
+ ? plotStates['rainbow-mulched-plot']
46
+ : null
47
47
 
48
48
  return [
49
49
  ...(overlay ? [`url(${overlay})`] : []),
@@ -70,8 +70,8 @@ const getTreeTooltipText = (
70
70
  treeLifeStage !== GROWN
71
71
  ? 'Growing...'
72
72
  : fruitLifeStage === GROWN
73
- ? `Ready to pick! (${fruitYield} ${fruitItemName ?? 'fruit'})`
74
- : 'Fruiting...'
73
+ ? `Ready to pick! (${fruitYield} ${fruitItemName ?? 'fruit'})`
74
+ : 'Fruiting...'
75
75
 
76
76
  if (!fertilizerType || fertilizerType === NONE) {
77
77
  return growthText
@@ -310,7 +310,7 @@ export const ForestPlot = ({
310
310
  <Typography>
311
311
  {getChopYieldText(
312
312
  chopWoodRange,
313
- isFruitRipe ? item?.name ?? null : null
313
+ isFruitRipe ? (item?.name ?? null) : null
314
314
  )}
315
315
  </Typography>
316
316
  </>
@@ -2,7 +2,6 @@ import Divider from '@mui/material/Divider/index.js'
2
2
  import Grid from '@mui/material/Grid/index.js'
3
3
  import Paper from '@mui/material/Paper/index.js'
4
4
  import { Theme } from '@mui/material/styles/index.js'
5
- import { array, bool, func, object, string } from 'prop-types'
6
5
 
7
6
  import { quickSelectSx } from '../../styles/sx.js'
8
7
  import FarmhandContext from '../Farmhand/Farmhand.context.js'
@@ -64,17 +63,6 @@ const ForestQuickSelect = ({
64
63
  </Paper>
65
64
  )
66
65
 
67
- ForestQuickSelect.propTypes = {
68
- mulchInventory: array.isRequired,
69
- handleForestItemSelectClick: func,
70
- handleItemSelectClick: func,
71
- isMenuOpen: bool,
72
- plantableTreeInventory: array.isRequired,
73
- playerInventoryQuantities: object.isRequired,
74
- selectedForestItemId: string.isRequired,
75
- selectedItemId: string.isRequired,
76
- }
77
-
78
66
  export default function Consumer(
79
67
  props: Partial<Parameters<typeof ForestQuickSelect>[0]>
80
68
  ) {
@@ -1,4 +1,3 @@
1
- import ExpandMoreIcon from '@mui/icons-material/ExpandMore.js'
2
1
  import Accordion from '@mui/material/Accordion/index.js'
3
2
  import AccordionDetails from '@mui/material/AccordionDetails/index.js'
4
3
  import AccordionSummary from '@mui/material/AccordionSummary/index.js'
@@ -7,9 +6,10 @@ import Card from '@mui/material/Card/index.js'
7
6
  import CardContent from '@mui/material/CardContent/index.js'
8
7
  import Divider from '@mui/material/Divider/index.js'
9
8
  import globalWindow from 'global/window.js'
10
- import { func, object } from 'prop-types'
11
9
  import ReactMarkdown from 'react-markdown'
12
10
 
11
+ import { ExpandMoreIcon } from '../PixelIcon/index.js'
12
+
13
13
  import { items } from '../../img/index.js'
14
14
 
15
15
  import { STANDARD_LOAN_AMOUNT } from '../../constants.js'
@@ -289,11 +289,6 @@ If you're playing on a mobile device, all you need to do is [add it to your home
289
289
  </Div>
290
290
  )
291
291
 
292
- Home.propTypes = {
293
- completedAchievements: object.isRequired,
294
- handleViewChangeButtonClick: func.isRequired,
295
- }
296
-
297
292
  export default function Consumer(props: Partial<Parameters<typeof Home>[0]>) {
298
293
  return (
299
294
  <FarmhandContext.Consumer>
@@ -10,7 +10,7 @@ const randomInt = (min: number, max: number) => {
10
10
 
11
11
  // Taken from:
12
12
  // https://github.com/alampros/react-confetti/blob/484bad0a0aaddbcfcc2fb4c1a4a7eeceaa6d4879/stories/snow.story.jsx#L7-L24
13
- const drawSnowflake = function(
13
+ const drawSnowflake = function (
14
14
  this: { numPoints?: number; radius: number },
15
15
  ctx: CanvasRenderingContext2D
16
16
  ) {
@@ -1,5 +1,4 @@
1
1
  import classNames from 'classnames'
2
- import { object, shape, string } from 'prop-types'
3
2
 
4
3
  import { itemsMap } from '../../data/maps.js'
5
4
  import { colors } from '../../styles/tokens.js'
@@ -46,9 +45,3 @@ export default function IngredientsList({
46
45
  </ul>
47
46
  )
48
47
  }
49
-
50
- IngredientsList.propTypes = {
51
- playerInventoryQuantities: object.isRequired,
52
- recipe: shape({ ingredients: object.isRequired, name: string.isRequired })
53
- .isRequired,
54
- }
@@ -45,7 +45,7 @@ const StubInventory = ({ gameState = {}, ...overrides }) => {
45
45
  describe('Inventory Component', () => {
46
46
  describe('Displaying items', () => {
47
47
  test('displays all items when no categories are selected', () => {
48
- const items = ([
48
+ const items = [
49
49
  testItem({ id: 'carrot', name: 'Carrot', type: 'CROP' as any }),
50
50
  testItem({ id: 'pumpkin', name: 'Pumpkin', type: 'CROP' as any }),
51
51
  testItem({
@@ -53,7 +53,7 @@ describe('Inventory Component', () => {
53
53
  name: 'Carrot Seed',
54
54
  type: 'SEEDS' as any,
55
55
  }),
56
- ] as unknown) as farmhand.item[]
56
+ ] as unknown as farmhand.item[]
57
57
 
58
58
  render(<StubInventory items={items} selectedCategories={[]} />)
59
59
  items.forEach(item => {
@@ -62,14 +62,14 @@ describe('Inventory Component', () => {
62
62
  })
63
63
 
64
64
  test('filters items by search query', () => {
65
- const items = ([
65
+ const items = [
66
66
  testItem({ id: 'carrot', name: 'Carrot', type: 'CROP' as any }),
67
67
  testItem({
68
68
  id: 'pumpkin-seed',
69
69
  name: 'Pumpkin Seed',
70
70
  type: 'SEEDS' as any,
71
71
  }),
72
- ] as unknown) as farmhand.item[]
72
+ ] as unknown as farmhand.item[]
73
73
 
74
74
  render(<StubInventory items={items} selectedCategories={[]} />)
75
75
 
@@ -4,8 +4,8 @@ import AccordionSummary from '@mui/material/AccordionSummary/index.js'
4
4
  import AccordionDetails from '@mui/material/AccordionDetails/index.js'
5
5
  import Checkbox from '@mui/material/Checkbox/index.js'
6
6
  import FormControlLabel from '@mui/material/FormControlLabel/index.js'
7
- import ExpandMoreIcon from '@mui/icons-material/ExpandMore.js'
8
- import { array } from 'prop-types'
7
+
8
+ import { ExpandMoreIcon } from '../PixelIcon/index.js'
9
9
 
10
10
  import FarmhandContext, { ContextData } from '../Farmhand/Farmhand.context.js'
11
11
  import Item from '../Item/index.js'
@@ -109,10 +109,9 @@ const Inventory = ({
109
109
  )
110
110
  }
111
111
 
112
- const filteredCategories = (Array.from(itemCategories.entries()) as [
113
- string,
114
- farmhand.item[]
115
- ][]).reduce(
112
+ const filteredCategories = (
113
+ Array.from(itemCategories.entries()) as [string, farmhand.item[]][]
114
+ ).reduce(
116
115
  (
117
116
  filtered: Map<string, farmhand.item[]>,
118
117
  [category, categoryItems]: [string, farmhand.item[]]
@@ -215,12 +214,6 @@ const Inventory = ({
215
214
  )
216
215
  }
217
216
 
218
- Inventory.propTypes = {
219
- items: array.isRequired,
220
- playerInventory: array,
221
- shopInventory: array,
222
- }
223
-
224
217
  export default function Consumer(
225
218
  props: Partial<Parameters<typeof Inventory>[0]>
226
219
  ) {
@@ -1,6 +1,5 @@
1
1
  import React, { useEffect, useState } from 'react'
2
- import KeyboardArrowUp from '@mui/icons-material/KeyboardArrowUp.js'
3
- import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown.js'
2
+
4
3
  import Button from '@mui/material/Button/index.js'
5
4
  import Box from '@mui/material/Box/index.js'
6
5
  import Card from '@mui/material/Card/index.js'
@@ -9,9 +8,13 @@ import CardContent from '@mui/material/CardContent/index.js'
9
8
  import CardActions from '@mui/material/CardActions/index.js'
10
9
  import Tooltip from '@mui/material/Tooltip/index.js'
11
10
  import Typography from '@mui/material/Typography/index.js'
12
- import { array, bool, func, number, object } from 'prop-types'
13
11
  import classNames from 'classnames'
14
12
 
13
+ import {
14
+ KeyboardArrowUpIcon as KeyboardArrowUp,
15
+ KeyboardArrowDownIcon as KeyboardArrowDown,
16
+ } from '../PixelIcon/index.js'
17
+
15
18
  import FarmhandContext, { ContextData } from '../Farmhand/Farmhand.context.js'
16
19
  import { items } from '../../img/index.js'
17
20
  import { itemsMap } from '../../data/maps.js'
@@ -36,18 +39,20 @@ interface ValueIndicatorProps {
36
39
  poorValue: boolean
37
40
  }
38
41
 
42
+ // Keeps the indicator from crowding the price it follows.
43
+ const valueIndicatorSx = { marginLeft: '0.5rem' } as const
44
+
39
45
  const ValueIndicator = ({ poorValue }: ValueIndicatorProps) => (
40
46
  <Tooltip
41
47
  {...{
42
- arrow: true,
43
48
  placement: 'top',
44
49
  title: `${poorValue ? 'Poor' : 'Good'} opportunity`,
45
50
  }}
46
51
  >
47
52
  {poorValue ? (
48
- <KeyboardArrowDown color="error" />
53
+ <KeyboardArrowDown color="error" sx={valueIndicatorSx} />
49
54
  ) : (
50
- <KeyboardArrowUp color="primary" />
55
+ <KeyboardArrowUp color="primary" sx={valueIndicatorSx} />
51
56
  )}
52
57
  </Tooltip>
53
58
  )
@@ -229,7 +234,6 @@ export const Item = ({
229
234
  !isPurchaseView && description ? (
230
235
  <Tooltip
231
236
  {...{
232
- arrow: true,
233
237
  placement: 'top',
234
238
  title: <Typography>{description}</Typography>,
235
239
  }}
@@ -246,7 +250,6 @@ export const Item = ({
246
250
  <p>
247
251
  <Tooltip
248
252
  {...{
249
- arrow: true,
250
253
  placement: 'top',
251
254
  title:
252
255
  previousDayAdjustedValue === null
@@ -288,7 +291,6 @@ export const Item = ({
288
291
  <p>
289
292
  <Tooltip
290
293
  {...{
291
- arrow: true,
292
294
  placement: 'top',
293
295
  title:
294
296
  previousDayAdjustedValue === null
@@ -455,26 +457,6 @@ export const Item = ({
455
457
  )
456
458
  }
457
459
 
458
- Item.propTypes = {
459
- adjustedValue: number,
460
- completedAchievements: object.isRequired,
461
- handleItemPurchaseClick: func,
462
- handleItemSelectClick: func,
463
- handleItemSellClick: func,
464
- historicalValueAdjustments: array.isRequired,
465
- inventory: array.isRequired,
466
- inventoryLimit: number.isRequired,
467
- isPurchaseView: bool,
468
- isSelectView: bool,
469
- isSelected: bool,
470
- isSellView: bool,
471
- item: object.isRequired,
472
- money: number.isRequired,
473
- playerInventoryQuantities: object.isRequired,
474
- showQuantity: bool,
475
- valueAdjustments: object.isRequired,
476
- }
477
-
478
460
  export default function Consumer(props: Partial<ItemProps>) {
479
461
  return (
480
462
  <FarmhandContext.Consumer>
@@ -2,7 +2,6 @@ import Button from '@mui/material/Button/index.js'
2
2
  import Tooltip from '@mui/material/Tooltip/index.js'
3
3
  import Typography from '@mui/material/Typography/index.js'
4
4
  import classNames from 'classnames'
5
- import { array, func, object, string } from 'prop-types'
6
5
 
7
6
  import { items as itemImages, pixel } from '../../img/index.js'
8
7
  import { spriteShadowSx, squareImgSx } from '../../styles/sx.js'
@@ -27,9 +26,10 @@ export const ItemList = ({
27
26
  sx={{
28
27
  display: 'flex',
29
28
  flexFlow: 'row',
30
- [`@media (orientation: landscape) and (min-height: ${breakpoints.largePhone}px)`]: {
31
- flexFlow: 'column',
32
- },
29
+ [`@media (orientation: landscape) and (min-height: ${breakpoints.largePhone}px)`]:
30
+ {
31
+ flexFlow: 'column',
32
+ },
33
33
  }}
34
34
  >
35
35
  {sortItems(items).map((item: farmhand.item) => (
@@ -98,10 +98,3 @@ export const ItemList = ({
98
98
  ))}
99
99
  </Div>
100
100
  )
101
-
102
- ItemList.propTypes = {
103
- handleItemSelectClick: func,
104
- items: array.isRequired,
105
- playerInventoryQuantities: object.isRequired,
106
- selectedItemId: string.isRequired,
107
- }