Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Add insert link button to the format bar #5879

Merged
merged 8 commits into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion res/css/views/rooms/_MessageComposerFormatBar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

.mx_MessageComposerFormatBar {
display: none;
width: calc(26px * 5);
width: calc(26px * 6);
height: 24px;
position: absolute;
cursor: pointer;
Expand Down Expand Up @@ -95,6 +95,10 @@ 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/room/format-bar/insert-link.svg');
}
}

.mx_MessageComposerFormatBar_buttonTooltip {
Expand Down
1 change: 1 addition & 0 deletions res/img/element-icons/room/format-bar/insert-link.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/components/views/rooms/BasicMessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
formatRangeAsCode,
toggleInlineFormat,
replaceRangeAndMoveCaret,
formatRangeAsLink,
} from '../../../editor/operations';
import { getCaretOffsetAndText, getRangeForSelection } from '../../../editor/dom';
import Autocomplete, { generateCompletionDomId } from '../rooms/Autocomplete';
Expand Down Expand Up @@ -644,6 +645,9 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
case Formatting.Quote:
formatRangeAsQuote(range);
break;
case Formatting.InsertLink:
formatRangeAsLink(range);
break;
}
};

Expand Down
2 changes: 2 additions & 0 deletions src/components/views/rooms/MessageComposerFormatBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export enum Formatting {
Strikethrough = "strikethrough",
Code = "code",
Quote = "quote",
InsertLink = "insert_link",
}

interface IProps {
Expand Down Expand Up @@ -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>);
}

Expand Down
13 changes: 11 additions & 2 deletions src/editor/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ export function replaceRangeAndExpandSelection(range: Range, newParts: Part[]) {
});
}

export function replaceRangeAndMoveCaret(range: Range, newParts: Part[]) {
export function replaceRangeAndMoveCaret(range: Range, newParts: Part[], offset?: number) {
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);
});
}
Expand Down Expand Up @@ -103,6 +103,15 @@ export function formatRangeAsCode(range: Range) {
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 === "newline";
Expand Down
1 change: 1 addition & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,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>)",
Expand Down