Add insert link button to the format bar (#5879)
This commit is contained in:
parent
75c7daa2c9
commit
ceb4c7e368
5 changed files with 24 additions and 3 deletions
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
.mx_MessageComposerFormatBar {
|
||||
display: none;
|
||||
width: calc(32px * 5);
|
||||
width: calc(32px * 6);
|
||||
height: 32px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
|
@ -87,6 +87,11 @@ limitations under the License.
|
|||
.mx_MessageComposerFormatBar_buttonIconCode::after {
|
||||
mask-image: url('$(res)/img/element-icons/room/format-bar/code.svg');
|
||||
}
|
||||
|
||||
.mx_MessageComposerFormatBar_buttonIconInsertLink::after {
|
||||
mask-image: url('$(res)/img/element-icons/link.svg');
|
||||
mask-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_MessageComposerFormatBar_buttonTooltip {
|
||||
|
|
|
@ -28,6 +28,7 @@ import {
|
|||
formatRangeAsCode,
|
||||
toggleInlineFormat,
|
||||
replaceRangeAndMoveCaret,
|
||||
formatRangeAsLink,
|
||||
} from '../../../editor/operations';
|
||||
import { getCaretOffsetAndText, getRangeForSelection } from '../../../editor/dom';
|
||||
import Autocomplete, { generateCompletionDomId } from '../rooms/Autocomplete';
|
||||
|
@ -706,6 +707,9 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
|
|||
case Formatting.Quote:
|
||||
formatRangeAsQuote(range);
|
||||
break;
|
||||
case Formatting.InsertLink:
|
||||
formatRangeAsLink(range);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ export enum Formatting {
|
|||
Strikethrough = "strikethrough",
|
||||
Code = "code",
|
||||
Quote = "quote",
|
||||
InsertLink = "insert_link",
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
|
@ -57,6 +58,7 @@ export default class MessageComposerFormatBar extends React.PureComponent<IProps
|
|||
<FormatButton label={_t("Strikethrough")} onClick={() => this.props.onAction(Formatting.Strikethrough)} icon="Strikethrough" visible={this.state.visible} />
|
||||
<FormatButton label={_t("Code block")} onClick={() => this.props.onAction(Formatting.Code)} icon="Code" visible={this.state.visible} />
|
||||
<FormatButton label={_t("Quote")} onClick={() => this.props.onAction(Formatting.Quote)} icon="Quote" shortcut={this.props.shortcuts.quote} visible={this.state.visible} />
|
||||
<FormatButton label={_t("Insert link")} onClick={() => this.props.onAction(Formatting.InsertLink)} icon="InsertLink" visible={this.state.visible} />
|
||||
</div>);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,13 +32,13 @@ export function replaceRangeAndExpandSelection(range: Range, newParts: Part[]):
|
|||
});
|
||||
}
|
||||
|
||||
export function replaceRangeAndMoveCaret(range: Range, newParts: Part[]): void {
|
||||
export function replaceRangeAndMoveCaret(range: Range, newParts: Part[], offset = 0): void {
|
||||
const { model } = range;
|
||||
model.transform(() => {
|
||||
const oldLen = range.length;
|
||||
const addedLen = range.replace(newParts);
|
||||
const firstOffset = range.start.asOffset(model);
|
||||
const lastOffset = firstOffset.add(oldLen + addedLen);
|
||||
const lastOffset = firstOffset.add(oldLen + addedLen + offset);
|
||||
return lastOffset.asPosition(model);
|
||||
});
|
||||
}
|
||||
|
@ -103,6 +103,15 @@ export function formatRangeAsCode(range: Range): void {
|
|||
replaceRangeAndExpandSelection(range, parts);
|
||||
}
|
||||
|
||||
export function formatRangeAsLink(range: Range) {
|
||||
const { model, parts } = range;
|
||||
const { partCreator } = model;
|
||||
parts.unshift(partCreator.plain("["));
|
||||
parts.push(partCreator.plain("]()"));
|
||||
// We set offset to -1 here so that the caret lands between the brackets
|
||||
replaceRangeAndMoveCaret(range, parts, -1);
|
||||
}
|
||||
|
||||
// parts helper methods
|
||||
const isBlank = part => !part.text || !/\S/.test(part.text);
|
||||
const isNL = part => part.type === Type.Newline;
|
||||
|
|
|
@ -1606,6 +1606,7 @@
|
|||
"Strikethrough": "Strikethrough",
|
||||
"Code block": "Code block",
|
||||
"Quote": "Quote",
|
||||
"Insert link": "Insert link",
|
||||
"Only the two of you are in this conversation, unless either of you invites anyone to join.": "Only the two of you are in this conversation, unless either of you invites anyone to join.",
|
||||
"This is the beginning of your direct message history with <displayName/>.": "This is the beginning of your direct message history with <displayName/>.",
|
||||
"Topic: %(topic)s (<a>edit</a>)": "Topic: %(topic)s (<a>edit</a>)",
|
||||
|
|
Loading…
Reference in a new issue