diff --git a/app/_layout.tsx b/app/_layout.tsx
index cb931c3..05a33e4 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -25,7 +25,7 @@ const AppStack = (): JSX.Element => {
fontWeight: 'bold',
},
}}>
-
+
);
};
diff --git a/app/index.tsx b/app/index.tsx
index daf4412..ac049bb 100644
--- a/app/index.tsx
+++ b/app/index.tsx
@@ -10,10 +10,11 @@ import {BadgeForm} from '@/components/BadgeForm';
import {BadgeScanning} from '@/components/BadgeScanning';
import {type BadgeConfigFormData} from '@/models/BadgeForm.model';
import {type BadgeMagic} from '@/models/BadgeMagic.model';
+import {Animations} from '@/utils/animations';
import {sendPackets} from '@/utils/bluetooth';
import {getPackets} from '@/utils/payload';
-const DefaultFormData: BadgeConfigFormData = {
+const DefaultBagdeConfigFormData: BadgeConfigFormData = {
text: '',
effects: {
flash: false,
@@ -21,13 +22,14 @@ const DefaultFormData: BadgeConfigFormData = {
invertLed: false,
},
speed: 0,
+ animation: Animations.RIGHT,
};
const Home = (): JSX.Element => {
const [scanning, setScanning] = useState(false);
const [connectedBadge, setConnectedBadge] = useState();
- const methods = useForm({defaultValues: DefaultFormData});
+ const methods = useForm({defaultValues: DefaultBagdeConfigFormData});
const handleSendToBadge = async (data: BadgeConfigFormData): Promise => {
if (!connectedBadge) {
@@ -79,7 +81,7 @@ const styles = StyleSheet.create({
position: 'absolute',
bottom: 40,
gap: 8,
- left: 20,
+ left: 40,
alignItems: 'center',
justifyContent: 'space-between',
flexDirection: 'row',
diff --git a/src/assets/ic_anim_animation.gif b/src/assets/ic_anim_animation.gif
new file mode 100644
index 0000000..f82b328
Binary files /dev/null and b/src/assets/ic_anim_animation.gif differ
diff --git a/src/assets/ic_anim_down.gif b/src/assets/ic_anim_down.gif
new file mode 100644
index 0000000..8e0d504
Binary files /dev/null and b/src/assets/ic_anim_down.gif differ
diff --git a/src/assets/ic_anim_fixed.gif b/src/assets/ic_anim_fixed.gif
new file mode 100644
index 0000000..4589377
Binary files /dev/null and b/src/assets/ic_anim_fixed.gif differ
diff --git a/src/assets/ic_anim_laser.gif b/src/assets/ic_anim_laser.gif
new file mode 100644
index 0000000..9351360
Binary files /dev/null and b/src/assets/ic_anim_laser.gif differ
diff --git a/src/assets/ic_anim_left.gif b/src/assets/ic_anim_left.gif
new file mode 100644
index 0000000..e8113cd
Binary files /dev/null and b/src/assets/ic_anim_left.gif differ
diff --git a/src/assets/ic_anim_picture.gif b/src/assets/ic_anim_picture.gif
new file mode 100644
index 0000000..e68dd13
Binary files /dev/null and b/src/assets/ic_anim_picture.gif differ
diff --git a/src/assets/ic_anim_right.gif b/src/assets/ic_anim_right.gif
new file mode 100644
index 0000000..9dd3583
Binary files /dev/null and b/src/assets/ic_anim_right.gif differ
diff --git a/src/assets/ic_anim_up.gif b/src/assets/ic_anim_up.gif
new file mode 100644
index 0000000..076f234
Binary files /dev/null and b/src/assets/ic_anim_up.gif differ
diff --git a/src/components/Animations.tsx b/src/components/Animations.tsx
index e69de29..c83bc9a 100644
--- a/src/components/Animations.tsx
+++ b/src/components/Animations.tsx
@@ -0,0 +1,35 @@
+import {StyleSheet, View} from 'react-native';
+
+import {useFormContext} from 'react-hook-form';
+
+import {animations} from '@/utils/animations';
+
+import {ControlledCard} from './CardControlled';
+
+export const Animations = (): JSX.Element => {
+ const {control} = useFormContext();
+
+ return (
+
+ {animations.map((animation) => (
+
+ ))}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ cardsContainer: {
+ paddingTop: 16,
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ justifyContent: 'space-evenly',
+ },
+});
diff --git a/src/components/BadgeForm.tsx b/src/components/BadgeForm.tsx
index 374d17d..0dcbf20 100644
--- a/src/components/BadgeForm.tsx
+++ b/src/components/BadgeForm.tsx
@@ -1,5 +1,5 @@
import {useState} from 'react';
-import {StyleSheet, View, useWindowDimensions, Text} from 'react-native';
+import {StyleSheet, View, useWindowDimensions} from 'react-native';
import {useFormContext} from 'react-hook-form';
import {SceneMap, TabView} from 'react-native-tab-view';
@@ -8,12 +8,11 @@ import {AppInput} from '@/components/AppInput';
import {tabRoutes} from '@/utils/tabRoutes';
import {type BadgeConfigFormData} from '../models/BadgeForm.model';
+import {Animations} from './Animations';
import {BadgeConfigTabBar} from './BadgeConfigTabBar';
import {Effects} from './Effects';
import {SpeedSlider} from './Speed';
-const Animations = (): JSX.Element => Nothing implemented 00;
-
const renderScene = SceneMap({
effects: Effects,
animations: Animations,
diff --git a/src/components/CardControlled.tsx b/src/components/CardControlled.tsx
index 186bcdf..7bf083f 100644
--- a/src/components/CardControlled.tsx
+++ b/src/components/CardControlled.tsx
@@ -3,34 +3,45 @@ import {type ImageSourcePropType, Text, StyleSheet} from 'react-native';
import {type FieldValues, type UseControllerProps, useController} from 'react-hook-form';
import {useTheme, Card} from 'react-native-paper';
+import {type Animations} from '@/utils/animations';
+
type ControlledCardProps = {
imagePath: ImageSourcePropType;
title: string;
+ code?: Animations;
} & UseControllerProps;
export const ControlledCard = ({
control,
name,
+ code,
title,
imagePath,
}: ControlledCardProps): JSX.Element => {
const {colors} = useTheme();
+ const isAnimationSelected = name === 'animation';
const {
field: {value, onChange},
} = useController({name, control});
const handleOnPress = (): void => {
- onChange(!value);
+ onChange(isAnimationSelected ? code : !value);
};
+ const cardColor = isAnimationSelected
+ ? value === code
+ ? colors.primary
+ : colors.onPrimary
+ : value
+ ? colors.primary
+ : colors.onPrimary;
+
return (
-
+
- {title}
+ {title}
);
@@ -38,8 +49,7 @@ export const ControlledCard = ({
const styles = StyleSheet.create({
card: {
- flex: 1,
- margin: 10,
+ marginTop: 10,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
@@ -49,7 +59,10 @@ const styles = StyleSheet.create({
alignSelf: 'center',
borderRadius: 2,
margin: 5,
- width: 70,
- height: 70,
+ width: 90,
+ height: 90,
+ },
+ text: {
+ textAlign: 'center',
},
});
diff --git a/src/models/BadgeForm.model.ts b/src/models/BadgeForm.model.ts
index 4326808..ce16833 100644
--- a/src/models/BadgeForm.model.ts
+++ b/src/models/BadgeForm.model.ts
@@ -1,3 +1,5 @@
+import {type Animations} from '@/utils/animations';
+
export interface BadgeConfigFormData {
text: string;
effects: {
@@ -5,5 +7,6 @@ export interface BadgeConfigFormData {
marquee: boolean;
invertLed: boolean;
};
+ animation: Animations;
speed: number;
}
diff --git a/src/models/SelectionType.model.ts b/src/models/SelectionType.model.ts
new file mode 100644
index 0000000..fd3450b
--- /dev/null
+++ b/src/models/SelectionType.model.ts
@@ -0,0 +1,8 @@
+import {type ImageSourcePropType} from 'react-native';
+
+export interface SelectionType {
+ imagePath: ImageSourcePropType;
+ title: string;
+ name?: string;
+ code?: number;
+}
diff --git a/src/utils/animations.ts b/src/utils/animations.ts
new file mode 100644
index 0000000..4ff747c
--- /dev/null
+++ b/src/utils/animations.ts
@@ -0,0 +1,64 @@
+import {type SelectionType} from '@/models/SelectionType.model';
+
+import animationImageSrc from '../assets/ic_anim_animation.gif';
+import downImageSrc from '../assets/ic_anim_down.gif';
+import fixedImageSrc from '../assets/ic_anim_fixed.gif';
+import laserImageSrc from '../assets/ic_anim_laser.gif';
+import leftImageSrc from '../assets/ic_anim_left.gif';
+import pictureImageSrc from '../assets/ic_anim_picture.gif';
+import rightImageSrc from '../assets/ic_anim_right.gif';
+import upImageSrc from '../assets/ic_anim_up.gif';
+
+export enum Animations {
+ LEFT = 1,
+ UP = 2,
+ DOWN = 3,
+ FIXED = 4,
+ PICTURE = 5,
+ LASER = 6,
+ ANIMATION = 7,
+ RIGHT = 0,
+}
+
+export const animations = [
+ {
+ imagePath: rightImageSrc,
+ title: 'Left',
+ code: Animations.LEFT,
+ },
+ {
+ imagePath: upImageSrc,
+ title: 'Up',
+ code: Animations.UP,
+ },
+ {
+ imagePath: downImageSrc,
+ title: 'Down',
+ code: Animations.DOWN,
+ },
+ {
+ imagePath: fixedImageSrc,
+ title: 'Fixed',
+ code: Animations.FIXED,
+ },
+ {
+ imagePath: pictureImageSrc,
+ title: 'Picture',
+ code: Animations.PICTURE,
+ },
+ {
+ imagePath: animationImageSrc,
+ title: 'Animation',
+ code: Animations.ANIMATION,
+ },
+ {
+ imagePath: laserImageSrc,
+ title: 'Laser',
+ code: Animations.LASER,
+ },
+ {
+ imagePath: leftImageSrc,
+ title: 'Right',
+ code: Animations.RIGHT,
+ },
+] as const satisfies SelectionType[];
diff --git a/src/utils/payload.ts b/src/utils/payload.ts
index 708737e..f91b12e 100644
--- a/src/utils/payload.ts
+++ b/src/utils/payload.ts
@@ -52,13 +52,15 @@ export function getPackets(data: BadgeConfigFormData): string[] {
}
function buildDataHexString(data: BadgeConfigFormData): string {
- const {text, effects, speed} = data;
+ const {text, effects, speed, animation} = data;
+
const payload = getLetterBitmaps(text).join('');
const size = getSize(text);
const timestamp = getTimestamp();
const marquee = getMarqueeValue(effects.marquee);
const flash = getFlashValue(effects.flash);
- const modes = `${speed}0` + '00' + '00' + '00' + '00' + '00' + '00' + '00';
+ const modes = `${speed}${animation}` + '00' + '00' + '00' + '00' + '00' + '00' + '00';
+
return (
HEADER + flash + marquee + modes + size + PADDING1 + timestamp + PADDING2 + SEPARATOR + payload
);