+
Skip to content
Merged
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
132 changes: 86 additions & 46 deletions src/common/components/card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import CardCostBadge from './CardCostBadge';
import CardImage from './CardImage';
import CardStat from './CardStat';
import Sentence from './Sentence';
import RaritySymbol from './RaritySymbol';

export interface CardProps {
children?: string | JSX.Element[]
Expand All @@ -44,6 +45,7 @@ export interface CardProps {
baseCost?: number
source: w.CardSource
collection?: boolean
rarityInSet?: w.CardInSetRarity // (rarity exists only for cards in sets, and only if enabled by the set owner)

visible: boolean
status?: {
Expand All @@ -67,6 +69,7 @@ export interface CardProps {

interface CardState {
shadow: number
showingFlavorText: boolean
}

export class Card extends React.Component<CardProps & WithStyles, CardState> {
Expand All @@ -75,37 +78,39 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
lineHeight: 'normal'
},
headerSubtitle: {
lineHeight: 'normal'
lineHeight: 1
}
}

public static fromObj = (card: w.PossiblyObfuscatedCard, props: Partial<CardProps> = {}): JSX.Element => (
public static fromObj = (card: w.PossiblyObfuscatedCard & { rarity?: w.CardInSetRarity }, props: Partial<CardProps> = {}): JSX.Element => (
isCardVisible(card)
? (
<CardWithStyles
visible
id={card.id}
name={card.name}
spriteID={card.spriteID}
spriteV={card.spriteV}
img={card.img}
type={card.type}
text={Sentence.fromText(card.text)}
rawText={card.text || ''}
highlightedTextBlocks={card.highlightedTextBlocks}
flavorText={card.flavorText}
stats={card.stats || {}}
cardStats={card.stats || {}}
cost={card.cost}
baseCost={card.cost}
source={card.metadata.source}
{...props}
/>
<CardWithStyles
visible
id={card.id}
name={card.name}
spriteID={card.spriteID}
spriteV={card.spriteV}
img={card.img}
type={card.type}
text={Sentence.fromText(card.text)}
rawText={card.text || ''}
highlightedTextBlocks={card.highlightedTextBlocks}
flavorText={card.flavorText}
stats={card.stats || {}}
cardStats={card.stats || {}}
cost={card.cost}
baseCost={card.cost}
source={card.metadata.source}
rarityInSet={card.rarity}
{...props}
/>
) : <CardBack />
)

public state = {
shadow: 2
shadow: 2,
showingFlavorText: false
};

public shouldComponentUpdate(nextProps: CardProps, nextState: CardState): boolean {
Expand Down Expand Up @@ -139,7 +144,7 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
};

if (type === TYPE_EVENT && this.numChars < 30) {
return {...baseStyle, ...compactStyle};
return { ...baseStyle, ...compactStyle };
} else {
return baseStyle;
}
Expand All @@ -162,7 +167,7 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
};

if (type === TYPE_EVENT && this.numChars < 30) {
return {...baseStyle, ...compactStyle};
return { ...baseStyle, ...compactStyle };
} else {
return baseStyle;
}
Expand All @@ -171,7 +176,7 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
public render(): JSX.Element {
const {
name, spriteID, spriteV, type, img, cost, baseCost, source, collection, flavorText,
showSpinner, status, visible, selected, targetable,
showSpinner, status, visible, selected, targetable, rarityInSet,
scale, margin, rotation, yTranslation, overrideContainerStyles,
onSpriteClick, classes
} = this.props;
Expand Down Expand Up @@ -231,13 +236,24 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
>
<CardHeader
key={`${name}_${type}_${flavorText}`}
style={{padding: 8 * (scale || 1), height: 'auto'}}
style={{ padding: 8 * (scale || 1), height: 'auto' }}
title={this.renderTitle()}
subheader={
<span style={{fontSize: 14 * (scale || 1)}}>
<span style={{ fontSize: 14 * (scale || 1) }} onClick={this.handleToggleFlavorText}>
{typeToString(type)}
{flavorText && <Tooltip inline text={flavorText}>
{rarityInSet && (
<div style={{
float: 'right',
marginTop: -4 * (scale || 1),
marginLeft: 5 * (scale || 1),
marginBottom: -3 * (scale || 1)
}}>
<RaritySymbol rarity={rarityInSet} scale={(scale || 1) * 1.2} />
</div>
)}
{flavorText && <Tooltip inline text="Show/hide flavor text" place="left" className="card-part-tooltip">
<Icon className="material-icons" style={{
marginTop: 4 * (scale || 1),
fontSize: 16 * (scale || 1),
color: '#999',
float: 'right'
Expand All @@ -253,6 +269,7 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
}}
/>


<Divider style={{ margin: '-1px 0px 0px' }} />

<CardImage
Expand Down Expand Up @@ -301,6 +318,17 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
}
}

private handleToggleFlavorText = (evt: React.MouseEvent<Element>) => {
evt.stopPropagation();
evt.preventDefault();

// Toggle flavor text; make sure that it's back to real text in 10 sec.
this.setState((state) => ({ showingFlavorText: !state.showingFlavorText }));
setTimeout(() => {
this.setState({ showingFlavorText: false });
}, 10000);
}

private handleMouseEnter = () => {
const { onCardHover } = this.props;
this.setState({ shadow: 3 });
Expand Down Expand Up @@ -340,32 +368,44 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
}

private renderText(): React.ReactNode {
const { highlightedTextBlocks, rawText, text, scale } = this.props;
const { highlightedTextBlocks, flavorText, rawText, text, scale } = this.props;
const { showingFlavorText } = this.state;

if (!inBrowser()) {
return text;
}

return (
<Textfit
autoResize={false}
mode="multi"
max={14 * (scale || 1)}
style={this.textFitStyle}
>
{
highlightedTextBlocks
? <Highlighter
} else if (showingFlavorText) {
return (
<Textfit
autoResize={false}
mode="multi"
max={14 * (scale || 1)}
style={this.textFitStyle}
>
<span style={{ fontFamily: 'Carter One, Carter One-fallback' }}>{flavorText}</span>
</Textfit>
);
} else {
return (
<Textfit
autoResize={false}
mode="multi"
max={14 * (scale || 1)}
style={this.textFitStyle}
>
{
highlightedTextBlocks
? <Highlighter
autoEscape
textToHighlight={rawText}
searchWords={highlightedTextBlocks}
highlightStyle={{ color: 'green', fontWeight: 'bold', backgroundColor: 'inherit' }}
unhighlightStyle={{ color: 'black' }}
/>
: text
}
</Textfit>
);
: text
}
</Textfit>
);
}
}

private renderStat(type: w.Attribute): JSX.Element {
Expand Down Expand Up @@ -394,7 +434,7 @@ export class Card extends React.Component<CardProps & WithStyles, CardState> {
);
} else if (type === TYPE_CORE || type === TYPE_STRUCTURE) {
return (
<CardContent style={{...style, marginLeft: '31%'}}>
<CardContent style={{ ...style, marginLeft: '31%' }}>
{this.renderStat('health')}
</CardContent>
);
Expand Down
10 changes: 7 additions & 3 deletions src/common/components/card/CardCostBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Badge from '@material-ui/core/Badge';
import * as React from 'react';

import Tooltip from '../Tooltip';

interface CardCostBadgeProps {
children: JSX.Element
cost: number
Expand All @@ -12,9 +14,11 @@ export default class CardCostBadge extends React.Component<CardCostBadgeProps> {
get badgeContent(): JSX.Element {
return (
<div style={this.badgeStyle}>
<div style={{ lineHeight: 2.4 }}>
{this.props.cost}
</div>
<Tooltip text="Cost" place="left" className="card-part-tooltip">
<div style={{ lineHeight: 2.4, userSelect: 'none' }}>
{this.props.cost}
</div>
</Tooltip>
</div>
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/common/components/card/CardStat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default class CardStat extends React.Component<CardStatProps> {

if (current && current !== base) {
return (
<span style={{position: 'relative'}}>
<span style={{ position: 'relative' }}>
<span style={baseStatStyle}>
&nbsp;{base}&nbsp;
</span>
Expand Down Expand Up @@ -101,8 +101,8 @@ export default class CardStat extends React.Component<CardStatProps> {
);
} else {
return (
<Tooltip text={capitalize(this.props.type)}>
<div style={{...style, cursor: 'pointer'}}>
<Tooltip text={capitalize(this.props.type)} className="card-part-tooltip">
<div style={{ ...style, cursor: 'pointer' }}>
{this.icon}
{this.statText}
</div>
Expand Down
39 changes: 39 additions & 0 deletions src/common/components/card/RaritySymbol.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { capitalize } from 'lodash';
import * as React from 'react';

import * as w from '../../types';
import Tooltip from '../Tooltip';

interface RaritySymbolProps {
rarity: w.CardInSetRarity
scale?: number
isEditing?: boolean
}

export default function RaritySymbol({ rarity, scale, isEditing }: RaritySymbolProps): JSX.Element {
return (
<span style={{
display: 'inline-block',
userSelect: 'none',
fontSize: ({ rare: 17, uncommon: 27, common: 26 })[rarity] * (scale || 1),
marginTop: ({ rare: 5, uncommon: -3, common: 0 })[rarity] * (scale || 1),
marginLeft: ({ rare: -1, uncommon: -2, common: 0 })[rarity] * (scale || 1),
color: ({ rare: '#d4af37', uncommon: '#aaa9ad', common: undefined })[rarity]
}}>
<Tooltip
key={rarity}
text={`${capitalize(rarity)}${isEditing ? ' (click to change)' : ''}`}
place="left"
className="card-part-tooltip"
>
{
({
'common': '●',
'uncommon': '◆',
'rare': '★'
})[rarity]
}
</Tooltip>
</span>
);
}
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载