Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bb63d6c

Browse files
committed
Merge branch 'bot-mobile-ux' into 'master'
Bot UI: Enhance UX on mobile See merge request postgres-ai/database-lab!869
2 parents 12c0ed5 + b34d7d8 commit bb63d6c

File tree

6 files changed

+87
-17
lines changed

6 files changed

+87
-17
lines changed

‎ui/packages/platform/src/components/ContentLayout/Footer/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const Footer = () => {
6868
const classes = useStyles()
6969

7070
return (
71-
<div className={classes.footer}>
71+
<footer className={classes.footer}>
7272
<div className={classes.footerCopyrightItem}>
7373
{new Date().getFullYear()} © Postgres.AI
7474
</div>
@@ -103,6 +103,6 @@ export const Footer = () => {
103103
</GatewayLink>
104104
</div>
105105
</div>
106-
</div>
106+
</footer>
107107
)
108108
}

‎ui/packages/platform/src/pages/Bot/ChatsList/ChatsList.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import React from "react";
99
import { Link } from "react-router-dom";
1010
import { useParams } from "react-router";
1111
import cn from "classnames";
12-
import { makeStyles, Theme } from "@material-ui/core";
12+
import { makeStyles, Theme,useMediaQuery } from "@material-ui/core";
1313
import Drawer from '@material-ui/core/Drawer';
1414
import List from "@material-ui/core/List";
1515
import Divider from "@material-ui/core/Divider";
@@ -18,6 +18,7 @@ import Box from "@mui/material/Box";
1818
import { Spinner } from "@postgres.ai/shared/components/Spinner";
1919
import { HeaderButtons, HeaderButtonsProps } from "../HeaderButtons/HeaderButtons";
2020
import { BotMessage } from "../../../types/api/entities/bot";
21+
import { theme } from "@postgres.ai/shared/styles/theme";
2122

2223

2324
const useStyles = makeStyles<Theme, ChatsListProps>((theme) => ({
@@ -111,7 +112,7 @@ export const ChatsList = (props: ChatsListProps) => {
111112
} = props;
112113
const classes = useStyles(props);
113114
const params = useParams<{ org?: string, threadId?: string }>();
114-
115+
constmatches=useMediaQuery(theme.breakpoints.down('sm'));
115116
const linkBuilder = (msgId: string) => {
116117
if (params.org) {
117118
return `/${params.org}/bot/${msgId}`
@@ -126,6 +127,12 @@ export const ChatsList = (props: ChatsListProps) => {
126127
}
127128
}
128129

130+
const handleCloseOnClickOutside = () => {
131+
if (matches) {
132+
onClose()
133+
}
134+
}
135+
129136
const loader = (
130137
<Box className={classes.loader}>
131138
<Spinner/>
@@ -172,11 +179,12 @@ export const ChatsList = (props: ChatsListProps) => {
172179

173180
return (
174181
<Drawer
175-
variant={'persistent'}
182+
variant={matches ? 'temporary' : 'persistent'}
176183
anchor="right"
177184
BackdropProps={{ invisible: true }}
178185
elevation={1}
179186
open={isOpen}
187+
onClose={handleCloseOnClickOutside}
180188
classes={{
181189
paper: classes.drawerPaper
182190
}}

‎ui/packages/platform/src/pages/Bot/Command/Command.tsx

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { useBuffer } from './useBuffer'
1414
import { useCaret } from './useCaret'
1515
import { theme } from "@postgres.ai/shared/styles/theme";
16+
import { isMobileDevice } from "../../../utils/utils";
1617

1718

1819
type Props = {
@@ -76,7 +77,7 @@ export const Command = React.memo((props: Props) => {
7677
const { sendDisabled, onSend, threadId } = props
7778

7879
const classes = useStyles()
79-
80+
constisMobile=isMobileDevice();
8081
// Handle value.
8182
const [value, setValue] = useState('')
8283

@@ -104,11 +105,21 @@ export const Command = React.memo((props: Props) => {
104105
}
105106

106107
const handleBlur = () => {
107-
if (window.innerWidth < theme.breakpoints.values.sm)
108-
window.scrollTo({
109-
top: 0,
110-
behavior: 'smooth'
111-
})
108+
if ((window.innerWidth < theme.breakpoints.values.sm) && isMobile) {
109+
window.scrollTo({
110+
top: 0,
111+
behavior: 'smooth'
112+
})
113+
const footer: HTMLElement | null = document.querySelector("footer")
114+
if (footer) footer.style.display = 'flex';
115+
}
116+
}
117+
118+
const handleFocus = () => {
119+
if ((window.innerWidth < theme.breakpoints.values.sm) && isMobile) {
120+
const footer: HTMLElement | null = document.querySelector("footer")
121+
if (footer) footer.style.display = 'none';
122+
}
112123
}
113124

114125
const handleKeyDown = (e: React.KeyboardEvent) => {
@@ -163,19 +174,20 @@ export const Command = React.memo((props: Props) => {
163174
return (
164175
<div className={classes.root}>
165176
<TextField
166-
autoFocus={true}
177+
autoFocus={window.innerWidth>theme.breakpoints.values.sm}
167178
multiline
168179
className={classes.field}
169180
onKeyDown={handleKeyDown}
181+
onChange={handleChange}
170182
onBlur={handleBlur}
183+
onFocus={handleFocus}
171184
InputProps={{
172185
inputRef,
173186
classes: {
174187
input: classes.fieldInput,
175188
},
176189
}}
177190
value={value}
178-
onChange={handleChange}
179191
placeholder="Message..."
180192
/>
181193
<IconButton

‎ui/packages/platform/src/pages/Bot/Command/utils.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
export const checkIsSendCmd = (e: KeyboardEvent) =>
2-
e.code === 'Enter' && !e.shiftKey && !e.ctrlKey && !e.metaKey
1+
import { isMobileDevice } from "../../../utils/utils";
32

4-
export const checkIsNewLineCmd = (e: KeyboardEvent) =>
5-
e.code === 'Enter' && (e.shiftKey || e.ctrlKey || e.metaKey)
3+
export const checkIsSendCmd = (e: KeyboardEvent): boolean => {
4+
if (isMobileDevice()) {
5+
return false; // On mobile devices, Enter should not send.
6+
}
7+
return e.code === 'Enter' && !e.shiftKey && !e.ctrlKey && !e.metaKey;
8+
};
9+
10+
export const checkIsNewLineCmd = (e: KeyboardEvent): boolean => {
11+
if (isMobileDevice()) {
12+
return e.code === 'Enter'; // On mobile devices, Enter should create a new line.
13+
}
14+
return e.code === 'Enter' && (e.shiftKey || e.ctrlKey || e.metaKey);
15+
};
616

717
export const addNewLine = (
818
value: string,

‎ui/packages/platform/src/utils/utils.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,41 @@ export const validateDLEName = (name: string) => {
3131
!name.match(/^([a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19})$/)
3232
)
3333
}
34+
35+
export const isMobileDevice = (): boolean => {
36+
let hasTouchScreen = false;
37+
38+
// Check for modern touch screen devices using maxTouchPoints
39+
if ("maxTouchPoints" in navigator) {
40+
hasTouchScreen = navigator.maxTouchPoints > 0;
41+
}
42+
// Check for older versions of IE with msMaxTouchPoints
43+
else if ("msMaxTouchPoints" in navigator) {
44+
hasTouchScreen = (navigator as unknown as { msMaxTouchPoints: number }).msMaxTouchPoints > 0;
45+
}
46+
// Use matchMedia to check for coarse pointer devices
47+
else {
48+
const mQ = window.matchMedia("(pointer:coarse)");
49+
if (mQ && mQ.media === "(pointer:coarse)") {
50+
hasTouchScreen = mQ.matches;
51+
}
52+
// Check for the presence of the orientation property as a fallback (deprecated in modern browsers)
53+
else if ('orientation' in window) {
54+
hasTouchScreen = true;
55+
}
56+
// Last resort: fallback with user agent sniffing
57+
else {
58+
const UA = navigator.userAgent;
59+
hasTouchScreen = (
60+
/\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) ||
61+
/\b(Android|WindowsPhone|iPad|iPod)\b/i.test(UA)
62+
);
63+
}
64+
}
65+
66+
// Check for mobile screen width, 1366 because of iPad Pro in Landscape mode
67+
// If this is not necessary, may reduce value to 1024 or 768
68+
const isMobileScreen = window.innerWidth <= 1366;
69+
70+
return hasTouchScreen && isMobileScreen;
71+
}

‎ui/packages/shared/components/TextField/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export type TextFieldProps = {
3434
error?: boolean
3535
placeholder?: string
3636
onBlur?: TextFieldPropsBase['onBlur']
37+
onFocus?: TextFieldPropsBase['onFocus']
3738
}
3839

3940
const useStyles = makeStyles(
@@ -98,6 +99,7 @@ export const TextField = (props: TextFieldProps) => {
9899
error={props.error}
99100
placeholder={props.placeholder}
100101
onBlur={props.onBlur}
102+
onFocus={props.onFocus}
101103
/>
102104
)
103105
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /