Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(design-v2): bottom controls drawer component with reactions flow #1539

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c5a7182
feat: add call duration badge and hangup call button
kristian-mkd Oct 15, 2024
ac283e7
feat: add icons and foundation for the top left call controls
kristian-mkd Oct 15, 2024
49b6c58
feat: call top component updates, still work in progress
kristian-mkd Oct 15, 2024
3d8bdcc
feat: configurable duration badge
kristian-mkd Oct 16, 2024
a0f2ba3
Merge branch 'PBE-5855-feat/react-native-video-design-v2' into PBE-58…
kristian-mkd Oct 16, 2024
5e1b3ba
Merge branch 'PBE-5855-feat/react-native-video-design-v2' into PBE-58…
kristian-mkd Oct 16, 2024
1282dd8
feat: network and speech status indicators
kristian-mkd Oct 16, 2024
9b16cc7
chore: move top call components to dogfood app
kristian-mkd Oct 17, 2024
81d0241
chore: code cleanup
kristian-mkd Oct 17, 2024
7dfa473
chore: additional clean up
kristian-mkd Oct 17, 2024
e77d38c
lint: fix reported issues
kristian-mkd Oct 17, 2024
98e742e
feat: add call duration observable in the call state
kristian-mkd Oct 18, 2024
c7399e6
feat(design-v2): adds layout switcher components
kristian-mkd Oct 19, 2024
1b773c0
fix: self code review improvements
kristian-mkd Oct 19, 2024
8220903
feat: add layout context and fix layout icons
kristian-mkd Oct 21, 2024
6cf8e8f
Merge branch 'PBE-5855-feat/react-native-video-design-v2' into PBE-58…
kristian-mkd Oct 22, 2024
6e37dfb
Merge branch 'PBE-5858-call-scene-container' into add-layout-switcher
kristian-mkd Oct 22, 2024
32f94a3
fix: lint reported issues
kristian-mkd Oct 22, 2024
0129827
fix: lint reported issues
kristian-mkd Oct 22, 2024
62b6137
remove duration changes
kristian-mkd Oct 22, 2024
e352c1e
Merge branch 'PBE-5858-call-scene-container' into add-layout-switcher
kristian-mkd Oct 22, 2024
5de1920
fix: lint issue
kristian-mkd Oct 22, 2024
38141b9
fix: lint issues
kristian-mkd Oct 22, 2024
0903b30
fix: lint issues
kristian-mkd Oct 22, 2024
53b908a
fix: lint reported issues
kristian-mkd Oct 22, 2024
23c0554
Merge branch 'PBE-5858-call-scene-container' into add-layout-switcher
kristian-mkd Oct 22, 2024
7539bc6
fix: styling fixes for grid and spotlight layouts
kristian-mkd Oct 24, 2024
fba22f1
Merge branch 'PBE-5855-feat/react-native-video-design-v2' into add-la…
kristian-mkd Oct 24, 2024
2856a31
feat: add fullscreen layout
kristian-mkd Oct 25, 2024
af0c28c
fix: layout improvements
kristian-mkd Oct 25, 2024
cdd2fdd
fix: top controls not sent to activeCall
kristian-mkd Oct 25, 2024
5acff28
fix: lint issues
kristian-mkd Oct 25, 2024
787e958
feat: add bottom controls drawer component with reactions flow
kristian-mkd Oct 28, 2024
7eaa092
chore: revert mocks
kristian-mkd Oct 29, 2024
55a63e4
Merge branch 'PBE-5855-feat/react-native-video-design-v2' into add-la…
kristian-mkd Oct 29, 2024
deafa18
Merge branch 'add-layout-switcher' into bottom-drawer-with-reactions-…
kristian-mkd Oct 29, 2024
7cbf2a5
feat: final changes for the drawer component
kristian-mkd Oct 29, 2024
15f2f68
fix: lint issues
kristian-mkd Oct 29, 2024
3e3dd8a
test: fix failing test case for tada reaction emoji
kristian-mkd Oct 29, 2024
796e5ff
fix: android specific styling issues
kristian-mkd Oct 30, 2024
5e27b61
Merge branch 'PBE-5855-feat/react-native-video-design-v2' into add-la…
kristian-mkd Oct 30, 2024
37fc7cf
Merge branch 'add-layout-switcher' into bottom-drawer-with-reactions-…
kristian-mkd Oct 30, 2024
36dd3e3
chore: update docs
kristian-mkd Oct 31, 2024
f5458ae
fix: revert some sdk changes
kristian-mkd Oct 31, 2024
23598b0
fix: use sdk emojis in dogfood
kristian-mkd Oct 31, 2024
6f7c691
Merge branch 'PBE-5855-feat/react-native-video-design-v2' into bottom…
kristian-mkd Nov 1, 2024
28ae879
fix: revert changes
kristian-mkd Nov 1, 2024
eaebe92
fix: revert callContent changes
kristian-mkd Nov 1, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ id: call-top-view
title: CallTopView
---

