mattermost-mobile/app/constants/view.ts
Rahim Rahman 5887c3ab46
feat(MM-65625): floating banner (#9162)
* feat: implement floating banner system

- Add FloatingBanner component with gesture support and keyboard awareness
- Implement BannerManager singleton for banner lifecycle management
- Create floating banner screen with SafeAreaProvider integration
- Add comprehensive banner configuration types and positioning
- Update Banner component to use modern gesture handling
- Enhance BannerItem with improved typography and spacing (40px height)
- Add ConnectionBanner improvements with better sizing
- Remove ConnectionBanner from channel list (moved to floating system)
- Update screens constants (remove FLOATING_BANNER - handled as overlay)
- Add i18n support for limited network connection message

The system provides:
- Auto-hide functionality with customizable duration
- Position-aware rendering (top/bottom with keyboard adjustment)
- Tablet-specific offset handling
- Swipe-to-dismiss with configurable thresholds
- Custom component support alongside default banner items
- Comprehensive test coverage with device-specific scenarios

* docs: add floating banner system documentation and cleanup

- Add comprehensive floating-banner.md with architecture diagrams
- Remove incompatible connection_banner/index.ts file
- Update device.ts hooks for better keyboard handling
- Simplify screens/index.tsx floating banner registration
- Update test/setup.ts to remove deprecated keyboard mocks
- Clean up keyboard height logic and ESLint issues

The documentation covers:
- System architecture and component relationships
- API reference and usage patterns
- Performance considerations and best practices
- Integration points and troubleshooting guide
- Comprehensive testing strategy

All tests now pass with the updated setup.

* fix issue with translation file

* some self cleanup.

* renamed index.tsx => Banner.tsx

* creaete meaningful tests for Banner component and all the hooks.

* fix tests

* cleanup based on initial review by AI

* dismissible was set to true, changing to what was configured.

* making title and message optional

* addressed some comments in PR

* more fixes based on PR review.

* added future enhancement

* dismissOverlay will be awaited
* delay dismissing overlay so we don't have to show a new one all the time

* make the banner stackable

* Fix issue with last banner dismissal delayed by 2s

* update floating-banner test

* clean-up based on review by @enahum

* fix failing test

* fix failiing tests

* rename confusing var

* fixed issue with swipe not working on android

* fix issue w/ android not registering touch events behind the overlay

* fix failing test

* animate the banner moving up when bottom banner first appear.

* removed unused functions and update tests

* add useMemo and useCallback

* update jsdoc to say dismissable is default true

* fix failing test
2025-10-12 09:33:51 -06:00

68 lines
2.1 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Platform} from 'react-native';
export const BOTTOM_TAB_HEIGHT = 52;
export const BOTTOM_TAB_ICON_SIZE = 31.2;
export const BOTTOM_TAB_PROFILE_PHOTO_SIZE = 22;
export const BOTTOM_TAB_STATUS_SIZE = 12;
export const PROFILE_PICTURE_SIZE = 32;
export const PROFILE_PICTURE_EMOJI_SIZE = 28;
export const TEAM_SIDEBAR_WIDTH = 72;
export const TABLET_HEADER_HEIGHT = 44;
export const TABLET_SIDEBAR_WIDTH = 320;
export const STATUS_BAR_HEIGHT = 20;
export const DEFAULT_HEADER_HEIGHT = Platform.select({android: 56, default: 44});
export const LARGE_HEADER_TITLE_HEIGHT = 60;
export const SUBTITLE_HEIGHT = 24;
export const KEYBOARD_TRACKING_OFFSET = 72;
export const SEARCH_INPUT_HEIGHT = Platform.select({android: 40, default: 36});
export const SEARCH_INPUT_MARGIN = 5;
export const JOIN_CALL_BAR_HEIGHT = 40;
export const CURRENT_CALL_BAR_HEIGHT = 60;
export const CALL_ERROR_BAR_HEIGHT = 52;
export const CALL_NOTIFICATION_BAR_HEIGHT = 40;
export const ANNOUNCEMENT_BAR_HEIGHT = 40;
export const BOOKMARKS_BAR_HEIGHT = 48;
export const CHANNEL_BANNER_HEIGHT = 40;
export const FLOATING_BANNER_BOTTOM_OFFSET_PHONE_IOS = 121;
export const FLOATING_BANNER_BOTTOM_OFFSET_PHONE_ANDROID = 98;
export const FLOATING_BANNER_BOTTOM_OFFSET_WITH_KEYBOARD_IOS = 78;
export const FLOATING_BANNER_BOTTOM_OFFSET_WITH_KEYBOARD_ANDROID = 88;
export const FLOATING_BANNER_TABLET_EXTRA_BOTTOM_OFFSET = 68;
export const FLOATING_BANNER_STACK_SPACING = 60;
export const FLOATING_BANNER_EXTRA_OFFSET = 8;
export const BANNER_SPACING = 8;
export const HOME_PADDING = {
paddingLeft: 18,
paddingRight: 20,
};
export default {
BOTTOM_TAB_HEIGHT,
BOTTOM_TAB_ICON_SIZE,
PROFILE_PICTURE_SIZE,
PROFILE_PICTURE_EMOJI_SIZE,
DATA_SOURCE_USERS: 'users',
DATA_SOURCE_CHANNELS: 'channels',
DATA_SOURCE_DYNAMIC: 'dynamic',
SEARCH_INPUT_HEIGHT,
TABLET_SIDEBAR_WIDTH,
TEAM_SIDEBAR_WIDTH,
TABLET_HEADER_HEIGHT,
STATUS_BAR_HEIGHT,
DEFAULT_HEADER_HEIGHT,
LARGE_HEADER_TITLE_HEIGHT,
SUBTITLE_HEIGHT,
KEYBOARD_TRACKING_OFFSET,
};