mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-01 00:07:01 +00:00
fix: keep the notification prompt clear of the reader's bottom bar on tablets
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { View, Text, StyleSheet, Pressable, Animated, Easing } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useFloatingCardFrame } from '../lib/use-layout';
|
||||
import { useFloatingCardFrame, useLayout } from '../lib/use-layout';
|
||||
import { pushPromptBottom } from '../lib/push-prompt-frame';
|
||||
import { BellRing, X } from './icons';
|
||||
import Button from './Button';
|
||||
import { spacing, radius, typography, type ThemePalette } from '../theme/tokens';
|
||||
@@ -52,6 +53,8 @@ export function PushOnboardingPrompt(): React.ReactElement | null {
|
||||
const insets = useSafeAreaInsets();
|
||||
// Full width above the tab bar on a phone; bottom right on a tablet.
|
||||
const frame = useFloatingCardFrame();
|
||||
// Above the reading pane's bottom bar on a split view.
|
||||
const { isSplit } = useLayout();
|
||||
const duration = useAnimDuration(200);
|
||||
const appear = React.useRef(new Animated.Value(0)).current;
|
||||
|
||||
@@ -118,7 +121,7 @@ export function PushOnboardingPrompt(): React.ReactElement | null {
|
||||
style={[
|
||||
styles.wrap,
|
||||
{
|
||||
left: frame.left, right: frame.right, bottom: insets.bottom + frame.bottom,
|
||||
left: frame.left, right: frame.right, bottom: insets.bottom + pushPromptBottom(frame.bottom, isSplit),
|
||||
opacity: appear,
|
||||
transform: [{ translateY: appear.interpolate({ inputRange: [0, 1], outputRange: [24, 0] }) }],
|
||||
},
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { pushPromptBottom, READER_BAR_CLEARANCE } from '../push-prompt-frame';
|
||||
|
||||
// On a tablet split view the notification prompt sat in the bottom right
|
||||
// corner, over the reading pane's Prev / Reply / Forward bar, until it was
|
||||
// dismissed.
|
||||
|
||||
describe('push prompt placement', () => {
|
||||
it('sits above the reading pane bar on a split view', () => {
|
||||
expect(pushPromptBottom(20, true)).toBe(20 + READER_BAR_CLEARANCE);
|
||||
expect(READER_BAR_CLEARANCE).toBeGreaterThanOrEqual(64);
|
||||
});
|
||||
|
||||
it('keeps the toast placement above the tab bar on a phone', () => {
|
||||
expect(pushPromptBottom(64, false)).toBe(64);
|
||||
});
|
||||
|
||||
it('is what the prompt uses', () => {
|
||||
const src = fs.readFileSync(path.resolve(__dirname, '..', '..', 'components/PushOnboardingPrompt.tsx'), 'utf8');
|
||||
expect(src).toMatch(/bottom: insets\.bottom \+ pushPromptBottom\(frame\.bottom, isSplit\)/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
// Where the push notification prompt floats. It takes the toast placement
|
||||
// (lib/use-layout floatingCardFrame), but stays until it is answered: on a
|
||||
// tablet split view the bottom right corner is the reading pane's Prev /
|
||||
// Reply / Forward bar, which the card covered until it was dismissed. There
|
||||
// it sits above that bar.
|
||||
|
||||
/** The reader's bottom bar (EmailThreadScreen: 60 + at least 4 for the inset) and a gap. */
|
||||
export const READER_BAR_CLEARANCE = 64;
|
||||
|
||||
/** The prompt's distance from the bottom, before the safe-area inset. */
|
||||
export function pushPromptBottom(frameBottom: number, split: boolean): number {
|
||||
return split ? frameBottom + READER_BAR_CLEARANCE : frameBottom;
|
||||
}
|
||||
Reference in New Issue
Block a user