import ParticipantsInfoBadge from '../../common-content/ui-components/call/call-content/participants-info-badge.mdx';
import OnBackPressed from '../../common-content/ui-components/call/call-content/on-back-pressed.mdx';
import OnParticipantInfoPress from '../../common-content/ui-components/call/call-content/on-participant-info-press.mdx';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
floatingChildViewContainerStyle,
} from './common';
import { getLogger } from '@stream-io/video-client';
import { useTheme } from '../../../..';

const AnimatedFloatingView = ({
initialAlignment,
Expand All @@ -29,6 +30,7 @@ const AnimatedFloatingView = ({
const translateRef = useRef(new Animated.ValueXY());
const opacity = useRef(new Animated.Value(0));

const { theme } = useTheme();
const [rectangle, setRectangle] = React.useState<LayoutRectangle>();

// we need to force update the component when the rectangle is available
Expand Down Expand Up @@ -58,6 +60,7 @@ const AnimatedFloatingView = ({
width: rectangle.width,
height: rectangle.height,
},
topOffset: theme.floatingParticipantsView.topPosition,
});
const { x, y } = snapAlignments[initialAlignment];
snapAlignmentsRef.current = snapAlignments;
Expand All @@ -66,7 +69,7 @@ const AnimatedFloatingView = ({
opacity.current.setValue(1);
forceUpdate();
// any time the dependency changes, we need to snap to the new alignment
}, [initialAlignment, rectangle, containerWidth, containerHeight]);
}, [initialAlignment, rectangle, containerWidth, containerHeight, theme]);

const panResponder = useRef(
PanResponder.create({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
floatingChildViewContainerStyle,
FloatingViewProps,
} from './common';
import { useTheme } from '../../../..';
type GestureHandlerExportsType = typeof import('react-native-gesture-handler');
type ReanimatedNamespaceType = typeof import('react-native-reanimated').default;
type ReanimatedExportsType = typeof import('react-native-reanimated');
Expand Down Expand Up @@ -54,6 +55,7 @@ try {
// we don't want to show the floating view until we have the layout rectangle
const opacity = useSharedValue(0);
const [rectangle, setRectangle] = React.useState<LayoutRectangle>();
const { theme } = useTheme();

const snapAlignments = useMemo(() => {
if (!rectangle) {
Expand All @@ -64,7 +66,6 @@ try {
[FloatingViewAlignment.bottomRight]: { x: 0, y: 0 },
};
}

return getSnapAlignments({
rootContainerDimensions: {
width: containerWidth,
Expand All @@ -74,8 +75,9 @@ try {
width: rectangle.width,
height: rectangle.height,
},
topOffset: theme.floatingParticipantsView.topPosition,
});
}, [rectangle, containerWidth, containerHeight]);
}, [rectangle, containerWidth, containerHeight, theme]);

const dragGesture = Gesture.Pan()
.onStart((_e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@ export type SnapAlignments = Record<
export function getSnapAlignments({
rootContainerDimensions,
floatingViewDimensions,
topOffset,
}: {
rootContainerDimensions: { width: number; height: number };
floatingViewDimensions: { width: number; height: number };
topOffset: number;
}): SnapAlignments {
const right = rootContainerDimensions.width - floatingViewDimensions.width;
const bottom = rootContainerDimensions.height - floatingViewDimensions.height;
const snapOffsets = {
[FloatingViewAlignment.topLeft]: {
x: 0,
y: 0,
y: topOffset,
},
[FloatingViewAlignment.topRight]: {
x: right,
y: 0,
y: topOffset,
},
[FloatingViewAlignment.bottomLeft]: {
x: 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useMemo } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { useCall } from '@stream-io/video-react-bindings';
import { Z_INDEX, defaultEmojiReactions } from '../../../constants';
Expand Down Expand Up @@ -32,12 +32,9 @@ export const ParticipantReaction = ({
}: ParticipantReactionProps) => {
const { reaction, sessionId } = participant;
const call = useCall();
const styles = useStyles();
const {
theme: {
typefaces,
variants: { iconSizes },
participantReaction,
},
theme: { typefaces, participantReaction },
} = useTheme();

useEffect(() => {
Expand All @@ -60,26 +57,34 @@ export const ParticipantReaction = ({
);

return (
<View
style={[
styles.container,
{
height: iconSizes.md,
width: iconSizes.md,
},
participantReaction.container,
]}
>
<Text style={[participantReaction.reaction, typefaces.heading6]}>
{currentReaction?.icon}
</Text>
</View>
currentReaction?.icon != null && (
<View style={[styles.container, participantReaction.container]}>
<Text style={[participantReaction.reaction, typefaces.heading6]}>
{currentReaction?.icon}
</Text>
</View>
)
);
};

const styles = StyleSheet.create({
container: {
alignSelf: 'flex-start',
zIndex: Z_INDEX.IN_FRONT,
},
});
const useStyles = () => {
const { theme } = useTheme();
return useMemo(
() =>
StyleSheet.create({
container: {
alignSelf: 'flex-end',
marginRight: theme.variants.spacingSizes.md,
marginTop: theme.variants.spacingSizes.md,
height: theme.variants.roundButtonSizes.md,
width: theme.variants.roundButtonSizes.md,
borderRadius: theme.variants.borderRadiusSizes.sm,
backgroundColor: theme.colors.sheetOverlay,
alignItems: 'center',
justifyContent: 'center',
zIndex: Z_INDEX.IN_FRONT,
},
}),
[theme]
);
};
30 changes: 27 additions & 3 deletions packages/react-native-sdk/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,48 @@ export const FLOATING_VIDEO_VIEW_STYLE = {
export const LOBBY_VIDEO_VIEW_HEIGHT = 240;

export const defaultEmojiReactions: StreamReactionType[] = [
{
type: 'reaction',
emoji_code: ':rolling_on_the_floor_laughing:',
custom: {},
icon: '🤣',
},
{
type: 'reaction',
emoji_code: ':like:',
custom: {},
icon: '👍',
},
{
type: 'raised-hand',
emoji_code: ':raise-hand:',
type: 'reaction',
emoji_code: ':rocket:',
custom: {},
icon: '✋',
icon: '🚀',
},
{
type: 'reaction',
emoji_code: ':dislike:',
custom: {},
icon: '👎',
},
{
type: 'reaction',
emoji_code: ':fireworks:',
custom: {},
icon: '🎉',
},
{
type: 'reaction',
emoji_code: ':raised-hands:',
custom: {},
icon: '🙌',
},
{
type: 'raised-hand',
emoji_code: ':raised-hand:',
custom: {},
icon: '✋',
},
];

export const Z_INDEX = {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-sdk/src/icons/CameraSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Props = {
};

export const CameraSwitch = ({ color, size }: Props) => (
<Svg viewBox={`0 0 24 24`} width={size} height={size}>
<Svg viewBox={'0 0 24 24'} width={size} height={size}>
<Path
d="M20 5.5H16.83L15.59 4.15C15.22 3.74 14.68 3.5 14.12 3.5H9.88C9.32 3.5 8.78 3.74 8.4 4.15L7.17 5.5H4C2.9 5.5 2 6.4 2 7.5V19.5C2 20.6 2.9 21.5 4 21.5H20C21.1 21.5 22 20.6 22 19.5V7.5C22 6.4 21.1 5.5 20 5.5ZM13.67 18.2C13.15 18.39 12.59 18.5 12 18.5C9.24 18.5 7 16.26 7 13.5H5L7.5 11L10 13.5H8C8 15.71 9.79 17.5 12 17.5C12.46 17.5 12.91 17.42 13.32 17.27C13.51 17.2 13.71 17.24 13.85 17.38C14.11 17.64 14.01 18.07 13.67 18.2ZM16.5 16L14 13.5H16C16 11.29 14.21 9.5 12 9.5C11.54 9.5 11.09 9.58 10.68 9.73C10.49 9.8 10.29 9.76 10.15 9.62C9.89 9.36 9.99 8.93 10.33 8.8C10.85 8.61 11.41 8.5 12 8.5C14.76 8.5 17 10.74 17 13.5H19L16.5 16Z"
fill={color}
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-sdk/src/icons/Effects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Props = {
};

export const Effects = ({ color, size }: Props) => (
<Svg viewBox={`0 0 24 24`} width={size} height={size}>
<Svg viewBox={'0 0 24 24'} width={size} height={size}>
<Path
d="M19.1065 8.00002L19.8965 6.25002L21.6465 5.46002C22.0365 5.28002 22.0365 4.73002 21.6465 4.55002L19.8965 3.76002L19.1065 2.00002C18.9265 1.61002 18.3765 1.61002 18.1965 2.00002L17.4065 3.75002L15.6465 4.54002C15.2565 4.72002 15.2565 5.27002 15.6465 5.45002L17.3965 6.24002L18.1865 8.00002C18.3665 8.39002 18.9265 8.39002 19.1065 8.00002ZM11.1465 9.50002L9.55652 6.00002C9.20652 5.22002 8.08652 5.22002 7.73652 6.00002L6.14652 9.50002L2.64652 11.09C1.86652 11.45 1.86652 12.56 2.64652 12.91L6.14652 14.5L7.73652 18C8.09652 18.78 9.20652 18.78 9.55652 18L11.1465 14.5L14.6465 12.91C15.4265 12.55 15.4265 11.44 14.6465 11.09L11.1465 9.50002ZM18.1865 16L17.3965 17.75L15.6465 18.54C15.2565 18.72 15.2565 19.27 15.6465 19.45L17.3965 20.24L18.1865 22C18.3665 22.39 18.9165 22.39 19.0965 22L19.8865 20.25L21.6465 19.46C22.0365 19.28 22.0365 18.73 21.6465 18.55L19.8965 17.76L19.1065 16C18.9265 15.61 18.3665 15.61 18.1865 16Z"
fill={color}
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native-sdk/src/theme/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export type Theme = {
container: ViewStyle;
participantViewContainer: ViewStyle;
videoFallback: ViewStyle;
topPosition: number;
};
chatButton: {
container: ViewStyle;
Expand Down Expand Up @@ -479,6 +480,7 @@ export const defaultTheme: Theme = {
container: {},
participantViewContainer: {},
videoFallback: {},
topPosition: 0,
},
participantLabel: {
container: {},
Expand Down
19 changes: 19 additions & 0 deletions sample-apps/react-native/dogfood/src/assets/ClosedCaptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { Svg, Path } from 'react-native-svg';
import { ColorValue } from 'react-native/types';

type Props = {
color: ColorValue;
size: number;
};

const ClosedCaptions = ({ color, size }: Props) => (
<Svg viewBox={'0 0 24 24'} width={size} height={size}>
<Path
d="M19 4H5C3.89 4 3 4.9 3 6V18C3 19.1 3.89 20 5 20H19C20.1 20 21 19.1 21 18V6C21 4.9 20.1 4 19 4ZM11 10.5C11 10.78 10.78 11 10.5 11H10C9.72 11 9.5 10.78 9.5 10.5H7.5V13.5H9.5C9.5 13.22 9.72 13 10 13H10.5C10.78 13 11 13.22 11 13.5V14C11 14.55 10.55 15 10 15H7C6.45 15 6 14.55 6 14V10C6 9.45 6.45 9 7 9H10C10.55 9 11 9.45 11 10V10.5ZM18 10.5C18 10.78 17.78 11 17.5 11H17C16.72 11 16.5 10.78 16.5 10.5H14.5V13.5H16.5C16.5 13.22 16.72 13 17 13H17.5C17.78 13 18 13.22 18 13.5V14C18 14.55 17.55 15 17 15H14C13.45 15 13 14.55 13 14V10C13 9.45 13.45 9 14 9H17C17.55 9 18 9.45 18 10V10.5Z"
fill={color}
/>
</Svg>
);

export default ClosedCaptions;
19 changes: 19 additions & 0 deletions sample-apps/react-native/dogfood/src/assets/Feedback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { Svg, Path } from 'react-native-svg';
import { ColorValue } from 'react-native/types';

type Props = {
color: ColorValue;
size: number;
};

const Feedback = ({ color, size }: Props) => (
<Svg viewBox={'0 0 24 24'} width={size} height={size}>
<Path
d="M19.9949 2H4.00488C2.90488 2 2.00488 2.9 2.00488 4V22L5.99488 18H19.9949C21.0949 18 21.9949 17.1 21.9949 16V4C21.9949 2.9 21.0949 2 19.9949 2ZM12.9949 14H10.9949V12H12.9949V14ZM12.9949 9C12.9949 9.55 12.5449 10 11.9949 10C11.4449 10 10.9949 9.55 10.9949 9V7C10.9949 6.45 11.4449 6 11.9949 6C12.5449 6 12.9949 6.45 12.9949 7V9Z"
fill={color}
/>
</Svg>
);

export default Feedback;
19 changes: 19 additions & 0 deletions sample-apps/react-native/dogfood/src/assets/NoiseCancelation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { Svg, Path } from 'react-native-svg';
import { ColorValue } from 'react-native/types';

type Props = {
color: ColorValue;
size: number;
};

const NoiseCancelation = ({ color, size }: Props) => (
<Svg viewBox={'0 0 24 24'} width={size} height={size}>
<Path
d="M17.0269 20.165C16.7369 20.165 16.4669 20.105 16.2669 20.015C15.5569 19.645 15.0569 19.135 14.5569 17.635C14.0469 16.075 13.0869 15.345 12.1669 14.635C11.3769 14.025 10.5569 13.395 9.84686 12.105C9.31686 11.145 9.02686 10.095 9.02686 9.16498C9.02686 6.36498 11.2269 4.16498 14.0269 4.16498C16.5869 4.16498 18.6569 6.01498 18.9769 8.47498C19.0369 8.87498 19.3869 9.16498 19.7969 9.16498H20.1369C20.6369 9.16498 21.0269 8.72498 20.9669 8.22498C20.5169 4.75498 17.6369 2.16498 14.0269 2.16498C10.0969 2.16498 7.02686 5.23498 7.02686 9.16498C7.02686 10.425 7.40686 11.815 8.09686 13.065C9.00686 14.715 10.0769 15.545 10.9469 16.215C11.7569 16.835 12.3369 17.285 12.6569 18.265C13.2569 20.085 14.0269 21.105 15.3869 21.815C15.8969 22.045 16.4569 22.165 17.0269 22.165C18.8669 22.165 20.4169 20.925 20.8869 19.235C21.0269 18.695 20.6369 18.165 20.0769 18.165H19.7269C19.3469 18.165 19.0469 18.435 18.9169 18.795C18.6569 19.585 17.9069 20.165 17.0269 20.165ZM6.99686 2.13498C6.56686 1.70498 5.87686 1.74498 5.49686 2.20498C3.95686 4.10498 3.02686 6.52498 3.02686 9.16498C3.02686 11.805 3.95686 14.225 5.49686 16.115C5.87686 16.575 6.56686 16.615 6.98686 16.195C7.34686 15.835 7.37686 15.265 7.05686 14.875C5.79686 13.325 5.02686 11.335 5.02686 9.16498C5.02686 6.99498 5.79686 5.00498 7.06686 3.46498C7.39686 3.06498 7.35686 2.49498 6.99686 2.13498ZM11.5269 9.16498C11.5269 10.545 12.6469 11.665 14.0269 11.665C15.4069 11.665 16.5269 10.545 16.5269 9.16498C16.5269 7.78498 15.4069 6.66498 14.0269 6.66498C12.6469 6.66498 11.5269 7.78498 11.5269 9.16498Z"
fill={color}
/>
</Svg>
);

export default NoiseCancelation;
19 changes: 19 additions & 0 deletions sample-apps/react-native/dogfood/src/assets/RaiseHand.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { Svg, Path } from 'react-native-svg';
import { ColorValue } from 'react-native/types';

type Props = {
color: ColorValue;
size: number;
};

const RaiseHand = ({ color, size }: Props) => (
<Svg viewBox={'0 0 20 20'} width={size} height={size}>
<Path
d="M18.2095 13.3333C18.2095 17.0167 15.2262 20 11.5428 20C8.82616 20 6.38449 18.3417 5.37616 15.8167L2.85116 9.475C2.59283 8.81667 3.20949 8.15833 3.88449 8.375L4.54283 8.59167C5.00949 8.74167 5.39283 9.1 5.57616 9.55833L6.64283 12.2333C6.70949 12.4 6.85949 12.5 7.02616 12.5H7.37616V2.70833C7.37616 2.13333 7.84283 1.66667 8.41783 1.66667C8.99283 1.66667 9.45949 2.13333 9.45949 2.70833V9.58333C9.45949 9.81667 9.64283 10 9.87616 10C10.1095 10 10.2928 9.81667 10.2928 9.58333V1.04167C10.2928 0.466667 10.7595 0 11.3345 0C11.9095 0 12.3762 0.466667 12.3762 1.04167V9.58333C12.3762 9.81667 12.5595 10 12.7928 10C13.0262 10 13.2095 9.81667 13.2095 9.58333V2.29167C13.2095 1.71667 13.6762 1.25 14.2512 1.25C14.8262 1.25 15.2928 1.71667 15.2928 2.29167V9.58333C15.2928 9.81667 15.4762 10 15.7095 10C15.9428 10 16.1262 9.81667 16.1262 9.58333V4.79167C16.1262 4.21667 16.5928 3.75 17.1678 3.75C17.7428 3.75 18.2095 4.21667 18.2095 4.79167V13.3333Z"
fill={color}
/>
</Svg>
);

export default RaiseHand;
19 changes: 19 additions & 0 deletions sample-apps/react-native/dogfood/src/assets/Stats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { Svg, Path } from 'react-native-svg';
import { ColorValue } from 'react-native/types';

type Props = {
color: ColorValue;
size: number;
};

const Stats = ({ color, size }: Props) => (
<Svg viewBox={'0 0 24 24'} width={size} height={size}>
<Path
d="M19.8836 17.9604C20.3636 17.1904 20.6336 16.2904 20.5736 15.3004C20.4436 13.1504 18.7336 11.3304 16.6036 11.1004C13.8836 10.8004 11.5836 12.9104 11.5836 15.5704C11.5836 18.0604 13.5936 20.0704 16.0736 20.0704C16.9536 20.0704 17.7736 19.8104 18.4636 19.3704L20.8736 21.7804C21.2636 22.1704 21.9036 22.1704 22.2936 21.7804C22.6836 21.3904 22.6836 20.7504 22.2936 20.3604L19.8836 17.9604ZM16.0836 18.0704C14.7036 18.0704 13.5836 16.9504 13.5836 15.5704C13.5836 14.1904 14.7036 13.0704 16.0836 13.0704C17.4636 13.0704 18.5836 14.1904 18.5836 15.5704C18.5836 16.9504 17.4636 18.0704 16.0836 18.0704ZM15.7236 9.57041C14.9836 9.59041 14.2736 9.75041 13.6236 10.0204L13.0736 9.19041L9.99365 14.2004C9.63365 14.7804 8.82365 14.8404 8.38365 14.3304L6.26365 11.8604L3.20365 16.7604C2.89365 17.2504 2.23365 17.3804 1.76365 17.0404C1.34365 16.7304 1.22365 16.1504 1.50365 15.7004L5.28365 9.65041C5.64365 9.08041 6.45365 9.02041 6.89365 9.53041L9.00365 11.9904L12.1836 6.82041C12.5636 6.20041 13.4636 6.18041 13.8636 6.79041L15.7236 9.57041ZM18.3136 10.0704C17.6736 9.79041 16.9836 9.62041 16.2636 9.58041L20.8036 2.39041C21.1136 1.90041 21.7736 1.78041 22.2336 2.12041C22.6636 2.43041 22.7736 3.02041 22.4936 3.46041L18.3136 10.0704Z"
fill={color}
/>
</Svg>
);

export default Stats;
Loading
Loading