PC項(xiàng)目設(shè)置里允許用戶切換發(fā)送按鍵為Enter或Command+Enter; 因此在綁定自定義快捷鍵時难咕,需先根據(jù)settingStore的值去切換巧还,使用Draftjs前,通過onKeyDown事件去監(jiān)聽處理。Draftjs提供了prop屬性
keyBindingFn
和handleKeyCommand
目前只有對enter
和command/ctrl + enter
這兩種鍵盤的特殊處理。Draftjs已經(jīng)提供了handleReturn
方法監(jiān)聽enter事件:
handleReturn(e) {
e.preventDefault();
if (this.state.isMention) return 'handled';
if (!this.props.isSendWithCommand) {
this.props.onReturn();
} else {
// 換行
const changeLine = '\r\n';
this.appendContent(changeLine);
}
return 'handled';
}
在父組件中通過監(jiān)聽settingStore
现喳,獲取用戶設(shè)置的是否發(fā)送需要CommandOrControl+Enter
this.state.settings.sendMessage.shortcut == 'CommandOrControl+Enter'
在使用keyBindingFn自定義按鍵事件后,發(fā)現(xiàn)會與handleReturn沖突犬辰,將handleReturn里的處理邏輯并到自定義事件中:
// 鍵盤事件處理
keyBindingFn(e) {
const isMac = util.isMac();
if (isMac && hasCommandModifier(e) && e.keyCode === 13) {
console.log('cmd-enter');
return 'cmd-enter';
}
if (!isMac && isCtrlKeyCommand(e) && e.keyCode === 13) {
return 'cmd-enter';
}
if (isMac && !hasCommandModifier(e) && e.keyCode === 13) {
return 'just-enter';
}
if (!isMac && !isCtrlKeyCommand(e) && e.keyCode === 13) {
return 'just-enter';
}
return getDefaultKeyBinding(e);
}
handleKeyCommand(command) {
const changeLine = '\r\n';
if (command === 'cmd-enter') {
if (this.props.isSendWithCommand) {
this.props.onReturn();
} else {
this.appendContent(changeLine);
}
return 'handled';
}
if (command === 'just-enter') {
if (this.props.isSendWithCommand) {
this.appendContent(changeLine);
} else {
this.props.onReturn();
}
}
return 'not-handled';
}
完成自定義快捷鍵后嗦篱,因?yàn)槿コ薶andleReturn,似乎不再會與mention插件的enter選中事件沖突幌缝,去除之前用于監(jiān)聽mention列表是否展開的state: isMention
和相關(guān)操作;
后續(xù)開發(fā)中灸促,發(fā)現(xiàn)Draftjs提供的handlePastedFiles
方法也無法滿足業(yè)務(wù)需求,無法獲取非圖片類型..
于是涵卵,添加識別cmd+v
或ctrl+v
的自定義快捷鍵:
if (isMac && e.keyCode === 86 && (isCtrlKeyCommand(e) || hasCommandModifier(e))) {
return 'cmd-paste';
}
handleKeyCommand(command) {
.......
if (command === 'cmd-paste') {
console.log('cmd+v');
const image = clipboard.readImage();
if (!image.isEmpty()) {
const url = image.isEmpty()? '': image.toDataURL();
this.appendImage({
data: url,
});
} else {
const rawFilePath = clipboard.read('FileNameW');
let filePath = rawFilePath.replace(new RegExp(String.fromCharCode(0), 'g'), '');
if (util.isMac()) {
filePath = clipboard.read('public.file-url').replace('file://', '');
}
if (filePath) {
if (util.isMac() && clipboard.readText()) {
clipboard.clear();
}
console.log('filePath:', decodeURI(filePath));
// TODO, 文件組件
// this.props.sendFile({
// name: '',
// path: decodeURI(filePath),
// type: '',
// size: '',
// });
}
}
let text = clipboard.readText();
if (!!text) {
text = this.parseContentWithEmojiText(text);
this.appendContent(text, 'insert-characters');
}
return 'handled';
}
return 'not-handled';
}
目前對文件的粘貼直接做發(fā)送處理浴栽,后續(xù)添加DraftEditor中的自定義文件組件;