1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
import React from 'react';
import { ApiCountedResource, ApiProduction, ApiResourceType } from '../../api/model';
import './ProductionBar.css'
type ProductionBarProps = {
gold: number,
production: ApiProduction,
}
export const ProductionBar = ({gold, production}: ProductionBarProps) => {
return <div className='production-bar'>
<GoldIndicator amount={gold}/>
<FixedResources resources={production.fixedResources}/>
<AlternativeResources resources={production.alternativeResources}/>
</div>;
};
type GoldIndicatorProps = {
amount: number,
}
const GoldIndicator = ({amount}: GoldIndicatorProps) => {
return <TokenWithCount tokenName="coin" count={amount} otherClasses="gold-indicator"/>
};
type FixedResourcesProps = {
resources: ApiCountedResource[],
}
const FixedResources = ({resources}: FixedResourcesProps) => {
return <div className="fixed-resources">
{resources.map(r => <TokenWithCount key={r.type}
tokenName={getTokenName(r.type)}
count={r.count}
otherClasses="resource-with-count"/>)}
</div>
};
type AlternativeResourcesProps = {
resources: ApiResourceType[][],
}
const AlternativeResources = ({resources}: AlternativeResourcesProps) => {
return <div className="alternative-resources">
{resources.map((types, i) => <ResourceChoice key={i} types={types}/>)}
</div>
};
type ResourceChoiceProps = {
types: ApiResourceType[],
}
const ResourceChoice = ({types}: ResourceChoiceProps) => {
let typeImages = types.map(type => <TokenImage key={type} tokenName={getTokenName(type)}/>);
let separator = <span className="choice-separator">∕</span>;
return <div className="resource-choice">
{intersperce(typeImages, separator)}
</div>
};
function intersperce<T>(array: T[], separator: T): T[] {
let result = array.reduce((acc: T[], elt: T) => acc.concat(elt, separator), []);
return result.slice(0, -1); // remove extra separator at the end
}
type TokenWithCountProps = {
tokenName: string,
count: number,
otherClasses?: string,
}
const TokenWithCount = ({tokenName, count, otherClasses = ""}: TokenWithCountProps) => {
return <div className={`token-with-count ${otherClasses}`}>
<TokenImage tokenName={tokenName}/>
<span className="token-count">× {count}</span>
</div>
};
type TokenImageProps = {
tokenName: string,
}
const TokenImage = ({tokenName}: TokenImageProps) => {
return <img src={getTokenImagePath(tokenName)} title={tokenName} alt={tokenName} className="token-img"/>
};
function getTokenImagePath(tokenName: string): string {
return `/images/tokens/${tokenName}.png`;
}
function getTokenName(resourceType: ApiResourceType): string {
return `resources/${resourceType.toLowerCase()}`;
}
|