Compare commits

...

7 Commits

Author SHA1 Message Date
c3fc993f5a added ";" for convar 2021-11-16 02:39:40 +01:00
64f1ea0be6 added fromObject method 2021-11-16 02:16:37 +01:00
9e7b456400 implemented save 2021-11-16 01:13:59 +01:00
7cc9fd7722 copy to clipboard 2021-11-16 01:04:59 +01:00
c036d7d5ca export modal 2021-11-16 00:58:56 +01:00
bd271021f1 eslint fix 2021-11-15 23:36:57 +01:00
63b1538a37 something broke with eslint. fixed it 2021-11-15 23:35:56 +01:00
9 changed files with 1808 additions and 2240 deletions

View File

@@ -9,6 +9,7 @@
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"autoprefixer": "^9",
"copy-to-clipboard": "^3.3.1",
"postcss": "^7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
@@ -43,7 +44,6 @@
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"eslint": "^8.2.0",
"eslint-plugin-react": "^7.27.0"
}
}

View File

@@ -1,25 +1,61 @@
import React, { useState } from "react"
import React, { useEffect, useState } from "react"
import copy from "copy-to-clipboard"
import RetakesConfig from "../types/RetakesConfig"
import AllDecks from "./AllDecks"
import MenuBar from "./MenuBar"
import Modal from "./Modal"
function App() {
const App: React.FC = () => {
const [retakesConfig,setRetakesConfig] = useState(new RetakesConfig())
const [showExport,setShowExport] = useState(false)
const [exportText,setExportText] = useState("")
useEffect(()=>{
// Load saved config
const retakesJSON = window.localStorage.getItem("retakesJSON")
if (retakesJSON){
try{
const parsedConfig: Record<string,unknown> = JSON.parse(retakesJSON)
setRetakesConfig(RetakesConfig.fromObject(parsedConfig))
}catch(err){
window.localStorage.removeItem("retakesJSON")
}
}
},[])
return (
<div className="text-white">
<MenuBar
onExport={()=>{
const exportString = retakesConfig.toCvar()
console.log(exportString)
setExportText(retakesConfig.toCvar())
setShowExport(true)
}}
onExportJson={()=>{
setExportText(JSON.stringify(retakesConfig))
setShowExport(true)
}}
onSave={()=>{
const jsonString = JSON.stringify(retakesConfig)
console.log(jsonString)
}}
window.localStorage.setItem("retakesJSON",jsonString)
// TODO: user feedback that config was saved
}}
/>
<AllDecks retakesConfig={retakesConfig} onChange={(newConfig)=>setRetakesConfig(newConfig)} />
<Modal show={showExport} onCloseClick={()=>setShowExport(false)}>
<div className="flex justify-center mb-2">
<textarea
cols={50} rows={10}
value={exportText}
readOnly
className="bg-transparent border-2 border-gray-900"
/>
</div>
<div
className="bg-gray-700 button flex justify-center"
onClick={()=>copy(exportText)}
>Copy to clipboard</div>
</Modal>
</div>
)
}

View File

