mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-10 04:12:54 +08:00
Check if a command should be copied or HTTP should be used
This commit is contained in:
parent
ef263cb326
commit
564e4e496b
23
src/handbook/src/backend/commands.ts
Normal file
23
src/handbook/src/backend/commands.ts
Normal 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
|
||||
};
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
47
src/handbook/src/ui/components/TextState.tsx
Normal file
47
src/handbook/src/ui/components/TextState.tsx
Normal 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;
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user