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 7 commits
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
40 changes: 20 additions & 20 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
"rules": {
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-empty-interface": "off"
},
"env": {
"browser": true,
"es2021": true
}
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
"rules": {
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-empty-interface": "off"
},
"env": {
"browser": true,
"es2021": true
}
}
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,198 changes: 2,110 additions & 88 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"@types/firefox-webext-browser": "^111.0.1",
"@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 @@ -41,20 +43,32 @@
"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",
"react-hook-form": "^7.45.2"
}
}
10 changes: 10 additions & 0 deletions src/background.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {Handle} from './lib/bridge/server';
import {InternalResponseBundle} from './lib/bridge/types';
import MessageSender = chrome.runtime.MessageSender;
import {DEFAULT_SETTINGS, SettingsType} from './settings';
import {StorageKey} from './lib/storage/keys';
import {gStore} from './lib/storage/store';

function unifiedHandler(request: any, sender: MessageSender, sendResponse: (response?: any) => void) {
Handle(request, sender)
Expand Down Expand Up @@ -29,3 +32,10 @@ chrome.runtime.onMessageExternal.addListener((request, sender, sendResponse) =>
unifiedHandler(request, sender, sendResponse);
return true;
});

gStore.get<SettingsType>(StorageKey.SETTINGS).then((settings) => {
ayoung19 marked this conversation as resolved.
Show resolved Hide resolved
gStore.set<SettingsType>(StorageKey.SETTINGS, {
...DEFAULT_SETTINGS,
...(settings || {}),
});
});
2 changes: 2 additions & 0 deletions src/lib/bridge/handlers/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {FetchSkinModel} from './fetch_skin_model';
import {StorageRemove} from './storage_remove';
import {RequestType} from './types';
import {FetchExtensionFile} from './fetch_extension_file';
import {OpenOptionsPage} from './open_options_page';

