Skip to content

Commit 74f7a55

Browse files
committed
feat: add preferences service
1 parent 8278fb7 commit 74f7a55

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { PreferenceService } from '../preference.types';
2+
3+
class PreferenceServiceMock implements PreferenceService {
4+
get = jest.fn();
5+
set = jest.fn();
6+
remove = jest.fn();
7+
}
8+
9+
export { PreferenceServiceMock };

electron/main/preference/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './preference.service';
2+
export * from './preference.types';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type { Maybe } from '../../common/types';
2+
import { Store, type StoreService } from '../store';
3+
import type {
4+
PreferenceKey,
5+
PreferenceKeyToTypeMap,
6+
PreferenceService,
7+
} from './preference.types';
8+
9+
class PreferenceServiceImpl implements PreferenceService {
10+
private storeService: StoreService;
11+
12+
constructor(options: { storeService: StoreService }) {
13+
this.storeService = options.storeService;
14+
}
15+
16+
public async get<K extends PreferenceKey>(
17+
key: K
18+
): Promise<Maybe<PreferenceKeyToTypeMap[K]>> {
19+
return this.storeService.get(key);
20+
}
21+
22+
public async set<K extends PreferenceKey, V = PreferenceKeyToTypeMap[K]>(
23+
key: K,
24+
value: V
25+
): Promise<void> {
26+
await this.storeService.set(key, value);
27+
}
28+
29+
public async remove(key: PreferenceKey): Promise<void> {
30+
await this.storeService.remove(key);
31+
}
32+
}
33+
34+
// There is exactly one preference service instance so that it's
35+
// easy anywhere in the app to get/set preference values.
36+
export const Preferences = new PreferenceServiceImpl({
37+
storeService: Store.getInstance(),
38+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import type { Layout } from 'react-grid-layout';
2+
import type { Maybe } from '../../common/types';
3+
4+
export enum PreferenceKey {
5+
/**
6+
* The window zoom factor (as a percentage).
7+
* 0.5 = 50%
8+
* 1.0 = 100%
9+
* 1.5 = 150%
10+
*/
11+
WINDOW_ZOOM_FACTOR = 'preference.window.zoomFactor',
12+
/**
13+
* How the mind state is shown in the game content experience stream.
14+
* When 'numbers' then the mind state is shown as a fraction (e.g. 7/34).
15+
* When 'words' then the mind state is shown as a word (e.g. 'pondering').
16+
*/
17+
GAME_CONTENT_EXPERIENCE_SHOW_MIND_STATE_AS = 'preference.gameContent.experience.showMindStateAs',
18+
/**
19+
* The maximum number of lines to keep in any game content stream.
20+
*/
21+
GAME_CONTENT_SCROLLBACK_BUFFER_SIZE = 'preference.gameContent.scrollbackBufferSize',
22+
/**
23+
* Map of grid item ids or other identifiers to custom text styles.
24+
*
25+
* Example keys include grid item ids like 'main', 'combat', etc.
26+
*
27+
* They also include the special keys '__ROOM_NAME__' and '__BOLD__',
28+
* which are used to style the room name and bold text respectively.
29+
*
30+
* They also include the special key '__DEFAULT__', which is used
31+
* when no grid item-specific text style is defined.
32+
*/
33+
GAME_CONTENT_TEXT_STYLES = 'preference.gameContent.textStyles',
34+
/**
35+
* Map of character names to grid layouts.
36+
*
37+
* Example keys include character names like 'Alice', 'Bob', 'Carol', etc.
38+
*
39+
* They also include the special key '__DEFAULT__', which is used
40+
* when no character-specific grid layout is defined.
41+
*/
42+
GAME_CONTENT_GRID_LAYOUTS = 'preference.gameContent.gridLayouts',
43+
}
44+
45+
export type PreferenceKeyToTypeMap = {
46+
[PreferenceKey.WINDOW_ZOOM_FACTOR]: number;
47+
48+
[PreferenceKey.GAME_CONTENT_EXPERIENCE_SHOW_MIND_STATE_AS]:
49+
| 'numbers'
50+
| 'words';
51+
52+
[PreferenceKey.GAME_CONTENT_SCROLLBACK_BUFFER_SIZE]: number;
53+
54+
[PreferenceKey.GAME_CONTENT_TEXT_STYLES]: {
55+
[key: string]: {
56+
fontFamilySerif?: string;
57+
fontFamilyMono?: string;
58+
fontSize?: number;
59+
color?: string;
60+
backgroundColor?: string;
61+
};
62+
};
63+
64+
[PreferenceKey.GAME_CONTENT_GRID_LAYOUTS]: {
65+
/**
66+
* Who the grid layout belongs to.
67+
*/
68+
[key: string]: {
69+
/**
70+
* The items on the grid.
71+
*/
72+
gridItems: Array<{ id: string; title: string }>;
73+
/**
74+
* How those items are positioned on the grid.
75+
*/
76+
gridLayout: Array<Layout>;
77+
};
78+
};
79+
};
80+
81+
export interface PreferenceService {
82+
get<K extends PreferenceKey>(
83+
key: K
84+
): Promise<Maybe<PreferenceKeyToTypeMap[K]>>;
85+
86+
set<K extends PreferenceKey, V = PreferenceKeyToTypeMap[K]>(
87+
key: K,
88+
value: V
89+
): Promise<void>;
90+
91+
remove(key: PreferenceKey): Promise<void>;
92+
}

0 commit comments

Comments
 (0)