Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add options page #158

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"48": "icons/48.png",
"128": "icons/128.png"
},
"options_page": "src/pages/options/index.html",
"content_scripts": [
{
"matches": ["*://*.steamcommunity.com/market/listings/730/*"],
Expand Down
2,088 changes: 2,040 additions & 48 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
"@types/chrome": "^0.0.193",
"@types/jquery": "^3.5.14",
"@types/lodash": "^4.14.195",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^5.39.0",
"@typescript-eslint/parser": "^5.39.0",
"copy-webpack-plugin": "^11.0.0",
Expand All @@ -38,20 +40,31 @@
"fast-json-stable-stringify": "^2.1.0",
"file-loader": "^6.2.0",
"filtrex": "^3.0.0",
"fs": "^0.0.1-security",
ayoung19 marked this conversation as resolved.
Show resolved Hide resolved
"glob": "^8.0.3",
"html-loader": "^4.1.0",
"html-webpack-plugin": "^5.5.3",
"ignore-loader": "^0.1.2",
"lit": "^2.3.0",
"lit-html": "^2.3.1",
"lodash": "^4.17.21",
"lodash-decorators": "^6.0.1",
"mini-css-extract-plugin": "^2.6.1",
"prettier": "^2.7.1",
"process": "^0.11.10",
"rxjs": "^7.5.7",
"sass-loader": "^13.0.2",
"ts-loader": "^9.3.1",
"typescript": "^4.7.4",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},
"dependencies": {
"@emotion/react": "^11.11.1",
"@mantine/core": "^6.0.17",
"@mantine/hooks": "^6.0.17",
"@tabler/icons-react": "^2.26.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
86 changes: 86 additions & 0 deletions src/pages/options/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
Button,
Card,
Divider,
Flex,
Group,
Image,
NavLink,
Space,
Stack,
Switch,
Tabs,
Text,
ThemeIcon,
Title,
UnstyledButton,
} from '@mantine/core';
import {AppShell, Navbar, Header} from '@mantine/core';
import {IconBackpack, IconBuildingStore, IconGitPullRequest, IconInfoCircle, IconSettings} from '@tabler/icons-react';
import {SettingsPage} from './settings/SettingsPage';
import {useState} from 'react';

const ALL_PAGE_IDS = ['settings', 'about'] as const;

type PageId = typeof ALL_PAGE_IDS[number];

const pageIdToComponent = (pageId: PageId) => {
switch (pageId) {
case 'settings':
return <SettingsPage />;
case 'about':
return <SettingsPage />;
}
};

export const App = () => {
const [activePageId, setActivePageId] = useState<PageId>('settings');

return (
<AppShell
padding="md"
navbar={
<Navbar width={{base: 300}} p="xs">
<Flex direction="column" gap="xs">
<NavLink
label={<Text size="sm">Settings</Text>}
icon={
<ThemeIcon color="blue" variant="light">
<IconSettings size="1rem" />
</ThemeIcon>
}
variant="light"
active={activePageId === 'settings'}
onClick={() => setActivePageId('settings')}
/>

<NavLink
label={<Text size="sm">About</Text>}
icon={
<ThemeIcon color="blue" variant="light">
<IconInfoCircle size="1rem" />
</ThemeIcon>
}
variant="light"
active={activePageId === 'about'}
onClick={() => setActivePageId('about')}
/>
</Flex>
</Navbar>
}
header={
<Header height={60} p="xs">
<Group pl="md">
<Image width={160} src="https://csgofloat.com/assets/full_logo.png" alt="CSGOFloat Logo" />
<Title order={2}>Market Checker</Title>
</Group>
</Header>
}
styles={(theme) => ({
main: {backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0]},
})}
>
{pageIdToComponent(activePageId)}
</AppShell>
);
};
13 changes: 13 additions & 0 deletions src/pages/options/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="CSGOFloat Options" />
<title>CSGOFloat Options</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
13 changes: 13 additions & 0 deletions src/pages/options/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import {MantineProvider} from '@mantine/core';
import {App} from './App';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<React.StrictMode>
<MantineProvider theme={{colorScheme: 'dark'}} withGlobalStyles withNormalizeCSS>
<App />
</MantineProvider>
</React.StrictMode>
);
32 changes: 32 additions & 0 deletions src/pages/options/settings/InventorySettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {Card, Divider, Flex, Space, Switch, Text, Title} from '@mantine/core';

export const InventorySettings = () => {
return (
<Card>
<Flex direction="column">
<Title order={4}>Inventory Settings</Title>
<Text fz="xs">Configure CSGOFloat Market Checker features in inventories.</Text>
</Flex>

<Space h="sm" />

<Flex gap="xl">
<Flex direction="column" w={500}>
<Title order={6}>Paint Seed</Title>
<Text fz="xs">Show the paint seed of items in an inventory.</Text>
</Flex>
<Switch />
</Flex>

<Divider my="sm" />

<Flex gap="xl">
<Flex direction="column" w={500}>
<Title order={6}>Smart Filter/Sort</Title>
<Text fz="xs">Shows the smart filter and sort buttons in a listing.</Text>
</Flex>
<Switch />
</Flex>
</Card>
);
};
34 changes: 34 additions & 0 deletions src/pages/options/settings/MarketSettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {Card, Divider, Flex, Space, Switch, Text, Title} from '@mantine/core';

export const MarketSettings = () => {
return (
<Card>
<Flex direction="column">
<Title order={4}>Market Settings</Title>
<Text fz="xs">Configure CSGOFloat Market Checker features in the market page and its listings.</Text>
</Flex>

<Space h="sm" />

<Flex gap="xl">
<Flex direction="column" w={500}>
<Title order={6}>3D/Screenshot Buttons</Title>
<Text fz="xs">
Shows buttons under a listing to quickly view 3d model or screenshot of the specific item.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we define the options that are possible in a schema (or just their own Setting<name, type, data_type>), then we can also define the description and auto-generate the entire page here.

Adding new settings would become super-simple, just adding the new defined Setting option and it all "hooks" up and allows toggling it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree it would be really nice once we’ve fleshed out more settings and define specific data types but it feels like an over optimization right now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be fair to add this once we have a third repeating data type for our settings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually at the very least i’ll component-ize this boolean setting field rn

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I think my solution is a bit of over-engineering for this. But yeah, let's prioritize making it simple to add new options fields.

</Text>
</Flex>
<Switch />
</Flex>

<Divider my="sm" />

<Flex gap="xl">
<Flex direction="column" w={500}>
<Title order={6}>Smart Filter/Sort</Title>
<Text fz="xs">Shows the smart filter and sort buttons in a listing.</Text>
</Flex>
<Switch />
</Flex>
</Card>
);
};
27 changes: 27 additions & 0 deletions src/pages/options/settings/SettingsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {Card, Divider, Flex, Space, Switch, Tabs, Text, Title} from '@mantine/core';
import {IconBackpack, IconBuildingStore} from '@tabler/icons-react';
import {MarketSettings} from './MarketSettings';
import {InventorySettings} from './InventorySettings';

export const SettingsPage = () => {
return (
<Tabs defaultValue="market">
<Tabs.List>
<Tabs.Tab value="market" icon={<IconBuildingStore size="0.8rem" />}>
Market
</Tabs.Tab>
<Tabs.Tab value="inventory" icon={<IconBackpack size="0.8rem" />}>
Inventory
</Tabs.Tab>
</Tabs.List>

<Tabs.Panel value="market" pt="xs">
<MarketSettings />
</Tabs.Panel>

<Tabs.Panel value="inventory" pt="xs">
<InventorySettings />
</Tabs.Panel>
</Tabs>
);
};
13 changes: 13 additions & 0 deletions src/pages/wow/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
ayoung19 marked this conversation as resolved.
Show resolved Hide resolved
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="CSGOFloat Options" />
<title>CSGOFloat Options</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
9 changes: 9 additions & 0 deletions src/pages/wow/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<React.StrictMode>
<div>yo</div>
</React.StrictMode>
);
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"typeRoots": ["node_modules/@types", "./src/lib/types"],
"experimentalDecorators": true,
"useDefineForClassFields": false,
"moduleResolution": "Node"
"moduleResolution": "Node",
"jsx": "react-jsx"
},
"exclude": ["dist/"]
}
24 changes: 21 additions & 3 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const path = require('path');
const glob = require('glob');
const fs = require('fs');
const CopyPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');

const CHROME_KEY =
Expand All @@ -27,19 +29,23 @@ module.exports = (env) => {
getPathEntries('./src/lib/page_scripts/*.ts'),
getPathEntries('./src/lib/types/*.d.ts'),
getPathEntries('./src/background.ts'),
getPathEntries('./src/**/*.js')
getPathEntries('./src/**/*.js'),
getPathEntries('./src/pages/**/*.tsx')
),
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
},
resolve: {
extensions: ['.ts', '.js', '.html'],
alias: {
process: 'process/browser',
},
extensions: ['.ts', '.js', '.html', '.tsx'],
},
module: {
rules: [
{
test: /\.ts$/,
test: /\.(ts|tsx)$/,
loader: 'ts-loader',
exclude: /node_modules|\.d\.ts$/,
},
Expand All @@ -58,6 +64,9 @@ module.exports = (env) => {
],
},
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new MiniCssExtractPlugin(),
new webpack.SourceMapDevToolPlugin({}),
new CopyPlugin({
Expand All @@ -84,6 +93,15 @@ module.exports = (env) => {
},
],
}),
...fs.readdirSync(path.join(__dirname, 'src', 'pages')).map(
(pageName) =>
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'pages', pageName, 'index.html'),
filename: `./src/pages/${pageName}/index.html`,
chunks: [`./src/pages/${pageName}/index`],
cache: false,
})
),
],
stats: {
errorDetails: true,
Expand Down