|
1 |
| -import type { ReactNode } from 'react'; |
2 |
| -import { useEffect } from 'react'; |
| 1 | +import { type ReactNode, useCallback, useState } from 'react'; |
3 | 2 | import { runInBackground } from '../../common/async';
|
| 3 | +import { equalsIgnoreCase } from '../../common/string'; |
4 | 4 | import { useLogger } from '../components/logger';
|
5 | 5 |
|
| 6 | +interface IpcSgeCharacter { |
| 7 | + gameCode: string; |
| 8 | + accountName: string; |
| 9 | + characterName: string; |
| 10 | +} |
| 11 | + |
6 | 12 | const HomePage: React.FC = (): ReactNode => {
|
7 |
| - // -- |
8 |
| - const { logger } = useLogger('page:grid'); |
9 |
| - useEffect(() => { |
10 |
| - runInBackground(async () => { |
11 |
| - logger.info('>> ping', { response: await window.api.ping() }); |
| 13 | + const { logger } = useLogger('page:home'); |
12 | 14 |
|
13 |
| - logger.info('>> sgeAddAccount', { |
14 |
| - response: await window.api.sgeAddAccount({ |
15 |
| - gameCode: 'DR', |
16 |
| - username: 'test-username', |
17 |
| - password: 'test-password', |
18 |
| - }), |
19 |
| - }); |
| 15 | + // TODO add state to track when any of the callbacks are running |
| 16 | + // so that we show a loading indicator or overlay or something |
| 17 | + // to prevent the user issuing more commands concurrently |
20 | 18 |
|
21 |
| - logger.info('>> sgeRemoveAccount', { |
22 |
| - response: await window.api.sgeRemoveAccount({ |
23 |
| - gameCode: 'DR', |
24 |
| - username: 'test-username', |
25 |
| - }), |
26 |
| - }); |
| 19 | + const [characters, setCharacters] = useState<Array<IpcSgeCharacter>>([]); |
| 20 | + |
| 21 | + const [playingCharacter, setPlayingCharacter] = useState< |
| 22 | + IpcSgeCharacter | undefined |
| 23 | + >(); |
| 24 | + |
| 25 | + const listCharacters = useCallback(async () => { |
| 26 | + setCharacters(await window.api.listCharacters()); |
| 27 | + }, []); |
27 | 28 |
|
28 |
| - logger.info('>> sgeListAccounts', { |
29 |
| - response: await window.api.sgeListAccounts({ |
30 |
| - gameCode: 'DR', |
31 |
| - }), |
| 29 | + const saveAccount = useCallback( |
| 30 | + (options: { accountName: string; accountPassword: string }) => { |
| 31 | + runInBackground(async () => { |
| 32 | + const { accountName } = options; |
| 33 | + logger.info('saving account', { accountName }); |
| 34 | + await window.api.saveAccount(options); |
| 35 | + await listCharacters(); |
32 | 36 | });
|
| 37 | + }, |
| 38 | + [] |
| 39 | + ); |
33 | 40 |
|
34 |
| - logger.info('>> sgeListCharacters', { |
35 |
| - response: await window.api.sgeListCharacters({ |
36 |
| - gameCode: 'DR', |
37 |
| - username: 'test-username', |
38 |
| - }), |
| 41 | + const removeAccount = useCallback((options: { accountName: string }) => { |
| 42 | + runInBackground(async () => { |
| 43 | + const { accountName } = options; |
| 44 | + logger.info('removing account', { accountName }); |
| 45 | + if (equalsIgnoreCase(playingCharacter?.accountName, accountName)) { |
| 46 | + await quitCharacter(); |
| 47 | + } |
| 48 | + await window.api.removeAccount(options); |
| 49 | + await listCharacters(); |
| 50 | + }); |
| 51 | + }, []); |
| 52 | + |
| 53 | + const addCharacter = useCallback( |
| 54 | + (options: { |
| 55 | + gameCode: string; |
| 56 | + accountName: string; |
| 57 | + characterName: string; |
| 58 | + }) => { |
| 59 | + runInBackground(async () => { |
| 60 | + const { characterName } = options; |
| 61 | + logger.info('saving character', { characterName }); |
| 62 | + await window.api.saveCharacter(options); |
| 63 | + await listCharacters(); |
39 | 64 | });
|
| 65 | + }, |
| 66 | + [] |
| 67 | + ); |
40 | 68 |
|
41 |
| - logger.info('>> gamePlayCharacter', { |
42 |
| - response: await window.api.gamePlayCharacter({ |
43 |
| - gameCode: 'DR', |
44 |
| - username: 'test-username', |
45 |
| - characterName: 'test-character', |
46 |
| - }), |
| 69 | + const removeCharacter = useCallback( |
| 70 | + (options: { |
| 71 | + gameCode: string; |
| 72 | + accountName: string; |
| 73 | + characterName: string; |
| 74 | + }) => { |
| 75 | + runInBackground(async () => { |
| 76 | + const { gameCode, accountName, characterName } = options; |
| 77 | + logger.info('removing character', { characterName }); |
| 78 | + if ( |
| 79 | + equalsIgnoreCase(playingCharacter?.gameCode, gameCode) && |
| 80 | + equalsIgnoreCase(playingCharacter?.accountName, accountName) && |
| 81 | + equalsIgnoreCase(playingCharacter?.characterName, characterName) |
| 82 | + ) { |
| 83 | + await quitCharacter(); |
| 84 | + } |
| 85 | + await window.api.removeCharacter(options); |
| 86 | + await listCharacters(); |
47 | 87 | });
|
| 88 | + }, |
| 89 | + [] |
| 90 | + ); |
48 | 91 |
|
49 |
| - logger.info('>> gameSendCommand', { |
50 |
| - response: await window.api.gameSendCommand('test command'), |
| 92 | + const playCharacter = useCallback( |
| 93 | + (options: { |
| 94 | + gameCode: string; |
| 95 | + accountName: string; |
| 96 | + characterName: string; |
| 97 | + }) => { |
| 98 | + runInBackground(async () => { |
| 99 | + const { gameCode, accountName, characterName } = options; |
| 100 | + logger.info('playing character', { characterName }); |
| 101 | + await window.api.playCharacter(options); |
| 102 | + setPlayingCharacter({ |
| 103 | + gameCode, |
| 104 | + accountName, |
| 105 | + characterName, |
| 106 | + }); |
51 | 107 | });
|
52 |
| - }); |
| 108 | + }, |
| 109 | + [] |
| 110 | + ); |
53 | 111 |
|
54 |
| - window.api.onMessage('window:pong', (_event, data) => { |
55 |
| - logger.info('<< window:pong', { data }); |
56 |
| - }); |
| 112 | + const quitCharacter = useCallback(async () => { |
| 113 | + if (playingCharacter) { |
| 114 | + const characterName = playingCharacter.characterName; |
| 115 | + logger.info('quitting character', { characterName }); |
| 116 | + await window.api.sendCommand('quit'); |
| 117 | + setPlayingCharacter(undefined); |
| 118 | + } |
57 | 119 | }, []);
|
58 |
| - // -- |
59 | 120 |
|
60 |
| - // TODO show welcome page |
61 |
| - // user to select recent character, or add account, etc |
62 |
| - // once select a character, then log in and load grid |
63 |
| - return <div>Hello World</div>; |
| 121 | + return ( |
| 122 | + <div> |
| 123 | + <h2>Characters</h2> |
| 124 | + <div> |
| 125 | + <button |
| 126 | + onClick={() => { |
| 127 | + saveAccount({ |
| 128 | + accountName: 'test', |
| 129 | + accountPassword: 'test', |
| 130 | + }); |
| 131 | + }} |
| 132 | + > |
| 133 | + Save Account |
| 134 | + </button> |
| 135 | + <button |
| 136 | + onClick={() => { |
| 137 | + addCharacter({ |
| 138 | + gameCode: 'DR', |
| 139 | + accountName: 'test', |
| 140 | + characterName: 'test', |
| 141 | + }); |
| 142 | + }} |
| 143 | + > |
| 144 | + Add Character |
| 145 | + </button> |
| 146 | + </div> |
| 147 | + {characters.map((character) => { |
| 148 | + return ( |
| 149 | + <div key={character.characterName}> |
| 150 | + Game Code: {character.gameCode} <br /> |
| 151 | + Account Name: {character.accountName} <br /> |
| 152 | + Character Name: {character.characterName} |
| 153 | + </div> |
| 154 | + ); |
| 155 | + })} |
| 156 | + </div> |
| 157 | + ); |
64 | 158 | };
|
65 | 159 |
|
66 | 160 | export default HomePage;
|
0 commit comments