Skip to content

Commit d0d9f37

Browse files
Merge branch 'communitycenter:main' into main
2 parents 048c5ac + 9e78b73 commit d0d9f37

31 files changed

Lines changed: 1845 additions & 760 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<img align=center src="https://github.com/communitycenter/stardew.app/blob/main/.github/background.png?raw=true" alt="Stardew.app Logo" width="500" /></br>
99
</p>
1010

11-
The website uses [Next.js](https://nextjs.org) for its frontend, [PlanetScale](https://planetscale.com) for its database, and a mixture of TypeScript and Python scripts to supplement data into the website. Internally, we use [Linear](https://linear.app) and [Pierre](https://pierre.co) for issue tracking and branch management.
11+
The website uses [Next.js](https://nextjs.org) for its frontend, self-hosted MySQL for its database, and a mixture of TypeScript and Python scripts to supplement data into the website. Internally, we use [Linear](https://linear.app) for issue tracking and branch management.
1212

1313
---
1414

@@ -40,7 +40,7 @@ The website uses [Next.js](https://nextjs.org) for its frontend, [PlanetScale](h
4040
<img align=center src="https://github.com/communitycenter/stardew.app/blob/main/.github/contributing.png?raw=true" alt="Stardew.app Logo" width="500" /></br>
4141
</p>
4242

43-
Thank you so much for wanting to contribute to stardew.app! This GitHub repository serves as a read-only mirror from our branch on Pierre, however contributions are still more than welcome (and can be merged in regardless!) We ask that you ensure your code is neat, adheres to the current programming style of the project, and runs without errors. Other than that, feel free to fix bugs, add features, and do whatever you desire to improve the website! stardew.app is built by the community, for the community, so we appreciate your contribution.
43+
Thank you so much for wanting to contribute to stardew.app! We ask that you ensure your code is neat, adheres to the current programming style of the project, and runs without errors. Other than that, feel free to fix bugs, add features, and do whatever you desire to improve the website! stardew.app is built by the community, for the community, so we appreciate your contribution.
4444

4545
Below are some incredible people that the website wouldn't be without today.
4646

bun.lockb

-10.9 KB
Binary file not shown.

next.config.js

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
const withBundleAnalyzer = require("@next/bundle-analyzer")({
2-
enabled: process.env.ANALYZE === "true",
3-
});
4-
51
/** @type {import('next').NextConfig} */
62
const nextConfig = {
73
reactStrictMode: true,
@@ -39,57 +35,7 @@ const nextConfig = {
3935
pathname: "/mediawiki/images/**",
4036
},
4137
],
42-
remotePatterns: [
43-
{
44-
protocol: "https",
45-
hostname: "github.com",
46-
port: "",
47-
pathname: "/**",
48-
},
49-
],
50-
}
51-
};
52-
53-
module.exports = withBundleAnalyzer(nextConfig);
54-
55-
// Injected content via Sentry wizard below
56-
57-
const { withSentryConfig } = require("@sentry/nextjs");
58-
59-
module.exports = withSentryConfig(
60-
module.exports,
61-
{
62-
// For all available options, see:
63-
// https://github.com/getsentry/sentry-webpack-plugin#options
64-
65-
// Suppresses source map uploading logs during build
66-
silent: true,
67-
org: "communitycenter",
68-
project: "stardewapp",
6938
},
70-
{
71-
// For all available options, see:
72-
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
73-
74-
// Upload a larger set of source maps for prettier stack traces (increases build time)
75-
widenClientFileUpload: true,
76-
77-
// Transpiles SDK to be compatible with IE11 (increases bundle size)
78-
transpileClientSDK: true,
79-
80-
// Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)
81-
tunnelRoute: "/monitoring",
82-
83-
// Hides source maps from generated client bundles
84-
hideSourceMaps: true,
85-
86-
// Automatically tree-shake Sentry logger statements to reduce bundle size
87-
disableLogger: true,
39+
};
8840

89-
// Enables automatic instrumentation of Vercel Cron Monitors.
90-
// See the following for more information:
91-
// https://docs.sentry.io/product/crons/
92-
// https://vercel.com/docs/cron-jobs
93-
automaticVercelMonitors: true,
94-
},
95-
);
41+
module.exports = nextConfig;

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@
3131
"@radix-ui/react-switch": "^1.0.3",
3232
"@radix-ui/react-tabs": "^1.0.4",
3333
"@radix-ui/react-toast": "^1.1.4",
34+
"@radix-ui/react-toggle": "^1.1.9",
35+
"@radix-ui/react-toggle-group": "^1.1.10",
3436
"@radix-ui/react-tooltip": "^1.0.6",
3537
"@react-hook/media-query": "^1.1.1",
36-
"@sentry/nextjs": "^7.104.0",
3738
"@tabler/icons-react": "^2.30.0",
3839
"@types/node": "20.4.0",
3940
"@types/react": "18.2.14",
@@ -48,12 +49,12 @@
4849
"eslint": "8.44.0",
4950
"eslint-config-next": "13.4.12",
5051
"fast-xml-parser": "^4.2.6",
52+
"lucide-react": "^0.522.0",
5153
"mysql2": "^3.10.1",
5254
"next": "^14.2.3",
5355
"next-themes": "^0.2.1",
5456
"pako": "^2.1.0",
5557
"postcss": "8.4.24",
56-
"posthog-js": "^1.110.0",
5758
"react": "18.2.0",
5859
"react-dom": "18.2.0",
5960
"react-dropzone": "^14.2.3",

