Skip to content
This repository was archived by the owner on Dec 5, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all 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
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# RPG-Inventory-UI
Drag &amp; Drop Inventory RPG Style using React. <br>
This is a pretty old resource!

### Todo
```
Switch to Redux
Support user keybinds
```

### Preview
![](https://i.imgur.com/4Y2YYT0.jpg)
40 changes: 37 additions & 3 deletions app/Inventory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export class Inventory extends Component<any, any> {
super(props)
this.state = {
clothes : false,
targetClothes : false
targetClothes : false,
searchPocketsValue: '',
searchOtherValue: '',
pocketsOrder: 0,
targetOrder: 0
}
}

Expand All @@ -55,6 +59,14 @@ export class Inventory extends Component<any, any> {
top: dragStore.mousey - offset * 2
}
}

requestFullFocus() {
fetch('http://gtalife/askFullFocus', { method: 'POST', body: "{}" })
}

releaseFullFocus() {
fetch('http://gtalife/releaseFullFocus', { method: 'POST', body: "{}" })
}

render() {
const icons = Icons
Expand All @@ -66,11 +78,22 @@ export class Inventory extends Component<any, any> {
<div className={"title" + (this.state.clothes ? "" : " selected")} onClick={() => this.setState({ clothes : false })}>Inventaire</div>
<div className="title" style={{ pointerEvents: 'none' }}>&nbsp;&nbsp;|&nbsp;&nbsp;</div>
<div className={"title" + (!this.state.clothes ? "" : " selected")} onClick={() => this.setState({ clothes : true })} >Vêtements</div>
<div className="title" style={{ pointerEvents: 'none' }}>&nbsp;&nbsp;|&nbsp;&nbsp;</div>
<div className="title">
<span className="dropdown-parent">Trier par &#9660;</span>
<div className="dropdown">
<div onClick={() => this.setState({ pocketsOrder : 0 })} className={this.state.pocketsOrder == 0 ? "selected" : ""}>{this.state.pocketsOrder == 0 ? "✔ " : ""}Alphabétique</div>
<div onClick={() => this.setState({ pocketsOrder : 1 })} className={this.state.pocketsOrder == 1 ? "selected" : ""}>{this.state.pocketsOrder == 1 ? "✔ " : ""}Nombre</div>
{/* <div onClick={() => this.setState({ pocketsOrder : 2 })} className={this.state.pocketsOrder == 2 ? "selected" : ""}>{this.state.pocketsOrder == 2 ? "✔ " : ""}Poids</div> */}
</div>
</div>
<div className="title" style={{ pointerEvents: 'none' }}>&nbsp;&nbsp;|&nbsp;&nbsp;</div>
<div className="title"><input onFocus={() => this.requestFullFocus()} onBlur={() => this.releaseFullFocus()} className="searchBox" type="text" onChange={(event) => this.setState({ searchPocketsValue: event.target.value })} placeholder="Rechercher"/></div>
<div className="infos">{inventoryStore.pocketsWeight} / 45</div>
</div>
<SwitchTransition>
<FadeTransition key={this.state.clothes ? "lol" : "no"}>
<ItemList items={this.state.clothes ? inventoryStore.clothes : inventoryStore.pockets} eventName="inventory" />
<ItemList items={this.state.clothes ? inventoryStore.clothes : inventoryStore.pockets} order={this.state.pocketsOrder} searchValue={this.state.searchPocketsValue} eventName="inventory" />
</FadeTransition>
</SwitchTransition>

Expand All @@ -92,14 +115,25 @@ export class Inventory extends Component<any, any> {
<div className={"title" + (this.state.targetClothes ? "" : " selected")} onClick={() => this.setState({ targetClothes : false })}>Coffre</div>
<div className="title" style={{ pointerEvents: 'none' }}>&nbsp;&nbsp;|&nbsp;&nbsp;</div>
<div className={"title" + (!this.state.targetClothes ? "" : " selected")} onClick={() => this.setState({ targetClothes : true })} >Vêtements</div>
<div className="title" style={{ pointerEvents: 'none' }}>&nbsp;&nbsp;|&nbsp;&nbsp;</div>
<div className="title">
<span className="dropdown-parent">Trier par &#9660;</span>
<div className="dropdown">
<div onClick={() => this.setState({ targetOrder : 0 })} className={this.state.targetOrder == 0 ? "selected" : ""}>{this.state.targetOrder == 0 ? "✔ " : ""}Alphabétique</div>
<div onClick={() => this.setState({ targetOrder : 1 })} className={this.state.targetOrder == 1 ? "selected" : ""}>{this.state.targetOrder == 1 ? "✔ " : ""}Nombre</div>
{/* <div onClick={() => this.setState({ targetOrder : 2 })} className={this.state.targetOrder == 2 ? "selected" : ""}>{this.state.targetOrder == 2 ? "✔ " : ""}Poids</div> */}
</div>
</div>
<div className="title" style={{ pointerEvents: 'none' }}>&nbsp;&nbsp;|&nbsp;&nbsp;</div>
<div className="title"><input onFocus={() => this.requestFullFocus()} onBlur={() => this.releaseFullFocus()} className="searchBox" type="text" onChange={(event) => this.setState({ searchOtherValue: event.target.value })} placeholder="Rechercher"/></div>
<div className="infos">{inventoryStore.targetWeight} / {inventoryStore.targetMaxWeight}</div>
</div>
)}

{inventoryStore.targetMaxWeight > 0 && (
<SwitchTransition>
<FadeTransition key={this.state.targetClothes ? "lol" : "no"}>
<ItemList IsTarget={true} items={this.state.targetClothes ? inventoryStore.targetClothes : inventoryStore.target} eventName="targetInventory" />
<ItemList IsTarget={true} items={this.state.targetClothes ? inventoryStore.targetClothes : inventoryStore.target} order={this.state.targetOrder} searchValue={this.state.searchOtherValue} eventName="targetInventory" />
</FadeTransition>
</SwitchTransition>
)}
Expand Down
24 changes: 22 additions & 2 deletions app/ItemList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,19 @@ export class ItemList extends Component<any, any> {

get items() {
if (this.props.items) {
return this.props.items.map((item, id) => {
const order = this.props.order;
return this.props.items.sort((a, b) => {
switch(order) {
case 0:
return a.name.toString().localeCompare(b.name.toString());

case 1:
return b.qty - a.qty

case 2:
}

}).map((item, id) => {
return <Item target={this.props.IsTarget} data={item} key={id} />
})
}
Expand All @@ -37,6 +49,14 @@ export class ItemList extends Component<any, any> {
this.setState({ dragOver: false })
}

filteredItems(searchValue) {
const low = searchValue.toLowerCase()
return this.props.items.sort((a, b) => a.name.toString().localeCompare(b.name.toString())).map((item, id) => {
if (item.name.toString().toLowerCase().indexOf(low) != -1)
return <Item target={this.props.IsTarget} data={item} key={id} />
})
}

scroll({ style, ...props }) {
return (
<div
Expand All @@ -61,7 +81,7 @@ export class ItemList extends Component<any, any> {
tabIndex={-1}
>
<Scrollbars renderThumbVertical={this.scroll}>
{this.items}
{this.props.searchValue.length == 0 ? this.items : this.filteredItems(this.props.searchValue) }
</Scrollbars>
</div>
)
Expand Down
1 change: 1 addition & 0 deletions app/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export class Item extends Component<any, any> {

onMouseEnter={this.onMouseEnter.bind(this)}
onMouseLeave={this.onMouseLeave.bind(this)}
onContextMenu={(e) => e.preventDefault()}
>

{(this.props.keyNumber || (this.props.data && this.props.data.qty)) && this.label}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"dev": "parcel index.pug --no-cache -d ../dist",
"build": "parcel build index.pug --no-cache -d ../dist --public-url '.'",
"webpack": "NODE_ENV=production webpack --mode production",
"webpack": "SET NODE_ENV=production webpack --mode production",
"devWebpack": "webpack-dev-server --mode development"
},
"keywords": [],
Expand Down
43 changes: 43 additions & 0 deletions sass/_inventory.scss
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,49 @@
&.selected, &:hover {
color: rgba(255, 255, 255, 1.0);
}

.dropdown {
position: absolute;
min-width: 12%;
max-width: 12%;

div {
background: rgba(100, 100, 100, 0.3);
padding: 5px;
text-align: center;
}

div.selected, div:hover {
background: rgba(100, 100, 100, 0.6);
}

display: none;
z-index: 1;
}

&:hover .dropdown, .dropdown:hover {
display: block;
}

.searchBox {
border: .2px solid rgba(100, 100, 100, 0.8);
border-radius: 5px;
font-size: 9px;
padding: 5px;
text-align: center;

background: rgba(100, 100, 100, 0);
color: white;

&::-webkit-input-placeholder { /* Edge */
color: white;
}

&:focus {
outline: none;
background: rgba(100, 100, 100, 0.3);
}
}
}
.infos {
float: right;
Expand Down
41 changes: 18 additions & 23 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -866,11 +866,6 @@
"@types/prop-types" "*"
csstype "^2.2.0"

"@types/socket.io-client@^1.4.32":
version "1.4.32"
resolved "https://registry.yarnpkg.com/@types/socket.io-client/-/socket.io-client-1.4.32.tgz#988a65a0386c274b1c22a55377fab6a30789ac14"
integrity sha512-Vs55Kq8F+OWvy1RLA31rT+cAyemzgm0EWNeax6BWF8H7QiiOYMJIdcwSDdm5LVgfEkoepsWkS+40+WNb7BUMbg==

"@webassemblyjs/[email protected]":
version "1.8.5"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
Expand Down Expand Up @@ -1092,10 +1087,10 @@ acorn@^5.0.0, acorn@^5.0.3, acorn@^5.5.3, acorn@^5.6.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==

acorn@^6.0.1, acorn@^6.0.5:
version "6.1.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
acorn@^6.0.0, acorn@^6.0.1, acorn@^6.0.5:
version "6.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474"
integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==

[email protected]:
version "1.0.0"
Expand Down Expand Up @@ -4616,6 +4611,11 @@ jsesc@~0.5.0:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=

json-loader@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==

json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
Expand Down Expand Up @@ -4808,9 +4808,9 @@ lodash.uniq@^4.5.0:
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=

lodash@^4.0.0, lodash@^4.13.1, lodash@^4.17.11, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.10:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==

log-symbols@^2.2.0:
version "2.2.0"
Expand Down Expand Up @@ -5118,9 +5118,9 @@ mississippi@^3.0.0:
through2 "^2.0.0"

mixin-deep@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe"
integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==
version "1.3.2"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==
dependencies:
for-in "^1.0.2"
is-extendable "^1.0.1"
Expand Down Expand Up @@ -7149,9 +7149,9 @@ safe-regex@^1.1.0:
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==

safer-eval@^1.3.0:
version "1.3.3"
resolved "https://registry.yarnpkg.com/safer-eval/-/safer-eval-1.3.3.tgz#0309e9fcc0609e66c1b599fd0d4772132b260ca8"
integrity sha512-j/qb0rtnwTp5V1D7nR0Ns/14HU8OiHPaoZNJhM+Lfmv1nbXZCXG9LHaVW157agEocdSVAeeRNddK/yuWfalzGQ==
version "1.3.6"
resolved "https://registry.yarnpkg.com/safer-eval/-/safer-eval-1.3.6.tgz#ee51e3348c39fdc4117a47dfb4b69df56a2e40cf"
integrity sha512-DN9tBsZgtUOHODzSfO1nGCLhZtxc7Qq/d8/2SNxQZ9muYXZspSh1fO7HOsrf4lcelBNviAJLCxB/ggmG+jV1aw==
dependencies:
clones "^1.2.0"

Expand Down Expand Up @@ -7266,11 +7266,6 @@ serialize-to-js@^1.1.1:
js-beautify "^1.8.9"
safer-eval "^1.3.0"

serialize-to-js@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/serialize-to-js/-/serialize-to-js-3.0.0.tgz#1fd8736744819a4df29dc85e9d04a44a4984edc3"
integrity sha512-WdGgi0jGnWCQXph2p3vkxceDnTfvfyXfYxherQMRcZjSaJzMQdMBAW6i0nojsBKIZ3fFOztZKKVbbm05VbIdRA==

serve-index@^1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
Expand Down