Open Find Channels with keyboard shortcut (#6260)

This commit is contained in:
Elias Nahum
2022-05-11 12:33:21 -04:00
committed by GitHub
parent e315fa6b4d
commit f62dcd42f7
8 changed files with 131 additions and 36 deletions

View File

@@ -43,10 +43,19 @@ public class MainActivity extends NavigationActivity {
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (HWKeyboardConnected && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
String keyPressed = event.isShiftPressed() ? "shift-enter" : "enter";
HWKeyboardEventModule.getInstance().keyPressed(keyPressed);
return true;
if (HWKeyboardConnected) {
int keyCode = event.getKeyCode();
int keyAction = event.getAction();
if (keyAction == KeyEvent.ACTION_UP) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
String keyPressed = event.isShiftPressed() ? "shift-enter" : "enter";
HWKeyboardEventModule.getInstance().keyPressed(keyPressed);
return true;
} else if (keyCode == KeyEvent.KEYCODE_K && event.isCtrlPressed()) {
HWKeyboardEventModule.getInstance().keyPressed("find-channels");
return true;
}
}
}
return super.dispatchKeyEvent(event);
};

View File

@@ -19,12 +19,11 @@ import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import useDidUpdate from '@hooks/did_update';
import {t} from '@i18n';
import EphemeralStore from '@store/ephemeral_store';
import {extractFileInfo} from '@utils/file';
import {switchKeyboardForCodeBlocks} from '@utils/markdown';
import {changeOpacity, makeStyleSheetFromTheme, getKeyboardAppearanceFromTheme} from '@utils/theme';
const HW_EVENT_IN_SCREEN = ['Channel', 'Thread'];
type Props = {
testID?: string;
channelDisplayName?: string;
@@ -220,7 +219,14 @@ export default function PostInput({
}, [addFiles, intl]);
const handleHardwareEnterPress = useCallback((keyEvent: {pressedKey: string}) => {
if (HW_EVENT_IN_SCREEN.includes(rootId ? Screens.THREAD : Screens.CHANNEL)) {
const topScreen = EphemeralStore.getNavigationTopComponentId();
let sourceScreen = Screens.CHANNEL;
if (rootId) {
sourceScreen = Screens.THREAD;
} else if (isTablet) {
sourceScreen = Screens.HOME;
}
if (topScreen === sourceScreen) {
switch (keyEvent.pressedKey) {
case 'enter':
sendMessage();
@@ -231,7 +237,7 @@ export default function PostInput({
break;
}
}
}, [sendMessage, updateValue, value, cursorPosition]);
}, [sendMessage, updateValue, value, cursorPosition, isTablet]);
const onAppStateChange = useCallback((appState: AppStateStatus) => {
if (appState !== 'active' && previousAppState.current === 'active') {
@@ -271,9 +277,9 @@ export default function PostInput({
}, [value]);
useEffect(() => {
HWKeyboardEvent.onHWKeyPressed(handleHardwareEnterPress);
const listener = HWKeyboardEvent.onHWKeyPressed(handleHardwareEnterPress);
return () => {
HWKeyboardEvent.removeOnHWKeyPressed();
listener.remove();
};
}, [handleHardwareEnterPress]);

View File

@@ -3,14 +3,12 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
import {DeviceEventEmitter, TouchableHighlight} from 'react-native';
import {Options} from 'react-native-navigation';
import {TouchableHighlight} from 'react-native';
import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
import {Events, Screens} from '@constants';
import {useTheme} from '@context/theme';
import {showModal} from '@screens/navigation';
import {findChannels} from '@screens/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
@@ -44,23 +42,9 @@ const SearchField = () => {
const styles = getStyleSheet(theme);
const onPress = useCallback(() => {
const options: Options = {modal: {swipeToDismiss: false}};
const closeButtonId = 'close-find-channels';
const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor);
options.topBar = {
leftButtons: [{
id: closeButtonId,
icon: closeButton,
testID: closeButtonId,
}],
};
DeviceEventEmitter.emit(Events.PAUSE_KEYBOARD_TRACKING_VIEW, true);
showModal(
Screens.FIND_CHANNELS,
findChannels(
intl.formatMessage({id: 'find_channels.title', defaultMessage: 'Find Channels'}),
{closeButtonId},
options,
theme,
);
}, [intl.locale, theme]);

View File

@@ -6,10 +6,13 @@ import {NavigationContainer} from '@react-navigation/native';
import React, {useEffect} from 'react';
import {useIntl} from 'react-intl';
import {DeviceEventEmitter, Platform} from 'react-native';
import HWKeyboardEvent from 'react-native-hw-keyboard-event';
import {enableFreeze, enableScreens} from 'react-native-screens';
import {Events, Screens} from '@constants';
import {useTheme} from '@context/theme';
import {findChannels} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {alertTeamRemove} from '@utils/navigation';
import {notificationError} from '@utils/notification';
@@ -46,7 +49,7 @@ export default function HomeScreen(props: HomeProps) {
return () => {
listener.remove();
};
}, []);
}, [intl.locale]);
useEffect(() => {
const listener = DeviceEventEmitter.addListener(Events.LEAVE_TEAM, (displayName: string) => {
@@ -56,7 +59,22 @@ export default function HomeScreen(props: HomeProps) {
return () => {
listener.remove();
};
});
}, [intl.locale]);
useEffect(() => {
const listener = HWKeyboardEvent.onHWKeyPressed((keyEvent: {pressedKey: string}) => {
const screen = EphemeralStore.getAllNavigationComponents();
if (!screen.includes(Screens.FIND_CHANNELS) && keyEvent.pressedKey === 'find-channels') {
findChannels(
intl.formatMessage({id: 'find_channels.title', defaultMessage: 'Find Channels'}),
theme,
);
}
});
return () => {
listener.remove();
};
}, [intl.locale]);
return (
<NavigationContainer

View File

@@ -688,3 +688,24 @@ export const showAppForm = async (form: AppForm, call: AppCallRequest) => {
const passProps = {form, call};
showModal(Screens.APP_FORM, form.title || '', passProps);
};
export async function findChannels(title: string, theme: Theme) {
const options: Options = {modal: {swipeToDismiss: false}};
const closeButtonId = 'close-find-channels';
const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor);
options.topBar = {
leftButtons: [{
id: closeButtonId,
icon: closeButton,
testID: closeButtonId,
}],
};
DeviceEventEmitter.emit(Events.PAUSE_KEYBOARD_TRACKING_VIEW, true);
showModal(
Screens.FIND_CHANNELS,
title,
{closeButtonId},
options,
);
}

View File

@@ -71,7 +71,15 @@ class EphemeralStore {
hasModalsOpened = () => this.navigationModalStack.length > 0;
private removeNavigationComponent = (componentId: string) => {
const index = this.allNavigationComponentIds.indexOf(componentId);
if (index >= 0) {
this.allNavigationComponentIds.splice(index, 1);
}
};
removeNavigationComponentId = (componentId: string) => {
this.removeNavigationComponent(componentId);
const index = this.navigationComponentIdStack.indexOf(componentId);
if (index >= 0) {
this.navigationComponentIdStack.splice(index, 1);
@@ -79,6 +87,7 @@ class EphemeralStore {
};
removeNavigationModal = (componentId: string) => {
this.removeNavigationComponent(componentId);
const index = this.navigationModalStack.indexOf(componentId);
if (index >= 0) {

View File

@@ -242,17 +242,24 @@ RNHWKeyboardEvent *hwKeyEvent = nil;
if ([hwKeyEvent isListening]) {
UIKeyCommand *enter = [UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:0 action:@selector(sendEnter:)];
UIKeyCommand *shiftEnter = [UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:UIKeyModifierShift action:@selector(sendShiftEnter:)];
UIKeyCommand *findChannels = [UIKeyCommand keyCommandWithInput:@"k" modifierFlags:UIKeyModifierCommand action:@selector(sendFindChannels:)];
if (@available(iOS 13.0, *)) {
[enter setTitle:@"Send message"];
[enter setDiscoverabilityTitle:@"Send message"];
[shiftEnter setTitle:@"Add new line"];
[shiftEnter setDiscoverabilityTitle:@"Add new line"];
[findChannels setTitle:@"Find channels"];
[findChannels setDiscoverabilityTitle:@"Find channels"];
}
if (@available(iOS 15.0, *)) {
[enter setWantsPriorityOverSystemBehavior:YES];
[shiftEnter setWantsPriorityOverSystemBehavior:YES];
[findChannels setWantsPriorityOverSystemBehavior:YES];
}
[commands addObject: enter];
[commands addObject: shiftEnter];
[commands addObject: findChannels];
}
return commands;
@@ -266,6 +273,10 @@ RNHWKeyboardEvent *hwKeyEvent = nil;
NSString *selected = sender.input;
[hwKeyEvent sendHWKeyEvent:@"shift-enter"];
}
- (void)sendFindChannels:(UIKeyCommand *)sender {
NSString *selected = sender.input;
[hwKeyEvent sendHWKeyEvent:@"find-channels"];
}
#if RCT_NEW_ARCH_ENABLED
#pragma mark - RCTCxxBridgeDelegate

View File

@@ -12,12 +12,49 @@ index a70aace..6443899 100644
versionCode 1
versionName "1.0"
diff --git a/node_modules/react-native-hw-keyboard-event/index.d.ts b/node_modules/react-native-hw-keyboard-event/index.d.ts
index 91999f1..53c7a42 100644
index 91999f1..116b725 100644
--- a/node_modules/react-native-hw-keyboard-event/index.d.ts
+++ b/node_modules/react-native-hw-keyboard-event/index.d.ts
@@ -1,4 +1,4 @@
@@ -1,4 +1,5 @@
+import {EventSubscription} from "react-native";
+
declare module "react-native-hw-keyboard-event";
-export function onHWKeyPressed(hwKeyEvent: { pressedKey: string }): void;
+export function onHWKeyPressed(callback: (hwKeyEvent: { pressedKey: string }) => void): void;
export function removeOnHWKeyPressed(): void;
-export function removeOnHWKeyPressed(): void;
+export function onHWKeyPressed(callback: (hwKeyEvent: { pressedKey: string }) => void): EventSubscription;
diff --git a/node_modules/react-native-hw-keyboard-event/index.js b/node_modules/react-native-hw-keyboard-event/index.js
index 30d4dd9..3dcff70 100644
--- a/node_modules/react-native-hw-keyboard-event/index.js
+++ b/node_modules/react-native-hw-keyboard-event/index.js
@@ -7,28 +7,9 @@ import {
class HWKeyboardEvent {
onHWKeyPressed(cb) {
- this.removeOnHWKeyPressed(true);
- if (!this.cbStack) {
- this.cbStack = [];
- }
- this.cbStack.push(cb);
let keyEvent = new NativeEventEmitter(NativeModules.RNHWKeyboardEvent);
- this.listener = keyEvent.addListener("onHWKeyPressed", cb);
- }
-
- removeOnHWKeyPressed(newCbAdded) {
- if (this.listener) {
- this.listener.remove();
- this.listener = null;
- }
- if (!this.cbStack) return;
- if (!newCbAdded) {
- this.cbStack.pop();
- if (this.cbStack.length > 0) {
- // re-add removed listeners in case there where any
- this.onHWKeyPressed(this.cbStack[this.cbStack.length - 1]);
- }
- }
+ const listener = keyEvent.addListener("onHWKeyPressed", cb);
+ return listener;
}
}