export const HANDLERS_MAP: {[key in RequestType]: RequestHandler<any, any>} = {
[RequestType.EXECUTE_SCRIPT_ON_PAGE]: ExecuteScriptOnPage,
Expand All @@ -24,4 +25,5 @@ export const HANDLERS_MAP: {[key in RequestType]: RequestHandler<any, any>} = {
[RequestType.FETCH_PENDING_TRADES]: FetchPendingTrades,
[RequestType.FETCH_SKIN_MODEL]: FetchSkinModel,
[RequestType.FETCH_EXTENSION_FILE]: FetchExtensionFile,
[RequestType.OPEN_OPTIONS_PAGE]: OpenOptionsPage,
};
12 changes: 12 additions & 0 deletions src/lib/bridge/handlers/open_options_page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {RequestHandler} from '../types';
import {RequestType} from './types';
import {isFirefox} from '../../utils/detect';
import {EmptyRequestHandler} from './main';

export const OpenOptionsPage = new EmptyRequestHandler<void>(RequestType.OPEN_OPTIONS_PAGE, async () => {
if (isFirefox()) {
ayoung19 marked this conversation as resolved.
Show resolved Hide resolved
return await browser.runtime.openOptionsPage();
}

return chrome.runtime.openOptionsPage();
});
1 change: 1 addition & 0 deletions src/lib/bridge/handlers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export enum RequestType {
FETCH_PENDING_TRADES,
FETCH_SKIN_MODEL,
FETCH_EXTENSION_FILE,
OPEN_OPTIONS_PAGE,
}
13 changes: 13 additions & 0 deletions src/lib/components/market/skin_viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {getMarketInspectLink} from './helpers';
import {rgAsset, ListingData} from '../../types/steam';
import {AppId, ContextId} from '../../types/steam_constants';
import {isSkin} from '../../utils/skin';
import {Get} from '../../bridge/handlers/storage_get';
import {SETTINGS} from '../../storage/keys';

enum Showing {
NONE,
Expand Down Expand Up @@ -74,8 +76,15 @@ export class SkinViewer extends FloatElement {
@state()
private showing: Showing = Showing.NONE;

@state()
private isEnabled = false;

async connectedCallback() {
super.connectedCallback();

const settings = await Get(SETTINGS);
ayoung19 marked this conversation as resolved.
Show resolved Hide resolved

this.isEnabled = !!settings && settings.market['3d-screenshot-buttons'];
}

loadingIfApplicable(text: string, type: Showing) {
Expand All @@ -95,6 +104,10 @@ export class SkinViewer extends FloatElement {
return nothing;
}

if (!this.isEnabled) {
return nothing;
}

return html`
<div class="btn-container">
<csgofloat-steam-button
Expand Down
47 changes: 44 additions & 3 deletions src/lib/components/market/utility_belt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import './page_size';
import './sort_listings';
import './ad_banner';
import '../filter/filter_container';
import {ClientSend} from '../../bridge/client';
import {OpenOptionsPage} from '../../bridge/handlers/open_options_page';

@CustomElement()
@InjectBefore('#searchResultsRows', InjectionMode.ONCE)
Expand All @@ -23,6 +25,23 @@ export class UtilityBelt extends FloatElement {
background-color: rgba(0, 0, 0, 0.2);
}

.buttons-container {
display: flex;
align-items: center;
}

.settings-icon-wrapper {
padding: 4px;
margin-left: auto;
margin-right: 0;
border-radius: 4px;
display: inherit;
}

.settings-icon-wrapper:hover {
background-color: rgba(0, 0, 0, 0.3);
}

.page-selector {
margin-left: 10px;
}
Expand All @@ -38,9 +57,31 @@ export class UtilityBelt extends FloatElement {
protected render(): HTMLTemplateResult {
return html`
<div class="utility-container">
<csgofloat-sort-listings></csgofloat-sort-listings>
<csgofloat-page-size class="page-selector"></csgofloat-page-size>
<a class="github" href="https://csgofloat.com" target="_blank">Powered by CSGOFloat</a>
<div class="buttons-container">
<csgofloat-sort-listings></csgofloat-sort-listings>
<csgofloat-page-size class="page-selector"></csgofloat-page-size>
<a class="github" href="https://csgofloat.com" target="_blank">Powered by CSGOFloat</a>
<a class="settings-icon-wrapper" @click="${() => ClientSend(OpenOptionsPage, undefined)}">
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-settings"
width="16"
height="16"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"
/>
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
</svg>
</a>
</div>
<hr />
<csgofloat-filter-container
?hidden="${!this.marketHashName}"
Expand Down
3 changes: 3 additions & 0 deletions src/lib/storage/keys.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/**
* Keys for use as the raw "key" in local/sync storage for a row
*/
import {SettingsType} from '../../settings';
import {SerializedFilter} from '../filter/types';

export enum StorageKey {
// Backwards compatible with <3.0.0
PAGE_SIZE = 'pageSize',
ITEM_FILTERS = 'expressions',
GLOBAL_FILTERS = 'global',
SETTINGS = 'settings',
}

export type DynamicStorageKey = string;
Expand Down Expand Up @@ -45,3 +47,4 @@ export const PAGE_SIZE = newRow<number>(StorageKey.PAGE_SIZE);
// Dynamic prefixes should be the market hash name of the item
export const DYNAMIC_ITEM_FILTERS = newDynamicRow<SerializedFilter[]>(StorageKey.ITEM_FILTERS);
export const GLOBAL_FILTERS = newRow<SerializedFilter[]>(StorageKey.GLOBAL_FILTERS);
export const SETTINGS = newRow<SettingsType>(StorageKey.SETTINGS);
72 changes: 72 additions & 0 deletions src/pages/options/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
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'] as const;

type PageId = typeof ALL_PAGE_IDS[number];

const pageIdToComponent = (pageId: PageId) => {
switch (pageId) {
case 'settings':
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')}
/>
</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>
);
Loading