Skip to content

Commit cb5e35f

Browse files
committed
[svelte] New API changes
1 parent c9882df commit cb5e35f

File tree

11 files changed

+514
-793
lines changed

11 files changed

+514
-793
lines changed

templates/client/src/chat/Message.svelte.hbs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,29 @@
22

33
<script{{#if typescript}} lang="ts"{{/if}}>
44
import './message.css';
5-
{{#if typescript}}import type {MessageRow} from './chatStore';{{/if}}
5+
import {createRow} from 'tinybase/ui-svelte';
6+
import {chatStore} from './chatStore';
7+
{{#if typescript}}
8+
{{#if schemas}}
9+
import type {Store as TinyBaseStore} from 'tinybase';
10+
{{/if}}
11+
import type {MessageRow} from './chatStore';
12+
{{/if}}
613
7-
let {message}{{#if typescript}}: {message: MessageRow}{{/if}} = $props();
14+
let {rowId}{{#if typescript}}: {rowId: string}{{/if}} = $props();
15+
16+
const message = createRow(
17+
'messages',
18+
() => rowId,
19+
{{#if schemas}}chatStore as unknown as TinyBaseStore{{else}}chatStore{{/if}},
20+
){{#if typescript}} as {readonly current: MessageRow}{{/if}};
821
922
const getTime = (timestamp{{#if typescript}}: number{{/if}}) =>
1023
new Date(timestamp).toLocaleTimeString();
1124
</script>
1225

1326
<div class="message">
14-
<span class="username">{message.username}:</span>
15-
<span class="text">{message.text}</span>
16-
<span class="time">{getTime(message.timestamp)}</span>
27+
<span class="username">{message.current.username}:</span>
28+
<span class="text">{message.current.text}</span>
29+
<span class="time">{getTime(message.current.timestamp)}</span>
1730
</div>

templates/client/src/chat/MessageInput.svelte.hbs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,32 @@
66
import './button.css';
77
import './input.css';
88
import './messageInput.css';
9+
import {createValue} from 'tinybase/ui-svelte';
910
import {onMount} from 'svelte';
1011
import {chatStore} from './chatStore';
1112
import {settingsStore} from './settingsStore';
13+
{{#if schemas}}
14+
{{#if typescript}}
15+
import type {Store as TinyBaseStore} from 'tinybase';
16+
{{/if}}
17+
{{/if}}
1218
1319
let message = $state('');
1420
let input{{#if typescript}}: HTMLInputElement | undefined{{/if}};
1521
22+
const username = createValue(
23+
'username',
24+
{{#if schemas}}settingsStore as unknown as TinyBaseStore{{else}}settingsStore{{/if}},
25+
){{#if typescript}} as {current: string | undefined}{{/if}};
26+
1627
const sendMessage = () => {
1728
const text = message.trim();
1829
if (!text) {
1930
return;
2031
}
2132
22-
const username =
23-
{{#if typescript}}(settingsStore.getValue('username') as string | undefined) ?? 'Anonymous'{{else}}settingsStore.getValue('username') ?? 'Anonymous'{{/if}};
24-
2533
chatStore.addRow('messages', {
26-
username,
34+
username: username.current || 'Anonymous',
2735
text,
2836
timestamp: Date.now(),
2937
});

templates/client/src/chat/Messages.svelte.hbs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,27 @@
33

44
<script{{#if typescript}} lang="ts"{{/if}}>
55
import './messages.css';
6-
import {onMount} from 'svelte';
6+
import {createSortedRowIds} from 'tinybase/ui-svelte';
77
import Message from './Message.svelte';
88
import {chatStore} from './chatStore';
9-
{{#if typescript}}import type {MessageRow} from './chatStore';{{/if}}
9+
{{#if schemas}}
10+
{{#if typescript}}
11+
import type {Store as TinyBaseStore} from 'tinybase';
12+
{{/if}}
13+
{{/if}}
1014
11-
const getMessages = () =>
12-
chatStore.getSortedRowIds('messages', 'timestamp').map((id) => ({
13-
id,
14-
row:
15-
{{#if typescript}}chatStore.getRow('messages', id) as MessageRow{{else}}chatStore.getRow('messages', id){{/if}},
16-
}));
17-
18-
let messages = $state(getMessages());
19-
20-
const updateMessages = () => {
21-
messages = getMessages();
22-
};
23-
24-
onMount(() => {
25-
chatStore.addTablesListener(updateMessages);
26-
updateMessages();
27-
});
15+
const messageIds = createSortedRowIds(
16+
'messages',
17+
'timestamp',
18+
false,
19+
0,
20+
undefined,
21+
{{#if schemas}}chatStore as unknown as TinyBaseStore{{else}}chatStore{{/if}},
22+
){{#if typescript}} as {readonly current: string[]}{{/if}};
2823
</script>
2924

3025
<div id="messages">
31-
{#each messages as message (message.id)}
32-
<Message message={message.row} />
26+
{#each messageIds.current as rowId (rowId)}
27+
<Message {rowId} />
3328
{/each}
3429
</div>

templates/client/src/chat/UsernameInput.svelte.hbs

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,26 @@
44
<script{{#if typescript}} lang="ts"{{/if}}>
55
import './input.css';
66
import './usernameInput.css';
7-
import {onMount} from 'svelte';
7+
import {createValue} from 'tinybase/ui-svelte';
88
import {settingsStore} from './settingsStore';
9-
10-
const getUsername = () =>
11-
{{#if typescript}}(settingsStore.getValue('username') as string | undefined) ?? ''{{else}}settingsStore.getValue('username') ?? ''{{/if}};
12-
13-
let username = $state(getUsername());
14-
15-
const updateUsername = () => {
16-
username = getUsername();
17-
};
18-
19-
const handleInput = (event{{#if typescript}}: Event{{/if}}) => {
9+
{{#if schemas}}
2010
{{#if typescript}}
21-
const input = event.currentTarget as HTMLInputElement;
22-
const nextUsername = input.value;
23-
{{else}}
24-
const nextUsername = event.currentTarget.value;
11+
import type {Store as TinyBaseStore} from 'tinybase';
2512
{{/if}}
26-
settingsStore.setValue('username', nextUsername);
27-
username = nextUsername;
28-
};
13+
{{/if}}
2914
30-
onMount(() => {
31-
settingsStore.addValueListener('username', updateUsername);
32-
updateUsername();
33-
});
15+
const username = createValue(
16+
'username',
17+
{{#if schemas}}settingsStore as unknown as TinyBaseStore{{else}}settingsStore{{/if}},
18+
){{#if typescript}} as {current: string | undefined}{{/if}};
3419
</script>
3520

3621
<div id="usernameInput">
3722
<label for="usernameInputField">Your name:</label>
3823
<input
3924
id="usernameInputField"
4025
type="text"
41-
value={username}
26+
bind:value={username.current}
4227
placeholder="Enter your name"
43-
oninput={handleInput}
4428
/>
4529
</div>

templates/client/src/drawing/BrushSize.svelte.hbs

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,18 @@
22

33
<script{{#if typescript}} lang="ts"{{/if}}>
44
import './brushSize.css';
5-
import {onMount} from 'svelte';
5+
import {createValue} from 'tinybase/ui-svelte';
66
import {settingsStore} from './settingsStore';
7-
8-
const getBrushSize = () =>
9-
{{#if typescript}}(settingsStore.getValue('brushSize') as number | undefined) ?? 5{{else}}settingsStore.getValue('brushSize') ?? 5{{/if}};
10-
11-
let size = $state(getBrushSize());
12-
13-
const updateSize = () => {
14-
size = getBrushSize();
15-
};
16-
17-
const handleInput = (event{{#if typescript}}: Event{{/if}}) => {
7+
{{#if schemas}}
188
{{#if typescript}}
19-
const input = event.currentTarget as HTMLInputElement;
20-
const nextSize = parseInt(input.value);
21-
{{else}}
22-
const nextSize = parseInt(event.currentTarget.value);
9+
import type {Store as TinyBaseStore} from 'tinybase';
2310
{{/if}}
24-
settingsStore.setValue('brushSize', nextSize);
25-
size = nextSize;
26-
};
11+
{{/if}}
2712
28-
onMount(() => {
29-
settingsStore.addValueListener('brushSize', updateSize);
30-
updateSize();
31-
});
13+
const size = createValue(
14+
'brushSize',
15+
{{#if schemas}}settingsStore as unknown as TinyBaseStore{{else}}settingsStore{{/if}},
16+
){{#if typescript}} as {current: number | undefined}{{/if}};
3217
</script>
3318

3419
<div id="brushSize">
@@ -38,8 +23,7 @@ updateSize();
3823
type="range"
3924
min="1"
4025
max="50"
41-
value={size}
42-
oninput={handleInput}
26+
bind:value={size.current}
4327
/>
44-
<span id="brushSizeValue">{size}</span>
28+
<span id="brushSizeValue">{size.current}</span>
4529
</div>

templates/client/src/drawing/ColorPicker.svelte.hbs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,30 @@
22

33
<script{{#if typescript}} lang="ts"{{/if}}>
44
import './colorPicker.css';
5-
import {onMount} from 'svelte';
5+
import {createValue} from 'tinybase/ui-svelte';
66
import {settingsStore} from './settingsStore';
7+
{{#if schemas}}
8+
{{#if typescript}}
9+
import type {Store as TinyBaseStore} from 'tinybase';
10+
{{/if}}
11+
{{/if}}
712
813
const colors = ['#d81b60', '#1976d2', '#388e3c', '#f57c00', '#7b1fa2', '#fff'];
9-
const getCurrentColor = () =>
10-
{{#if typescript}}(settingsStore.getValue('brushColor') as string | undefined) ?? '#d81b60'{{else}}settingsStore.getValue('brushColor') ?? '#d81b60'{{/if}};
11-
12-
let currentColor = $state(getCurrentColor());
13-
14-
const updateActive = () => {
15-
currentColor = getCurrentColor();
16-
};
14+
const currentColor = createValue(
15+
'brushColor',
16+
{{#if schemas}}settingsStore as unknown as TinyBaseStore{{else}}settingsStore{{/if}},
17+
){{#if typescript}} as {current: string | undefined}{{/if}};
1718
1819
const setColor = (color{{#if typescript}}: string{{/if}}) => {
19-
settingsStore.setValue('brushColor', color);
20+
currentColor.current = color;
2021
};
21-
22-
onMount(() => {
23-
settingsStore.addValueListener('brushColor', updateActive);
24-
updateActive();
25-
});
2622
</script>
2723

2824
<div id="colorPicker">
2925
{#each colors as color (color)}
3026
<button
3127
class="colorBtn"
32-
class:active={currentColor === color}
28+
class:active={currentColor.current === color}
3329
style={`background: ${color}`}
3430
onclick={() => setColor(color)}
3531
aria-label={`Select ${color} brush`}

templates/client/src/game/Board.svelte.hbs

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,69 +3,66 @@
33

44
<script{{#if typescript}} lang="ts"{{/if}}>
55
import './board.css';
6-
import {onMount} from 'svelte';
6+
import {createTable, createValues} from 'tinybase/ui-svelte';
77
import Square from './Square.svelte';
88
import {store} from './store';
9+
{{#if schemas}}
10+
{{#if typescript}}
11+
import type {Store as TinyBaseStore} from 'tinybase';
12+
{{/if}}
13+
{{/if}}
914
10-
const getSquares = () => {
11-
const gameStatus =
12-
{{#if typescript}}(store.getValue('gameStatus') as string | undefined) ?? 'playing'{{else}}store.getValue('gameStatus') ?? 'playing'{{/if}};
13-
const winningLine =
14-
{{#if typescript}}(store.getValue('winningLine') as string | undefined) ?? ''{{else}}store.getValue('winningLine') ?? ''{{/if}};
15-
const currentPlayer =
16-
{{#if typescript}}(store.getValue('currentPlayer') as string | undefined) ?? 'X'{{else}}store.getValue('currentPlayer') ?? 'X'{{/if}};
15+
const positions = Array.from({length: 9}, (_, i) => i.toString());
16+
17+
const board = createTable(
18+
'board',
19+
{{#if schemas}}store as unknown as TinyBaseStore{{else}}store{{/if}},
20+
){{#if typescript}} as {readonly current: Record<string, {value?: string}>}{{/if}};
21+
22+
const gameState = createValues(
23+
{{#if schemas}}store as unknown as TinyBaseStore{{else}}store{{/if}},
24+
){{#if typescript}} as {
25+
readonly current: {
26+
currentPlayer?: string;
27+
gameStatus?: string;
28+
winningLine?: string;
29+
};
30+
}{{/if}};
31+
32+
const getSquare = (position{{#if typescript}}: string{{/if}}) => {
33+
const gameStatus = gameState.current.gameStatus ?? 'playing';
34+
const winningLine = gameState.current.winningLine ?? '';
1735
const winningPositions = new Set(
1836
winningLine ? winningLine.split(',') : [],
1937
);
20-
const disabled = gameStatus !== 'playing';
21-
22-
return Array.from({length: 9}, (_, i) => {
23-
const position = i.toString();
24-
const value =
25-
{{#if typescript}}(store.getCell('board', position, 'value') as string | undefined) ?? ''{{else}}store.getCell('board', position, 'value') ?? ''{{/if}};
38+
const value = board.current[position]?.value ?? '';
2639
2740
return {
28-
position,
2941
value,
30-
disabled: disabled || !!value,
42+
disabled: gameStatus !== 'playing' || !!value,
3143
winning: winningPositions.has(position),
32-
currentPlayer,
3344
};
34-
});
35-
};
36-
37-
let squares = $state(getSquares());
38-
39-
const updateBoard = () => {
40-
squares = getSquares();
4145
};
4246
4347
const handleSquareClick = (position{{#if typescript}}: string{{/if}}) => {
44-
const gameStatus =
45-
{{#if typescript}}(store.getValue('gameStatus') as string | undefined) ?? 'playing'{{else}}store.getValue('gameStatus') ?? 'playing'{{/if}};
46-
const currentPlayer =
47-
{{#if typescript}}(store.getValue('currentPlayer') as string | undefined) ?? 'X'{{else}}store.getValue('currentPlayer') ?? 'X'{{/if}};
48-
const value = store.getCell('board', position, 'value');
48+
const gameStatus = gameState.current.gameStatus ?? 'playing';
49+
const currentPlayer = gameState.current.currentPlayer ?? 'X';
50+
const value = board.current[position]?.value;
4951
5052
if (gameStatus === 'playing' && !value && currentPlayer) {
5153
store.setCell('board', position, 'value', currentPlayer);
5254
}
5355
};
54-
55-
onMount(() => {
56-
store.addValuesListener(updateBoard);
57-
store.addTableListener('board', updateBoard);
58-
updateBoard();
59-
});
6056
</script>
6157
6258
<div id="board">
63-
{#each squares as square (square.position)}
59+
{#each positions as position (position)}
60+
{@const square = getSquare(position)}
6461
<Square
6562
value={square.value}
6663
disabled={square.disabled}
6764
winning={square.winning}
68-
handleClick={() => handleSquareClick(square.position)}
65+
handleClick={() => handleSquareClick(position)}
6966
/>
7067
{/each}
7168
</div>

0 commit comments

Comments
 (0)