Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70d6f6ff42 | ||
| 97f0a15ae2 | |||
| 4cf19131bf | |||
|
|
83137c92a9 | ||
| 426ddf5650 | |||
| 7800e7ced7 |
@@ -1,3 +1,5 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {}
|
"dependencies": {
|
||||||
|
"@capacitor/status-bar": "8.0.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { RoomTimeline } from './RoomTimeline';
|
|||||||
import { RoomViewTyping } from './RoomViewTyping';
|
import { RoomViewTyping } from './RoomViewTyping';
|
||||||
import { RoomTombstone } from './RoomTombstone';
|
import { RoomTombstone } from './RoomTombstone';
|
||||||
import { RoomInput } from './RoomInput';
|
import { RoomInput } from './RoomInput';
|
||||||
import { RoomViewFollowing } from './RoomViewFollowing';
|
import { RoomViewFollowing, RoomViewFollowingPlaceholder } from './RoomViewFollowing';
|
||||||
import { Page } from '../../components/page';
|
import { Page } from '../../components/page';
|
||||||
import { RoomViewHeader } from './RoomViewHeader';
|
import { RoomViewHeader } from './RoomViewHeader';
|
||||||
import { useKeyDown } from '../../hooks/useKeyDown';
|
import { useKeyDown } from '../../hooks/useKeyDown';
|
||||||
@@ -65,7 +65,7 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) {
|
|||||||
const roomViewRef = useRef<HTMLDivElement>(null);
|
const roomViewRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
|
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
|
||||||
const { isLandscape, keyboardOpen } = useMobileKeyboardLayout();
|
const { immersive } = useMobileKeyboardLayout();
|
||||||
|
|
||||||
const { roomId } = room;
|
const { roomId } = room;
|
||||||
const editor = useEditor();
|
const editor = useEditor();
|
||||||
@@ -104,9 +104,9 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const flushComposer = keyboardOpen || isLandscape;
|
const flushComposer = immersive;
|
||||||
const composerPadding = flushComposer ? '0' : `0 ${config.space.S400}`;
|
const composerPadding = flushComposer ? '0' : `0 ${config.space.S400}`;
|
||||||
const showHeader = !keyboardOpen;
|
const showHeader = !immersive;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page ref={roomViewRef}>
|
<Page ref={roomViewRef}>
|
||||||
@@ -134,7 +134,7 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) {
|
|||||||
data-composer-flush={flushComposer ? 'true' : undefined}
|
data-composer-flush={flushComposer ? 'true' : undefined}
|
||||||
className={composerCss.ComposerDock}
|
className={composerCss.ComposerDock}
|
||||||
>
|
>
|
||||||
{!hideActivity && (
|
{immersive && !hideActivity && (
|
||||||
<div className={composerCss.FollowingFloat}>
|
<div className={composerCss.FollowingFloat}>
|
||||||
<div className={composerCss.FollowingFloatHit}>
|
<div className={composerCss.FollowingFloatHit}>
|
||||||
<RoomViewFollowing room={room} />
|
<RoomViewFollowing room={room} />
|
||||||
@@ -171,6 +171,12 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{!immersive &&
|
||||||
|
(hideActivity ? (
|
||||||
|
<RoomViewFollowingPlaceholder />
|
||||||
|
) : (
|
||||||
|
<RoomViewFollowing room={room} />
|
||||||
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import { style } from '@vanilla-extract/css';
|
import { style } from '@vanilla-extract/css';
|
||||||
import { recipe } from '@vanilla-extract/recipes';
|
import { recipe } from '@vanilla-extract/recipes';
|
||||||
import { DefaultReset, color, config } from 'folds';
|
import { DefaultReset, color, config, toRem } from 'folds';
|
||||||
|
|
||||||
export const RoomViewFollowingPlaceholder = style([
|
export const RoomViewFollowingPlaceholder = style([
|
||||||
DefaultReset,
|
DefaultReset,
|
||||||
{
|
{
|
||||||
display: 'none',
|
height: toRem(28),
|
||||||
height: 0,
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -14,13 +13,22 @@ export const RoomViewFollowing = recipe({
|
|||||||
base: [
|
base: [
|
||||||
DefaultReset,
|
DefaultReset,
|
||||||
{
|
{
|
||||||
minHeight: 0,
|
minHeight: toRem(28),
|
||||||
padding: `${config.space.S100} ${config.space.S200}`,
|
padding: `0 ${config.space.S400}`,
|
||||||
width: 'auto',
|
width: '100%',
|
||||||
maxWidth: '100%',
|
backgroundColor: color.Surface.Container,
|
||||||
backgroundColor: 'transparent',
|
|
||||||
color: color.Surface.OnContainer,
|
color: color.Surface.OnContainer,
|
||||||
outline: 'none',
|
outline: 'none',
|
||||||
|
selectors: {
|
||||||
|
// Compact floating chip while the keyboard is open.
|
||||||
|
'[data-composer-flush="true"] &': {
|
||||||
|
minHeight: 0,
|
||||||
|
width: 'auto',
|
||||||
|
maxWidth: '100%',
|
||||||
|
padding: `${config.space.S100} ${config.space.S200}`,
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
variants: {
|
variants: {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { isCapacitorNative } from '../utils/tauri';
|
||||||
|
|
||||||
const KEYBOARD_HEIGHT_THRESHOLD_PX = 120;
|
const KEYBOARD_HEIGHT_THRESHOLD_PX = 120;
|
||||||
|
const IMMERSIVE_CLASS = 'immersive-landscape-keyboard';
|
||||||
|
|
||||||
const getIsLandscape = (): boolean => {
|
const getIsLandscape = (): boolean => {
|
||||||
if (typeof window === 'undefined') return false;
|
if (typeof window === 'undefined') return false;
|
||||||
@@ -24,9 +26,25 @@ const getKeyboardOpen = (): boolean => {
|
|||||||
return tag === 'INPUT' || tag === 'TEXTAREA';
|
return tag === 'INPUT' || tag === 'TEXTAREA';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setNativeStatusBarHidden = async (hidden: boolean) => {
|
||||||
|
if (!isCapacitorNative()) return;
|
||||||
|
try {
|
||||||
|
const { StatusBar } = await import('@capacitor/status-bar');
|
||||||
|
if (hidden) {
|
||||||
|
await StatusBar.hide();
|
||||||
|
} else {
|
||||||
|
await StatusBar.show();
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Plugin may be missing in some builds; CSS safe-area collapse still applies.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export type MobileKeyboardLayout = {
|
export type MobileKeyboardLayout = {
|
||||||
isLandscape: boolean;
|
isLandscape: boolean;
|
||||||
keyboardOpen: boolean;
|
keyboardOpen: boolean;
|
||||||
|
/** Landscape + keyboard: compact immersive room chrome. */
|
||||||
|
immersive: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,6 +55,8 @@ export const useMobileKeyboardLayout = (): MobileKeyboardLayout => {
|
|||||||
const [isLandscape, setIsLandscape] = useState(getIsLandscape);
|
const [isLandscape, setIsLandscape] = useState(getIsLandscape);
|
||||||
const [keyboardOpen, setKeyboardOpen] = useState(getKeyboardOpen);
|
const [keyboardOpen, setKeyboardOpen] = useState(getKeyboardOpen);
|
||||||
|
|
||||||
|
const immersive = isLandscape && keyboardOpen;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const sync = () => {
|
const sync = () => {
|
||||||
setIsLandscape(getIsLandscape());
|
setIsLandscape(getIsLandscape());
|
||||||
@@ -63,5 +83,15 @@ export const useMobileKeyboardLayout = (): MobileKeyboardLayout => {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return { isLandscape, keyboardOpen };
|
useEffect(() => {
|
||||||
|
document.documentElement.classList.toggle(IMMERSIVE_CLASS, immersive);
|
||||||
|
void setNativeStatusBarHidden(immersive);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.documentElement.classList.remove(IMMERSIVE_CLASS);
|
||||||
|
void setNativeStatusBarHidden(false);
|
||||||
|
};
|
||||||
|
}, [immersive]);
|
||||||
|
|
||||||
|
return { isLandscape, keyboardOpen, immersive };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ type ClientLayoutProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function ClientLayout({ nav, children }: ClientLayoutProps) {
|
export function ClientLayout({ nav, children }: ClientLayoutProps) {
|
||||||
const { keyboardOpen } = useMobileKeyboardLayout();
|
const { immersive } = useMobileKeyboardLayout();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box grow="Yes">
|
<Box grow="Yes">
|
||||||
{!keyboardOpen && <Box shrink="No">{nav}</Box>}
|
{!immersive && <Box shrink="No">{nav}</Box>}
|
||||||
<Box grow="Yes">{children}</Box>
|
<Box grow="Yes">{children}</Box>
|
||||||
<DockedCallPanel />
|
<DockedCallPanel />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ body {
|
|||||||
font-variant-ligatures: no-contextual;
|
font-variant-ligatures: no-contextual;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Landscape + keyboard: reclaim status-bar inset while chrome is hidden. */
|
||||||
|
html.immersive-landscape-keyboard {
|
||||||
|
--safe-area-inset-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Prevent zalgo text and combining diacritics from overflowing line boundaries */
|
/* Prevent zalgo text and combining diacritics from overflowing line boundaries */
|
||||||
p, span, div, a, button, li, td, th, h1, h2, h3, h4, h5, h6 {
|
p, span, div, a, button, li, td, th, h1, h2, h3, h4, h5, h6 {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
|||||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "paarrot",
|
"name": "paarrot",
|
||||||
"version": "4.11.77",
|
"version": "4.11.121",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "paarrot",
|
"name": "paarrot",
|
||||||
"version": "4.11.77",
|
"version": "4.11.121",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/android": "8.3.0",
|
"@capacitor/android": "8.3.0",
|
||||||
"@capacitor/cli": "8.3.0",
|
"@capacitor/cli": "8.3.0",
|
||||||
"@capacitor/core": "8.3.0",
|
"@capacitor/core": "8.3.0",
|
||||||
"@capacitor/local-notifications": "8.0.2"
|
"@capacitor/local-notifications": "8.0.2",
|
||||||
|
"@capacitor/status-bar": "8.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"node-fetch": "3.3.2",
|
"node-fetch": "3.3.2",
|
||||||
@@ -82,6 +83,15 @@
|
|||||||
"@capacitor/core": ">=8.0.0"
|
"@capacitor/core": ">=8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@capacitor/status-bar": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-OR59dlbwvmrV5dKsC9lvwv48QaGbqcbSTBpk+9/WXWxXYSdXXdzJZU9p8oyNPAkuJhCdnSa3XmU43fZRPBJJ5w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@capacitor/core": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@emnapi/runtime": {
|
"node_modules/@emnapi/runtime": {
|
||||||
"version": "1.8.1",
|
"version": "1.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "paarrot",
|
"name": "paarrot",
|
||||||
"version": "4.11.121",
|
"version": "4.11.123",
|
||||||
"description": "Paarrot - A Matrix client based on Cinny",
|
"description": "Paarrot - A Matrix client based on Cinny",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
@@ -25,7 +25,8 @@
|
|||||||
"@capacitor/android": "8.3.0",
|
"@capacitor/android": "8.3.0",
|
||||||
"@capacitor/cli": "8.3.0",
|
"@capacitor/cli": "8.3.0",
|
||||||
"@capacitor/core": "8.3.0",
|
"@capacitor/core": "8.3.0",
|
||||||
"@capacitor/local-notifications": "8.0.2"
|
"@capacitor/local-notifications": "8.0.2",
|
||||||
|
"@capacitor/status-bar": "8.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"node-fetch": "3.3.2",
|
"node-fetch": "3.3.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user