Skip to content

Commit

Permalink
Merge pull request #8 from RuiOkazaki/feature/TSK-34
Browse files Browse the repository at this point in the history
[TSK-34]ダーツボードと接続できるようにする
  • Loading branch information
RuiOkazaki authored May 12, 2024
2 parents f045a67 + 296df4d commit dfa482a
Show file tree
Hide file tree
Showing 11 changed files with 488 additions and 28 deletions.
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"graphql": "^16.8.1",
"jotai": "^2.8.0",
"lucide-react": "^0.376.0",
"next": "14.2.3",
"react": "^18",
Expand All @@ -44,6 +45,7 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/web-bluetooth": "^0.0.20",
"@vitest/coverage-v8": "^1.5.2",
"lefthook": "^1.6.10",
"npm-run-all2": "^6.1.2",
Expand Down
11 changes: 7 additions & 4 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UserProvider } from '@auth0/nextjs-auth0/client';
import { Auth0Provider } from '@/shared/libs/auth0/provider';
import { JotaiProvider } from '@/shared/libs/jotai/provider';
import type { Metadata } from 'next';
import './globals.css';

Expand All @@ -14,9 +15,11 @@ export default function RootLayout({
}>) {
return (
<html lang='ja'>
<UserProvider>
<body>{children}</body>
</UserProvider>
<Auth0Provider>
<JotaiProvider>
<body>{children}</body>
</JotaiProvider>
</Auth0Provider>
</html>
);
}
9 changes: 9 additions & 0 deletions src/entitie/dartsboard/constants/bluetooth-uuid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type BluetoothUUID = {
readonly SERVICE_UUID: string;
readonly CHARACTERISTIC_UUID: string;
};

export const DARTSLIVE_HOME_BLUETOOTH_UUID: BluetoothUUID = {
SERVICE_UUID: '6e400001-b5a3-f393-e0a9-e50e24dcca9e',
CHARACTERISTIC_UUID: '6e40fff6-b5a3-f393-e0a9-e50e24dcca9e',
} as const;
241 changes: 241 additions & 0 deletions src/entitie/dartsboard/constants/position-format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import type { DartsPosition } from '../stores/atoms';

type DartsPositionFormat = {
[key: number]: DartsPosition;
};

