Skip to content

Commit

Permalink
feat: add faction name search, fix exported filename
Browse files Browse the repository at this point in the history
  • Loading branch information
Redmega committed Jan 5, 2022
1 parent 2cfdadb commit f1f7f48
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 33 deletions.
47 changes: 29 additions & 18 deletions src/components/editor/section/factions-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import { Bitburner } from "bitburner.types";
import { Checkbox } from "components/inputs/checkbox";
import { Input } from "components/inputs/input";
import { formatNumber } from "util/format";
import { useDebounce } from "util/hooks";

import { SortAscendingIcon, SortDescendingIcon } from "@heroicons/react/solid";
import { ReactComponent as SearchIcon } from "icons/search.svg";

export type FactionDataKey = keyof Bitburner.FactionsSaveObject["data"];

Expand All @@ -29,6 +31,8 @@ interface Props extends PropsWithChildren<{}> {
}
export default observer(function FactionSection({ isFiltering }: Props) {
const { factions } = useContext(FileContext);
const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 500);
const [filters, setFilters] = useState<Partial<Bitburner.FactionsSaveObject["data"]>>({
playerReputation: -1,
});
Expand All @@ -38,7 +42,8 @@ export default observer(function FactionSection({ isFiltering }: Props) {
return (
(!filters.alreadyInvited || faction.data.alreadyInvited) &&
(!filters.isMember || faction.data.isMember) &&
(!filters.isBanned || faction.data.isBanned)
(!filters.isBanned || faction.data.isBanned) &&
(debouncedQuery.length === 0 || faction.data.name.indexOf(debouncedQuery) >= 0)
);
});

Expand All @@ -55,7 +60,7 @@ export default observer(function FactionSection({ isFiltering }: Props) {
[filters[sortProperty] > 0 ? ascend(path([1, "data", sortProperty])) : descend(path([1, "data", sortProperty]))],
filteredFactions
);
}, [factions.data, filters]);
}, [factions.data, filters, debouncedQuery]);

