amaurymartiny/shoot-i-smoke

View on GitHub
App/components/Cigarettes/Cigarettes.tsx

Summary

Maintainability
A
1 hr
Test Coverage
// Shoot! I Smoke
// Copyright (C) 2018-2023 Marcelo S. Coelho, Amaury M.
 
// Shoot! I Smoke is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
 
// Shoot! I Smoke is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
 
// You should have received a copy of the GNU General Public License
// along with Shoot! I Smoke. If not, see <http://www.gnu.org/licenses/>.
 
import React from 'react';
import { StyleProp, StyleSheet, View, ViewProps } from 'react-native';
 
import { round } from '@shootismoke/ui/lib/util/api';
import { Cigarette } from './Cigarette';
 
export interface CigarettesProps extends ViewProps {
/**
* The number of cigarettes to show.
*/
cigarettes: number;
/**
* Additional styling for inner cigarettes
*/
cigaretteStyle?: StyleProp<ViewProps>;
/**
* Length, in pixels, of a full cigarette.
*
* @default 90
*/
fullCigaretteLength?: number;
/**
* The maximum number of cigarettes to show.
*
* @default 50
*/
showMaxCigarettes?: number;
/**
* For small amount of cigarettes, we display them horizontally. After this
* number, they are displayed vertically.
*
* @default 4
*/
showVerticalAfter?: number;
/**
* Horizontal spacing, in pixels, between the cigarettes, assuming the
* cigarettes are displayed vertically.
*
* @default 5
*/
spacingHorizontal?: number;
/**
* Vertical spacing, in pixels, between the cigarettes, assuming the
* cigarettes are displayed vertically.
*
* @default 20
*/
spacingVertical?: number;
}
 
const styles = StyleSheet.create({
innerContainer: {
alignContent: 'flex-end',
alignItems: 'flex-end',
flexDirection: 'row',
flexWrap: 'wrap',
},
});
 
Function `Cigarettes` has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring.
export function Cigarettes(props: CigarettesProps): React.ReactElement {
const {
cigarettes: realCigarettes,
cigaretteStyle,
fullCigaretteLength = 90,
showMaxCigarettes = 50,
showVerticalAfter = 4,
spacingHorizontal = 5,
spacingVertical = 20,
style,
...rest
} = props;
 
// We don't show more than `showMaxCigarettes` cigarettes, and we round to
// 0.1.
const cigarettes = round(
Math.max(0.1, Math.min(realCigarettes, showMaxCigarettes))
);
 
const count = Math.floor(cigarettes); // The cigarette count, without decimal.
const decimal = cigarettes - count;
 
const orientation =
cigarettes <= 1
? 'diagonal'
: cigarettes <= showVerticalAfter
? 'horizontal'
: 'vertical';
const baseCigaretteStyle =
orientation === 'diagonal'
? undefined
: orientation === 'horizontal'
? {
marginBottom: spacingHorizontal,
marginRight: spacingVertical,
}
: {
marginBottom: spacingVertical,
marginRight: spacingHorizontal,
};
 
return (
<View style={[styles.innerContainer, style]} {...rest}>
{cigarettes > 1 &&
count >= 1 &&
Array.from(Array(count)).map((_, i) => (
<Cigarette
key={i}
orientation={orientation}
percentage={1}
fullCigaretteLength={fullCigaretteLength}
style={[baseCigaretteStyle, cigaretteStyle]}
/>
))}
{(cigarettes === 1 || decimal > 0) && (
<Cigarette
orientation={orientation}
percentage={decimal || 1}
fullCigaretteLength={fullCigaretteLength}
style={[baseCigaretteStyle, cigaretteStyle]}
/>
)}
</View>
);
}