export const DARTSLIVE_HOME_POSITION_FORMAT: DartsPositionFormat = {
1: { id: 1, position_code: 'S1', multiplier: 1, score: 1, sector: 'inner' },
2: { id: 2, position_code: 'S2', multiplier: 1, score: 2, sector: 'inner' },
3: { id: 3, position_code: 'S3', multiplier: 1, score: 3, sector: 'inner' },
4: { id: 4, position_code: 'S4', multiplier: 1, score: 4, sector: 'inner' },
5: { id: 5, position_code: 'S5', multiplier: 1, score: 5, sector: 'inner' },
6: { id: 6, position_code: 'S6', multiplier: 1, score: 6, sector: 'inner' },
7: { id: 7, position_code: 'S7', multiplier: 1, score: 7, sector: 'inner' },
8: { id: 8, position_code: 'S8', multiplier: 1, score: 8, sector: 'inner' },
9: { id: 9, position_code: 'S9', multiplier: 1, score: 9, sector: 'inner' },
10: {
id: 10,
position_code: 'S10',
multiplier: 1,
score: 10,
sector: 'inner',
},
11: {
id: 11,
position_code: 'S11',
multiplier: 1,
score: 11,
sector: 'inner',
},
12: {
id: 12,
position_code: 'S12',
multiplier: 1,
score: 12,
sector: 'inner',
},
13: {
id: 13,
position_code: 'S13',
multiplier: 1,
score: 13,
sector: 'inner',
},
14: {
id: 14,
position_code: 'S14',
multiplier: 1,
score: 14,
sector: 'inner',
},
15: {
id: 15,
position_code: 'S15',
multiplier: 1,
score: 15,
sector: 'inner',
},
16: {
id: 16,
position_code: 'S16',
multiplier: 1,
score: 16,
sector: 'inner',
},
17: {
id: 17,
position_code: 'S17',
multiplier: 1,
score: 17,
sector: 'inner',
},
18: {
id: 18,
position_code: 'S18',
multiplier: 1,
score: 18,
sector: 'inner',
},
19: {
id: 19,
position_code: 'S19',
multiplier: 1,
score: 19,
sector: 'inner',
},
20: {
id: 20,
position_code: 'S20',
multiplier: 1,
score: 20,
sector: 'inner',
},
21: { id: 21, position_code: 'S1', multiplier: 1, score: 1, sector: 'outer' },
22: { id: 22, position_code: 'S2', multiplier: 1, score: 2, sector: 'outer' },
23: { id: 23, position_code: 'S3', multiplier: 1, score: 3, sector: 'outer' },
24: { id: 24, position_code: 'S4', multiplier: 1, score: 4, sector: 'outer' },
25: { id: 25, position_code: 'S5', multiplier: 1, score: 5, sector: 'outer' },
26: { id: 26, position_code: 'S6', multiplier: 1, score: 6, sector: 'outer' },
27: { id: 27, position_code: 'S7', multiplier: 1, score: 7, sector: 'outer' },
28: { id: 28, position_code: 'S8', multiplier: 1, score: 8, sector: 'outer' },
29: { id: 29, position_code: 'S9', multiplier: 1, score: 9, sector: 'outer' },
30: {
id: 30,
position_code: 'S10',
multiplier: 1,
score: 10,
sector: 'outer',
},
31: {
id: 31,
position_code: 'S11',
multiplier: 1,
score: 11,
sector: 'outer',
},
32: {
id: 32,
position_code: 'S12',
multiplier: 1,
score: 12,
sector: 'outer',
},
33: {
id: 33,
position_code: 'S13',
multiplier: 1,
score: 13,
sector: 'outer',
},
34: {
id: 34,
position_code: 'S14',
multiplier: 1,
score: 14,
sector: 'outer',
},
35: {
id: 35,
position_code: 'S15',
multiplier: 1,
score: 15,
sector: 'outer',
},
36: {
id: 36,
position_code: 'S16',
multiplier: 1,
score: 16,
sector: 'outer',
},
37: {
id: 37,
position_code: 'S17',
multiplier: 1,
score: 17,
sector: 'outer',
},
38: {
id: 38,
position_code: 'S18',
multiplier: 1,
score: 18,
sector: 'outer',
},
39: {
id: 39,
position_code: 'S19',
multiplier: 1,
score: 19,
sector: 'outer',
},
40: {
id: 40,
position_code: 'S20',
multiplier: 1,
score: 20,
sector: 'outer',
},
41: { id: 41, position_code: 'D1', multiplier: 2, score: 1, sector: null },
42: { id: 42, position_code: 'D2', multiplier: 2, score: 2, sector: null },
43: { id: 43, position_code: 'D3', multiplier: 2, score: 3, sector: null },
44: { id: 44, position_code: 'D4', multiplier: 2, score: 4, sector: null },
45: { id: 45, position_code: 'D5', multiplier: 2, score: 5, sector: null },
46: { id: 46, position_code: 'D6', multiplier: 2, score: 6, sector: null },
47: { id: 47, position_code: 'D7', multiplier: 2, score: 7, sector: null },
48: { id: 48, position_code: 'D8', multiplier: 2, score: 8, sector: null },
49: { id: 49, position_code: 'D9', multiplier: 2, score: 9, sector: null },
50: { id: 50, position_code: 'D10', multiplier: 2, score: 10, sector: null },
51: { id: 51, position_code: 'D11', multiplier: 2, score: 11, sector: null },
52: { id: 52, position_code: 'D12', multiplier: 2, score: 12, sector: null },
53: { id: 53, position_code: 'D13', multiplier: 2, score: 13, sector: null },
54: { id: 54, position_code: 'D14', multiplier: 2, score: 14, sector: null },
55: { id: 55, position_code: 'D15', multiplier: 2, score: 15, sector: null },
56: { id: 56, position_code: 'D16', multiplier: 2, score: 16, sector: null },
57: { id: 57, position_code: 'D17', multiplier: 2, score: 17, sector: null },
58: { id: 58, position_code: 'D18', multiplier: 2, score: 18, sector: null },
59: { id: 59, position_code: 'D19', multiplier: 2, score: 19, sector: null },
60: { id: 60, position_code: 'D20', multiplier: 2, score: 20, sector: null },
61: { id: 61, position_code: 'T1', multiplier: 3, score: 1, sector: null },
62: { id: 62, position_code: 'T2', multiplier: 3, score: 2, sector: null },
63: { id: 63, position_code: 'T3', multiplier: 3, score: 3, sector: null },
64: { id: 64, position_code: 'T4', multiplier: 3, score: 4, sector: null },
65: { id: 65, position_code: 'T5', multiplier: 3, score: 5, sector: null },
66: { id: 66, position_code: 'T6', multiplier: 3, score: 6, sector: null },
67: { id: 67, position_code: 'T7', multiplier: 3, score: 7, sector: null },
68: { id: 68, position_code: 'T8', multiplier: 3, score: 8, sector: null },
69: { id: 69, position_code: 'T9', multiplier: 3, score: 9, sector: null },
70: { id: 70, position_code: 'T10', multiplier: 3, score: 10, sector: null },
71: { id: 71, position_code: 'T11', multiplier: 3, score: 11, sector: null },
72: { id: 72, position_code: 'T12', multiplier: 3, score: 12, sector: null },
73: { id: 73, position_code: 'T13', multiplier: 3, score: 13, sector: null },
74: { id: 74, position_code: 'T14', multiplier: 3, score: 14, sector: null },
75: { id: 75, position_code: 'T15', multiplier: 3, score: 15, sector: null },
76: { id: 76, position_code: 'T16', multiplier: 3, score: 16, sector: null },
77: { id: 77, position_code: 'T17', multiplier: 3, score: 17, sector: null },
78: { id: 78, position_code: 'T18', multiplier: 3, score: 18, sector: null },
79: { id: 79, position_code: 'T19', multiplier: 3, score: 19, sector: null },
80: { id: 80, position_code: 'T20', multiplier: 3, score: 20, sector: null },
81: {
id: 81,
position_code: 'S-BULL',
multiplier: 1,
score: 25,
sector: null,
},
82: {
id: 81,
position_code: 'D-BULL',
multiplier: 2,
score: 25,
sector: null,
},
84: {
id: 84,
position_code: 'CHANGE',
multiplier: 0,
score: 0,
sector: null,
},
};
81 changes: 81 additions & 0 deletions src/entitie/dartsboard/hooks/use-connect-dartslive-home.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { DartsHitHistory } from '@/entitie/dartsboard/stores/atoms';
import { useAtom } from 'jotai/react';
import { DARTSLIVE_HOME_BLUETOOTH_UUID } from '../constants/bluetooth-uuid';
import { DARTSLIVE_HOME_POSITION_FORMAT } from '../constants/position-format';
import { connectStatusAtom, dartsRoundsHistoryAtom } from '../stores/atoms';
import { connectToBluetoothDevice } from '../utils/connect-bluetooth-dartsboard';