const onSubmit = useCallback(
(faction: string, updates: Partial<Bitburner.FactionsSaveObject["data"]>) => {
Expand Down Expand Up @@ -93,15 +98,25 @@ export default observer(function FactionSection({ isFiltering }: Props) {
{isFiltering && (
<>
<div className="mb-4 flex gap-4">
<label className="inline-flex items-start text-slate-100">
<label className="flex items-center">
<SearchIcon className="h-6 w-6 text-slate-500" />
<Input
className="border-b border-green-900"
onChange={(e) => setQuery(e.currentTarget.value)}
value={query}
type="text"
placeholder="Search Factions..."
/>
</label>
<label className="inline-flex items-center text-slate-100">
<Checkbox onChange={onEditFilters} data-key="alreadyInvited" checked={filters.alreadyInvited ?? false} />
<span className="ml-2">Invited?</span>
</label>
<label className="inline-flex items-start text-slate-100">
<label className="inline-flex items-center text-slate-100">
<Checkbox onChange={onEditFilters} data-key="isMember" checked={filters.isMember ?? false} />
<span className="ml-2">Joined?</span>
</label>
<label className="inline-flex items-start text-slate-100">
<label className="inline-flex items-center text-slate-100">
<Checkbox onChange={onEditFilters} data-key="isBanned" checked={filters.isBanned ?? false} />
<span className="ml-2">Banned?</span>
</label>
Expand Down Expand Up @@ -153,15 +168,11 @@ const Faction = function Faction({ id, faction, onSubmit }: FactionProps) {
const [editing, setEditing] = useState(false);
const [state, setState] = useState(Object.assign({}, faction.data));

const onClickEnter = useCallback<MouseEventHandler<HTMLDivElement>>(
(event) => {
setEditing(true);
// So clicking into the box does not trigger checkboxes.
if ((event.target as HTMLElement).tagName === "svg") event.preventDefault();
console.log(state.augmentations);
},
[state.augmentations]
);
const onClickEnter = useCallback<MouseEventHandler<HTMLDivElement>>((event) => {
setEditing(true);
// So clicking into the box does not trigger checkboxes.
if ((event.target as HTMLElement).tagName === "svg") event.preventDefault();
}, []);

const onChange = useCallback<ChangeEventHandler<HTMLInputElement>>((event) => {
const { checked, dataset, type, value } = event.currentTarget;
Expand Down Expand Up @@ -191,16 +202,16 @@ const Faction = function Faction({ id, faction, onSubmit }: FactionProps) {
<>
<div
className={clsx(
"transition-colors duration-200 ease-in-out relative inline-flex flex-col p-2 rounded border shadow shadow-green-700 border-gray-700 hover:bg-gray-800 focus-within:bg-gray-800 row-span-2",
editing && "z-20"
"transition-colors duration-200 ease-in-out relative inline-flex flex-col p-2 rounded border shadow shadow-green-700 border-gray-700 hover:bg-gray-800 focus-within:bg-gray-800 row-span-2 h-10 overflow-hidden",
editing && "z-20 h-auto"
)}
onClick={!editing ? onClickEnter : undefined}
>
<form className="grid grid-cols-3 gap-1" data-id="faction-section" onSubmit={onClose}>
<header className="col-span-2 flex items-baseline justify-between">
<h3 className="text-lg tracking-wide text-green-100">{faction.data.name}</h3>
<h3 className="tracking-wide text-green-100">{faction.data.name}</h3>
</header>
<label className="ml-auto inline-flex items-start text-slate-100">
<label className="ml-auto inline-flex items-center text-slate-100">
<span className="mr-2 text-sm">Invited: </span>
<Checkbox
checked={state.alreadyInvited}
Expand Down
23 changes: 10 additions & 13 deletions src/components/inputs/input.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import React, { ChangeEventHandler, PropsWithChildren } from "react";
import clsx from "clsx";
import React, { ChangeEventHandler, InputHTMLAttributes, PropsWithChildren } from "react";

interface Props extends PropsWithChildren<{}> {
"data-key": string;
disabled?: boolean;
onChange: ChangeEventHandler<HTMLInputElement>;
type: React.HTMLInputTypeAttribute;
value?: string;
interface Props extends PropsWithChildren<InputHTMLAttributes<HTMLInputElement>> {
"data-key"?: string;
}

export function Input({ "data-key": dataKey, disabled, onChange, type, value }: Props) {
export function Input({ "data-key": dataKey, className, ...props }: Props) {
return (
<input
className="w-full bg-transparent px-2 py-1 rounded border-gray-800 hover:bg-gray-900 focus:bg-gray-900 outline-none disabled:opacity-50"
className={clsx(
"w-full bg-transparent px-2 py-1 rounded border-gray-800 hover:bg-gray-900 focus:bg-gray-900 outline-none disabled:opacity-50",
className
)}
data-key={dataKey}
disabled={disabled}
value={value}
type={type}
onChange={onChange}
{...props}
/>
);
}
3 changes: 3 additions & 0 deletions src/icons/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/store/file.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export class FileStore {

constructor() {
makeAutoObservable(this);
autorun(() => console.log("filestore autorun"));

// @ts-ignore
window.store = this;
Expand Down Expand Up @@ -115,9 +114,12 @@ export class FileStore {
const downloadLink = document.createElement("a");
downloadLink.style.display = "none";
downloadLink.href = blobUrl;
const match = this.file.name.match(/bitburnerSave_(?<ts>\d+)_(?<bn>BN.*).json/);

downloadLink.download = `bitburnerSave_${
Math.floor(Date.now() / 1000) // Seconds, not milliseconds
}_BN1x0-H4CKeD.json`; // Adding BN1x0 blindly for now, don't understand why it's there in the original filename.
}_${match.groups.bn ?? "BN1x0"}-H4CKeD.json`;

document.body.appendChild(downloadLink);
downloadLink.click();

Expand Down
17 changes: 17 additions & 0 deletions src/util/hooks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useEffect, useState } from "react";

export function useDebounce<T>(value: T, delay: number) {
const [debouncedValue, setDebouncedValue] = useState(value);

useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);

return () => {
clearTimeout(handler);
};
}, [value, delay]);

return debouncedValue;
}

0 comments on commit f1f7f48

Please sign in to comment.