Check if a command should be copied or HTTP should be used

This commit is contained in:
KingRainbow44 2023-05-11 22:52:09 -04:00
parent ef263cb326
commit 564e4e496b
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
5 changed files with 110 additions and 9 deletions

View File

@ -0,0 +1,23 @@
/**
* Validates a number.
*
* @param value The number to validate.
*/
function invalid(value: number): boolean {
return isNaN(value) || value < 0;
}
/**
* Generates a basic give command.
*/
function basicGive(item: number, amount = 1): string {
// Validate the numbers.
if (invalid(item) || invalid(amount))
return "Invalid arguments.";
return `/give ${item} x${amount}`;
}
export const give = {
basic: basicGive
};

View File

@ -1,6 +1,8 @@
import type { CommandResponse } from "@backend/types";
import emitter from "@backend/events";
let targetPlayer = 0; // The UID of the target player.
export let connected = false; // Whether the server is connected.
/**
* Sets the target player.
@ -9,7 +11,10 @@ let targetPlayer = 0; // The UID of the target player.
*/
export function setTargetPlayer(player: number): void {
targetPlayer = player;
console.log(`Target Player is now: ${targetPlayer}`);
connected = !isNaN(player) && player > 0;
// Emit the connected event.
emitter.emit("connected", connected);
}
/**

View File

@ -0,0 +1,47 @@
import React from "react";
import emitter from "@backend/events";
interface IProps {
event: string;
text1: string;
text2: string;
}
interface IState {
state: boolean;
}
class TextState extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
state: false
};
}
/**
* Updates the current state.
* @private
*/
private update(state: boolean): void {
this.setState({ state });
}
componentDidMount(): void {
emitter.on(this.props.event, this.update.bind(this));
}
componentWillUnmount(): void {
emitter.off(this.props.event, this.update);
}
render() {
return this.state.state ?
this.props.text2 :
this.props.text1;
}
}
export default TextState;

View File

@ -1,9 +1,12 @@
import React from "react";
import TextState from "@components/TextState";
import type { Item as ItemType, ItemInfo } from "@backend/types";
import { itemTypeToString } from "@backend/types";
import { itemIcon } from "@app/utils";
import { giveItem } from "@backend/server";
import { copyToClipboard, itemIcon } from "@app/utils";
import { connected, giveItem } from "@backend/server";
import { give } from "@backend/commands";
import "@css/widgets/ItemCard.scss";
@ -82,10 +85,17 @@ class ItemCard extends React.Component<IProps, IState> {
* @private
*/
private async addToInventory(): Promise<void> {
await giveItem(
this.props.item?.id ?? 102,
typeof this.state.count == "string" ? parseInt(this.state.count) : this.state.count
);
const item = this.props.item?.id ?? 102;
const amount = typeof this.state.count == "string" ?
parseInt(this.state.count) :
this.state.count;
if (connected) {
await giveItem(item, amount);
} else {
await copyToClipboard(
give.basic(item, amount));
}
}
componentDidUpdate(prevProps: Readonly<IProps>, prevState: Readonly<IState>, snapshot?: any) {
@ -155,8 +165,14 @@ class ItemCard extends React.Component<IProps, IState> {
</div>
</div>
<button className={"ItemCard_Submit"} onClick={this.addToInventory.bind(this)}>
Add to Inventory
<button className={"ItemCard_Submit"}
onClick={this.addToInventory.bind(this)}
>
<TextState
event={"connected"}
text1={"Copy Command"}
text2={"Add to Inventory"}
/>
</button>
</div>
</div>

View File

@ -134,3 +134,13 @@ export async function fetchEntityData(entity: Entity): Promise<EntityInfo> {
.then((res) => res.json())
.catch(() => {});
}
/**
* Attempts to copy text to the clipboard.
* Uses the Clipboard API.
*
* @param text The text to copy.
*/
export async function copyToClipboard(text: string): Promise<void> {
await navigator.clipboard.writeText(text);
}