const fillLastRoundWithNull = (
roundsHistory: Array<[DartsHitHistory?, DartsHitHistory?, DartsHitHistory?]>,
) => {
const newRoundsHistory = [...roundsHistory];
const lastRound = newRoundsHistory[newRoundsHistory.length - 1];
const numToFill = 3 - lastRound.length;
for (let i = 0; i < numToFill; i++) {
lastRound.push(null);
}
return newRoundsHistory;
};

export const useConnectDartsliveHome = () => {
const [dartsRoundsHistory, setDartsRoundsHistory] = useAtom(
dartsRoundsHistoryAtom,
);
const [connectStatus, setConnectStatus] = useAtom(connectStatusAtom);

const connectDartsliveHome = async () => {
try {
await connectToBluetoothDevice({
bluetoothUUID: DARTSLIVE_HOME_BLUETOOTH_UUID,
handleDartsHit: target => {
const hitTarget = DARTSLIVE_HOME_POSITION_FORMAT[target];
setDartsRoundsHistory(prev => {
const newDartsRoundsHistory = [...prev];

// 最後の配列が最大個数の場合、配列を追加する
if (
newDartsRoundsHistory[newDartsRoundsHistory.length - 1].length ===
3
) {
newDartsRoundsHistory.push([]);
}

// チェンジボタンが押されたら、最後の配列をnullで埋める
if (hitTarget.position_code === 'CHANGE') {
newDartsRoundsHistory[newDartsRoundsHistory.length - 1] =
fillLastRoundWithNull(newDartsRoundsHistory)[
newDartsRoundsHistory.length - 1
];
} else {
newDartsRoundsHistory[newDartsRoundsHistory.length - 1].push(
hitTarget,
);
}

return newDartsRoundsHistory;
});
},
handleConnectStatus: connectStatus => {
setConnectStatus(connectStatus);
},
});
} catch (error) {
// TODO: toast
console.error(error);
}
};

const finalizeCurrentRound = () => {
if (dartsRoundsHistory[dartsRoundsHistory.length - 1].length === 3) {
setDartsRoundsHistory(prev => [...prev, []]);
}
setDartsRoundsHistory(prev => fillLastRoundWithNull(prev));
};

return {
connectDartsliveHome,
finalizeCurrentRound,
dartsRoundsHistory,
connectStatus,
};
};
12 changes: 12 additions & 0 deletions src/entitie/dartsboard/stores/atoms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Darts_Positions } from '@/shared/libs/gql-codegen/generated/graphql';
import { atom } from 'jotai';

export type ConnectStatus = 'disconnected' | 'connecting' | 'connected';
export const connectStatusAtom = atom<ConnectStatus>('disconnected');

export type DartsPosition = Darts_Positions;
export type DartsHitHistory = DartsPosition | null;

export const dartsRoundsHistoryAtom = atom<
Array<[DartsHitHistory?, DartsHitHistory?, DartsHitHistory?]>
>([[]]);
Loading

0 comments on commit dfa482a

Please sign in to comment.