Skip to content

Commit 7fcecf0

Browse files
committed
feat(hooks): add layout hooks to get, list, save, and delete
1 parent 1006ca1 commit 7fcecf0

File tree

3 files changed

+115
-9
lines changed

3 files changed

+115
-9
lines changed

electron/renderer/hooks/accounts.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,23 @@ export const useGetHasAccounts = (): boolean => {
2727
export const useListAccounts = (): Array<Account> => {
2828
const [accounts, setAccounts] = useState<Array<Account>>([]);
2929

30-
const loadAccounts = useCallback(async () => {
30+
const listAccounts = useCallback(async () => {
3131
const allAccounts = await window.api.listAccounts();
3232
const sortedAccounts = sortBy(allAccounts, 'accountName');
3333
setAccounts(sortedAccounts);
3434
}, []);
3535

3636
// Reload when told to.
3737
useSubscribe(['accounts:reload'], async () => {
38-
await loadAccounts();
38+
await listAccounts();
3939
});
4040

4141
// Reload on first render.
4242
useEffect(() => {
4343
runInBackground(async () => {
44-
await loadAccounts();
44+
await listAccounts();
4545
});
46-
}, [loadAccounts]);
46+
}, [listAccounts]);
4747

4848
return accounts;
4949
};

electron/renderer/hooks/characters.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ export const useListCharacters = (options?: {
1717
}): Array<Character> => {
1818
const [characters, setCharacters] = useState<Array<Character>>([]);
1919

20-
const loadCharacters = useCallback(async () => {
20+
const listCharacters = useCallback(async () => {
2121
const accountName = options?.accountName;
22-
2322
const allCharacters = await window.api.listCharacters();
2423
const filteredCharacters = allCharacters.filter((character) => {
2524
return isBlank(accountName) || character.accountName === accountName;
@@ -30,15 +29,15 @@ export const useListCharacters = (options?: {
3029

3130
// Reload when told to.
3231
useSubscribe(['characters:reload'], async () => {
33-
await loadCharacters();
32+
await listCharacters();
3433
});
3534

3635
// Reload on first render.
3736
useEffect(() => {
3837
runInBackground(async () => {
39-
await loadCharacters();
38+
await listCharacters();
4039
});
41-
}, [loadCharacters]);
40+
}, [listCharacters]);
4241

4342
return characters;
4443
};

electron/renderer/hooks/layouts.tsx

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { useCallback, useEffect, useState } from 'react';
2+
import type { Layout } from '../../common/layout/types.js';
3+
import type { Maybe } from '../../common/types.js';
4+
import { runInBackground } from '../lib/async/run-in-background.js';
5+
import { usePubSub, useSubscribe } from './pubsub.jsx';
6+
7+
export const useGetLayout = (layoutName: string): Maybe<Layout> => {
8+
const [layout, setLayout] = useState<Layout>();
9+
10+
const getLayout = useCallback(async () => {
11+
const layout = await window.api.getLayout({ layoutName });
12+
setLayout(layout);
13+
}, [layoutName]);
14+
15+
// Reload when told to.
16+
useSubscribe(['layouts:reload'], async () => {
17+
await getLayout();
18+
});
19+
20+
// Reload on first render.
21+
useEffect(() => {
22+
runInBackground(async () => {
23+
await getLayout();
24+
});
25+
}, [getLayout]);
26+
27+
return layout;
28+
};
29+
30+
/**
31+
* Returns a list of layout names the user can choose from.
32+
* Automatically refreshes the list when a layout is saved or deleted.
33+
*/
34+
export const useListLayoutNames = (): Array<string> => {
35+
const [layoutNames, setLayoutNames] = useState<Array<string>>([]);
36+
37+
const listLayoutNames = useCallback(async () => {
38+
const layoutNames = await window.api.listLayoutNames();
39+
setLayoutNames(layoutNames);
40+
}, []);
41+
42+
// Reload when told to.
43+
useSubscribe(['layouts:reload'], async () => {
44+
await listLayoutNames();
45+
});
46+
47+
// Reload on first render.
48+
useEffect(() => {
49+
runInBackground(async () => {
50+
await listLayoutNames();
51+
});
52+
}, [listLayoutNames]);
53+
54+
return layoutNames;
55+
};
56+
57+
type SaveLayoutFn = (options: {
58+
layoutName: string;
59+
layout: Layout;
60+
}) => Promise<void>;
61+
62+
/**
63+
* Provides a function that when called saves a layout.
64+
*/
65+
export const useSaveLayout = (): SaveLayoutFn => {
66+
const { publish } = usePubSub();
67+
68+
const fn = useCallback<SaveLayoutFn>(
69+
async (options): Promise<void> => {
70+
const { layoutName, layout } = options;
71+
await window.api.saveLayout({ layoutName, layout });
72+
publish('layouts:reload');
73+
publish('toast:add', {
74+
title: 'Layout Saved',
75+
type: 'success',
76+
text: layoutName,
77+
});
78+
},
79+
[publish]
80+
);
81+
82+
return fn;
83+
};
84+
85+
type DeleteLayoutFn = (layoutName: string) => Promise<void>;
86+
87+
/**
88+
* Provides a function that when called deletes a layout.
89+
*/
90+
export const useDeleteLayout = (): DeleteLayoutFn => {
91+
const { publish } = usePubSub();
92+
93+
const fn = useCallback<DeleteLayoutFn>(
94+
async (layoutName): Promise<void> => {
95+
await window.api.deleteLayout({ layoutName });
96+
publish('layouts:reload');
97+
publish('toast:add', {
98+
title: 'Layout Deleted',
99+
type: 'success',
100+
text: layoutName,
101+
});
102+
},
103+
[publish]
104+
);
105+
106+
return fn;
107+
};

0 commit comments

Comments
 (0)