@@ -3,9 +3,10 @@ import React from "react"
interface Props {
onExport?: ()=>void
onExportJson?: ()=>void
onSave?:()=>void
}
const MenuBar: React.FC<Props> = ({onExport,onExportJson}) => {
const MenuBar: React.FC<Props> = ({onExport,onExportJson,onSave}) => {
return (
<div className="bg-gray-800 h-10 m-1 p-1 flex">
<div className="bg-gray-700 button" onClick={onExport}>
@@ -13,6 +14,9 @@ const MenuBar: React.FC<Props> = ({onExport,onExportJson}) => {
</div>
<div className="bg-gray-700 button" onClick={onExportJson}>
Export to JSON
</div>
<div className="bg-gray-700 button" onClick={onSave}>
Save
</div>
<a href="https://developer.valvesoftware.com/wiki/CS:GO_Game_Mode_-_Retakes" target="_blank" rel='noreferrer'>
<div className="bg-gray-700 button">

26
src/components/Modal.tsx Normal file
View File

@@ -0,0 +1,26 @@
import React from "react"
interface Props {
show: boolean
onCloseClick?: ()=>void
}
const Modal: React.FC<Props> = ({children,show,onCloseClick}) => {
return (
<div
className={`${!show?"hidden":"" }
fixed z-10 left-0 top-0 w-full h-full
flex justify-center items-center bg-gray-900 bg-opacity-80`}
onClick={()=>{
onCloseClick?.()
}}>
<div className="bg-gray-800 mx-auto p-5 border-2 border-gray-800 w-10/12 overflow-hidden max-h-full" onClick={(e)=>{
e.stopPropagation()
}}>
{children}
</div>
</div>
)
}
export default Modal

View File

@@ -16,6 +16,15 @@ class Card {
public toCvar(): string {
return `${this.title},${bToS(this.armor)},${bToS(this.helmet)},${this.items.join(",")}`
}
static fromObject(input: Record<string, unknown>): Card {
return new Card(
input.title as string,
input.armor as boolean,
input.helmet as boolean,
...input.items as Item[]
)
}
}
/**

View File

@@ -12,6 +12,13 @@ class CardGroup {
public toCvar(): string {
return `${this.numInDeck};${this.cards.map(e => e.toCvar()).join(";")}`
}
static fromObject(input: Record<string, unknown>): CardGroup{
return new CardGroup(
input.numInDeck as number,
...(input.cards as Record<string, unknown>[]).map((e)=>Card.fromObject(e))
)
}
}
export default CardGroup

View File

@@ -12,6 +12,13 @@ class Deck {
public toCvar(): string {
return `${this.numDefusers}|${this.cardGroups.map(e => e.toCvar()).join("|")}`
}
static fromObject(input: Record<string, unknown>): Deck{
return new Deck(
input.numDefusers as number,
...(input.cardGroups as Record<string, unknown>[]).map((e)=>CardGroup.fromObject(e))
)
}
}
export default Deck

View File

@@ -60,21 +60,41 @@ class RetakesConfig {
}
public toCvar(): string{
return `mp_retake_ct_loadout_default_pistol_round "${this.ctPistol.toCvar()}"
mp_retake_t_loadout_default_pistol_round "${this.tPistol.toCvar()}"
mp_retake_ct_loadout_upgraded_pistol_round "${this.ctUpgradedPistol.toCvar()}"
mp_retake_t_loadout_upgraded_pistol_round "${this.tUpgradedPistol.toCvar()}"
mp_retake_ct_loadout_light_buy_round "${this.ctLight.toCvar()}"
mp_retake_t_loadout_light_buy_round "${this.tLight.toCvar()}"
mp_retake_ct_loadout_full_buy_round "${this.ctFull.toCvar()}"
mp_retake_t_loadout_full_buy_round "${this.tFull.toCvar()}"
mp_retake_ct_loadout_bonus_card "${this.ctBonus.toCvar()}"
mp_retake_t_loadout_bonus_card "${this.tBonus.toCvar()}"
mp_retake_ct_loadout_bonus_card_availability "${this.ctBonusAvailability.join(",")}"
mp_retake_t_loadout_bonus_card_availability "${this.tBonusAvailability.join(",")}"
console.debug("THIS:")
return `mp_retake_ct_loadout_default_pistol_round "${this.ctPistol.toCvar()}";
mp_retake_t_loadout_default_pistol_round "${this.tPistol.toCvar()}";
mp_retake_ct_loadout_upgraded_pistol_round "${this.ctUpgradedPistol.toCvar()}";
mp_retake_t_loadout_upgraded_pistol_round "${this.tUpgradedPistol.toCvar()}";
mp_retake_ct_loadout_light_buy_round "${this.ctLight.toCvar()}";
mp_retake_t_loadout_light_buy_round "${this.tLight.toCvar()}";
mp_retake_ct_loadout_full_buy_round "${this.ctFull.toCvar()}";
mp_retake_t_loadout_full_buy_round "${this.tFull.toCvar()}";
mp_retake_ct_loadout_bonus_card "${this.ctBonus.toCvar()}";
mp_retake_t_loadout_bonus_card "${this.tBonus.toCvar()}";
mp_retake_ct_loadout_bonus_card_availability "${this.ctBonusAvailability.join(",")}";
mp_retake_t_loadout_bonus_card_availability "${this.tBonusAvailability.join(",")}";
`
}
static fromObject(input: Record<string, unknown>): RetakesConfig {
return new RetakesConfig({
ctPistol: Deck.fromObject(input.ctPistol as Record<string, unknown>),
tPistol: Deck.fromObject(input.tPistol as Record<string,unknown>),
ctUpgradedPistol: Deck.fromObject(input.ctUpgradedPistol as Record<string,unknown>),
tUpgradedPistol: Deck.fromObject(input.tUpgradedPistol as Record<string,unknown>),
ctLight: Deck.fromObject(input.ctLight as Record<string,unknown>),
tLight: Deck.fromObject(input.tLight as Record<string,unknown>),
ctFull: Deck.fromObject(input.ctFull as Record<string,unknown>),
tFull: Deck.fromObject(input.tFull as Record<string,unknown>),
ctEnemy: Card.fromObject(input.ctEnemy as Record<string,unknown>),
tEnemy: Card.fromObject(input.tEnemy as Record<string,unknown>),
ctBonus: Card.fromObject(input.ctBonus as Record<string,unknown>),
tBonus: Card.fromObject(input.tBonus as Record<string,unknown>),
ctBonusAvailability: input.ctBonusAvailability as number[],
tBonusAvailability: input.tBonusAvailability as number[],
})
}
}
export default RetakesConfig

3897
yarn.lock

File diff suppressed because it is too large Load Diff