sentry.client.config.ts

Lines changed: 0 additions & 30 deletions
This file was deleted.

sentry.edge.config.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

sentry.server.config.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/components/cards/boolean-card.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { ItemData, MuseumItem } from "@/types/items";
55
import { Dispatch, SetStateAction } from "react";
66

77
import { usePlayers } from "@/contexts/players-context";
8+
import { useMultiSelect } from "@/contexts/multi-select-context";
89

910
import { NewItemBadge } from "@/components/new-item-badge";
1011
import {
@@ -66,6 +67,7 @@ export const BooleanCard = ({
6667
handleStatusChange,
6768
}: BooleanCardProps) => {
6869
const { activePlayer, patchPlayer } = usePlayers();
70+
const { isMultiSelectMode, selectedItems, toggleItem } = useMultiSelect();
6971
// let itemType = "O"; //Todo add item types to object data files, and use them here to hotswap data source
7072
// let dataSource = objects;
7173
let iconURL: string;
@@ -137,6 +139,8 @@ export const BooleanCard = ({
137139
await patchPlayer(patch);
138140
}
139141

142+
const isSelected = selectedItems.has(item.itemID.toString());
143+
140144
return (
141145
<ContextMenu>
142146
<ContextMenuTrigger asChild>
@@ -146,8 +150,13 @@ export const BooleanCard = ({
146150
completed
147151
? "border-green-900 bg-green-500/20 hover:bg-green-500/30 dark:bg-green-500/10 hover:dark:bg-green-500/20"
148152
: "border-neutral-200 bg-white hover:bg-neutral-100 dark:border-neutral-800 dark:bg-neutral-950 dark:hover:bg-neutral-800",
153+
isMultiSelectMode && isSelected && "ring-primary ring-2",
149154
)}
150155
onClick={() => {
156+
if (isMultiSelectMode) {
157+
toggleItem(item.itemID.toString());
158+
return;
159+
}
151160
if (minVersion === "1.6.0" && !show && !completed) {
152161
setPromptOpen?.(true);
153162
return;

src/components/cards/dialog-card.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828

2929
import { Stardrop } from "@/lib/parsers/general";
3030
import { ChevronRightIcon } from "@radix-ui/react-icons";
31+
import { useMultiSelect } from "@/contexts/multi-select-context";
3132

3233
interface Props {
3334
title: string;
@@ -65,13 +66,18 @@ export const DialogCard = ({
6566
}: Props) => {
6667
const { activePlayer, patchPlayer } = usePlayers();
6768
const [open, setOpen] = useState(false);
69+
const { isMultiSelectMode, selectedItems, toggleItem } = useMultiSelect();
6870

6971
const minVersion = _type === "power" ? powersData[_id].minVersion : "1.5.0";
7072

7173
let checkedClass = completed
7274
? "border-green-900 bg-green-500/20 hover:bg-green-500/30 dark:bg-green-500/10 hover:dark:bg-green-500/20"
7375
: "border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-950 hover:bg-neutral-100 dark:hover:bg-neutral-800";
7476

77+
if (isMultiSelectMode && selectedItems.has(_id)) {
78+
checkedClass += " ring-2 ring-primary";
79+
}
80+
7581
async function handleStatusChange(status: boolean) {
7682
if (!activePlayer) return;
7783

@@ -156,6 +162,10 @@ export const DialogCard = ({
156162
checkedClass,
157163
)}
158164
onClick={(e) => {
165+
if (isMultiSelectMode) {
166+
toggleItem(_id);
167+
return;
168+
}
159169
if (minVersion === "1.6.0" && !show && !completed) {
160170
e.preventDefault();
161171
setPromptOpen?.(true);

src/components/cards/recipe-card.tsx

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import objects from "@/data/objects.json";
66
import type { CraftingRecipe, Recipe } from "@/types/recipe";
77

88
import { cn } from "@/lib/utils";
9-
import { Dispatch, SetStateAction } from "react";
9+
import { Dispatch, SetStateAction, useRef } from "react";
1010

1111
import { usePlayers } from "@/contexts/players-context";
12+
import { useMultiSelect } from "@/contexts/multi-select-context";
1213

1314
import { NewItemBadge } from "@/components/new-item-badge";
1415
import {
@@ -41,6 +42,9 @@ interface Props<T extends Recipe> {
4142
* @memberof Props
4243
*/
4344
setPromptOpen?: Dispatch<SetStateAction<boolean>>;
45+
46+
index: number;
47+
allRecipes: T[];
4448
}
4549

4650
export const RecipeCard = <T extends Recipe>({
@@ -50,8 +54,14 @@ export const RecipeCard = <T extends Recipe>({
5054
setObject,
5155
setPromptOpen,
5256
show,
57+
index,
58+
allRecipes,
5359
}: Props<T>) => {
5460
const { activePlayer, patchPlayer } = usePlayers();
61+
const { isMultiSelectMode, selectedItems, toggleItem, addItems } =
62+
useMultiSelect();
63+
const lastSelectedIndex = useRef<number | null>(null);
64+
5565
let colorClass = "";
5666
switch (status) {
5767
case 1:
@@ -110,24 +120,48 @@ export const RecipeCard = <T extends Recipe>({
110120
await patchPlayer(patch);
111121
}
112122

123+
const isSelected = selectedItems.has(recipe.itemID.toString());
124+
125+
const handleClick = (e: React.MouseEvent) => {
126+
if (isMultiSelectMode) {
127+
if (e.shiftKey && lastSelectedIndex.current !== null) {
128+
// Select range of items
129+
const start = Math.min(lastSelectedIndex.current, index);
130+
const end = Math.max(lastSelectedIndex.current, index);
131+
const itemsToSelect = allRecipes
132+
.slice(start, end + 1)
133+
.map((r) => r.itemID.toString());
134+
addItems(itemsToSelect);
135+
} else {
136+
// Single item selection
137+
toggleItem(recipe.itemID.toString());
138+
lastSelectedIndex.current = index;
139+
}
140+
return;
141+
}
142+
143+
if (recipe.minVersion === "1.6.0" && !show && status < 1) {
144+
setPromptOpen?.(true);
145+
return;
146+
}
147+
setObject(recipe);
148+
setIsOpen(true);
149+
};
150+
113151
return (
114152
<ContextMenu>
115153
<ContextMenuTrigger asChild>
116154
<button
117155
className={cn(
118156
"relative flex select-none items-center justify-between rounded-lg border px-5 py-4 text-neutral-950 shadow-sm transition-colors hover:cursor-pointer dark:text-neutral-50",
119157
colorClass,
158+
isMultiSelectMode && isSelected && "ring-2 ring-blue-500",
120159
)}
121-
onClick={() => {
122-
if (recipe.minVersion === "1.6.0" && !show && status < 1) {
123-
setPromptOpen?.(true);
124-
return;
125-
}
126-
setObject(recipe);
127-
setIsOpen(true);
128-
}}
160+
onClick={handleClick}
129161
>
130-
{recipe.minVersion === "1.6.0" && <NewItemBadge version={recipe.minVersion}/>}
162+
{recipe.minVersion === "1.6.0" && (
163+
<NewItemBadge version={recipe.minVersion} />
164+
)}
131165
<div
132166
className={cn(
133167
"flex items-center space-x-3 truncate text-left",
@@ -150,7 +184,9 @@ export const RecipeCard = <T extends Recipe>({
150184
</p>
151185
</div>
152186
</div>
153-
<IconChevronRight className="h-5 w-5 flex-shrink-0 text-neutral-500 dark:text-neutral-400" />
187+
{!isMultiSelectMode && (
188+
<IconChevronRight className="h-5 w-5 flex-shrink-0 text-neutral-500 dark:text-neutral-400" />
189+
)}
154190
</button>
155191
</ContextMenuTrigger>
156192
<ContextMenuContent className="w-48">

0 commit comments

Comments
 (0)