Skip to content

Commit 5028447

Browse files
authored
ui: Refactor isMobile as reactive value in viewport store (ggml-org#23330)
* refactor: `isMobile` as reactive value in `viewport` store * refactor: Use Svelte media query for the viewport store
1 parent 585080d commit 5028447

7 files changed

Lines changed: 18 additions & 24 deletions

File tree

tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionsAdd.svelte

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { IsMobile } from '$lib/hooks/is-mobile.svelte';
2+
import { isMobile } from '$lib/stores/viewport.svelte';
33
import ChatFormActionAddDropdown from './ChatFormActionAddDropdown.svelte';
44
import ChatFormActionAddSheet from './ChatFormActionAddSheet.svelte';
55
import ChatFormActionAddButton from './ChatFormActionAddButton.svelte';
@@ -31,8 +31,6 @@
3131
onMcpSettingsClick,
3232
onSystemPromptClick
3333
}: Props = $props();
34-
35-
const isMobile = new IsMobile();
3634
</script>
3735

3836
{#if isMobile.current}

tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionModels.svelte

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { modelsStore, modelOptions, selectedModelId } from '$lib/stores/models.svelte';
44
import { isRouterMode, serverError } from '$lib/stores/server.svelte';
55
import { ModelsSelectorDropdown, ModelsSelectorSheet } from '$lib/components/app';
6-
import { IsMobile } from '$lib/hooks/is-mobile.svelte';
6+
import { isMobile } from '$lib/stores/viewport.svelte';
77
import { activeMessages } from '$lib/stores/conversations.svelte';
88
99
interface Props {
@@ -152,8 +152,6 @@
152152
let selectorModelRef: ModelsSelectorDropdown | ModelsSelectorSheet | undefined =
153153
$state(undefined);
154154
155-
let isMobile = new IsMobile();
156-
157155
export function open() {
158156
selectorModelRef?.open();
159157
}

tools/ui/src/lib/components/ui/sidebar/context.svelte.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IsMobile } from '$lib/hooks/is-mobile.svelte.js';
1+
import { isMobile } from '$lib/stores/viewport.svelte.js';
22
import { getContext, setContext } from 'svelte';
33
import { SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_MIN_WIDTH } from './constants.js';
44

@@ -27,19 +27,17 @@ class SidebarState {
2727
sidebarWidth = $state(SIDEBAR_MIN_WIDTH);
2828
isResizing = $state(false);
2929
setOpen: SidebarStateProps['setOpen'];
30-
#isMobile: IsMobile;
3130
state = $derived.by(() => (this.open ? 'expanded' : 'collapsed'));
3231

3332
constructor(props: SidebarStateProps) {
3433
this.setOpen = props.setOpen;
35-
this.#isMobile = new IsMobile();
3634
this.props = props;
3735
}
3836

3937
// Convenience getter for checking if the sidebar is mobile
4038
// without this, we would need to use `sidebar.isMobile.current` everywhere
4139
get isMobile() {
42-
return this.#isMobile.current;
40+
return isMobile.current;
4341
}
4442

4543
// Event handler to apply to the `<svelte:window>`

tools/ui/src/lib/hooks/is-mobile.svelte.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

tools/ui/src/lib/stores/settings.svelte.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ import {
4141
SETTINGS_KEYS,
4242
USER_OVERRIDES_LOCALSTORAGE_KEY
4343
} from '$lib/constants';
44-
45-
import { IsMobile } from '$lib/hooks/is-mobile.svelte';
44+
import { isMobile } from '$lib/stores/viewport.svelte';
4645
import { ParameterSyncService } from '$lib/services/parameter-sync.service';
4746
import { serverStore } from '$lib/stores/server.svelte';
4847
import {
@@ -132,7 +131,7 @@ class SettingsStore {
132131

133132
// Default sendOnEnter to false on mobile when the user has no saved preference
134133
if (!(SETTINGS_KEYS.SEND_ON_ENTER in savedVal)) {
135-
if (new IsMobile().current) {
134+
if (isMobile.current) {
136135
this.config[SETTINGS_KEYS.SEND_ON_ENTER] = false;
137136
}
138137
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { browser } from '$app/environment';
2+
import { DEFAULT_MOBILE_BREAKPOINT } from '$lib/constants/viewport';
3+
import { MediaQuery } from 'svelte/reactivity';
4+
5+
export const viewport = $state({
6+
width: browser ? window.innerWidth : 0
7+
});
8+
9+
export const isMobile = new MediaQuery(`max-width: ${DEFAULT_MOBILE_BREAKPOINT - 1}px`);

tools/ui/src/routes/+layout.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@
2626
import { modelsStore } from '$lib/stores/models.svelte';
2727
import { mcpStore } from '$lib/stores/mcp.svelte';
2828
import { TOOLTIP_DELAY_DURATION } from '$lib/constants';
29-
import { IsMobile } from '$lib/hooks/is-mobile.svelte';
3029
import { useKeyboardShortcuts } from '$lib/hooks/use-keyboard-shortcuts.svelte';
3130
import { useSettingsNavigation } from '$lib/hooks/use-settings-navigation.svelte';
3231
import { conversations } from '$lib/stores/conversations.svelte';
32+
import { isMobile } from '$lib/stores/viewport.svelte';
3333
3434
let { children } = $props();
3535
let alwaysShowSidebarOnDesktop = $derived(config().alwaysShowSidebarOnDesktop);
36-
let isMobile = new IsMobile();
3736
let isDesktop = $derived(!isMobile.current);
3837
let sidebarOpen = $state(false);
3938
let mounted = $state(false);
4039
let innerHeight = $state<number | undefined>();
40+
let innerWidth = $state(browser ? window.innerWidth : 0);
4141
4242
let chatSidebar:
4343
| {
@@ -278,4 +278,4 @@
278278
</Sidebar.Provider>
279279
</Tooltip.Provider>
280280

281-
<svelte:window onkeydown={handleKeydown} bind:innerHeight />
281+
<svelte:window onkeydown={handleKeydown} bind:innerHeight bind:innerWidth />

0 commit comments

Comments
 (0)