Skip to content
This repository was archived by the owner on Oct 30, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@
"noteToSelf": "Note to Self",
"hideMenuBarTitle": "Hide Menu Bar",
"hideMenuBarDescription": "Toggle system menu bar visibility",
"messageFormattingTitle": "Message Formatting (Experimental)",
"messageFormattingDescription": "Render messages using Markdown formatting",
"startConversation": "Start New Conversation",
"invalidNumberError": "Invalid Session ID or ONS Name",
"failedResolveOns": "Failed to resolve ONS name",
Expand Down
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@
"linkify-it": "3.0.2",
"lodash": "^4.17.20",
"long": "^4.0.0",
"markdown-it": "^13.0.1",
"markdown-it-abbr": "^1.0.4",
"markdown-it-container": "^3.0.0",
"markdown-it-footnote": "^3.0.3",
"markdown-it-highlightjs": "^4.0.1",
"markdown-it-ins": "^3.0.1",
"markdown-it-mark": "^3.0.1",
"markdown-it-sub": "^1.0.0",
"markdown-it-sup": "^1.0.0",
"mic-recorder-to-mp3": "^2.2.2",
"minimist": "^1.2.6",
"moment": "^2.29.4",
Expand Down
24 changes: 24 additions & 0 deletions stylesheets/_session.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,31 @@ input {
}

.module-message__text {

white-space: pre-wrap;

p {
display: inline-block;
margin-top: 0.4em;
margin-bottom: 0.25em;
}

ul, ol, blockquote {
margin-bottom: -0.5em;
white-space: normal;

p {
display: block !important;
}
}

pre {
margin-bottom: -0.5em;
}

* {
user-select: text;
}
}

.speedButton {
Expand Down
1 change: 1 addition & 0 deletions stylesheets/manifest.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@import '../node_modules/sanitize.css/sanitize.css';
@import '../node_modules/sanitize.css/forms.css';
@import '../node_modules/sanitize.css/typography.css';
@import '../node_modules/highlight.js/styles/stackoverflow-dark.css';

// Global Settings, Variables, and Mixins
@import 'session_constants';
Expand Down
47 changes: 44 additions & 3 deletions ts/components/conversation/message/message-content/MessageBody.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import LinkifyIt from 'linkify-it';

import MarkdownIt from 'markdown-it';
import { RenderTextCallbackType } from '../../../../types/Util';
import { getEmojiSizeClass, SizeClassType } from '../../../../util/emoji';
import { AddMentions } from '../../AddMentions';
Expand All @@ -12,6 +12,42 @@ import { showLinkVisitWarningDialog } from '../../../dialog/SessionConfirm';

const linkify = LinkifyIt();

const markdown = MarkdownIt('default', {
html: false,
linkify: true,
typographer: true,
// This seems not to work:
breaks: false
}
)
// tslint:disable:no-var-requires no-require-imports
.use(require('markdown-it-abbr'))
.use(require('markdown-it-sub'))
.use(require('markdown-it-sup'))
.use(require('markdown-it-ins'))
.use(require('markdown-it-mark'))
.use(require('markdown-it-container'), 'spoiler', {
validate: (params: string) => {
return params.trim().match(/^spoiler\s+(.*)$/);
},

render: (tokens: Array<any>, idx: number) => {
const m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/);

if (tokens[idx].nesting === 1) {
// opening tag
return `<details><summary>${markdown.utils.escapeHtml(m[1])}</summary>\n`;
} else {
// closing tag
return '</details>\n';
}
}
})
.use(require('markdown-it-footnote'))
.use(require('markdown-it-highlightjs'), { inline: true }
// tslint:enable:no-var-requires no-require-imports
);

type Props = {
text: string;
/** If set, all emoji will be the same size. Otherwise, just one emoji will be large. */
Expand Down Expand Up @@ -104,8 +140,13 @@ export const MessageBody = (props: Props) => {
);
}

if (text && text.startsWith('```') && text.endsWith('```') && text.length > 6) {
return <pre className="text-selectable">{text.substring(4, text.length - 3)}</pre>;
if (window.getSettingValue('message-formatting')) {
/* tslint:disable:react-no-dangerous-html */
return (
<div className="text-selectable"
dangerouslySetInnerHTML={{__html: `<span style="font-size: 1.1em;">${markdown.render(text).trim()}</span>`}}
/>
);
}

return JsxSelectable(
Expand Down
14 changes: 14 additions & 0 deletions ts/components/settings/section/CategoryAppearance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export const SettingsCategoryAppearance = (props: { hasPassword: boolean | null
? true
: window.getSettingValue(SettingsKey.settingsMenuBar);

const isMessageFormattingActive =
window.getSettingValue(SettingsKey.settingsMessageFormatting) === undefined
? false
: window.getSettingValue(SettingsKey.settingsMessageFormatting);

const isSpellCheckActive =
window.getSettingValue(SettingsKey.settingsSpellCheck) === undefined
? true
Expand All @@ -78,6 +83,15 @@ export const SettingsCategoryAppearance = (props: { hasPassword: boolean | null
active={isHideMenuBarActive}
/>
)}
<SessionToggleWithDescription
onClickToggle={() => {
window.toggleMessageFormatting();
forceUpdate();
}}
title={window.i18n('messageFormattingTitle')}
description={window.i18n('messageFormattingDescription')}
active={isMessageFormattingActive}
/>
<SessionToggleWithDescription
onClickToggle={() => {
window.toggleSpellCheck();
Expand Down
3 changes: 3 additions & 0 deletions ts/data/settings-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const settingsLinkPreview = 'link-preview-setting';
const settingsStartInTray = 'start-in-tray-setting';
const settingsOpengroupPruning = 'prune-setting';

const settingsMessageFormatting = 'message-formatting';

export const SettingsKey = {
settingsReadReceipt,
settingsTypingIndicator,
Expand All @@ -17,4 +19,5 @@ export const SettingsKey = {
settingsLinkPreview,
settingsStartInTray,
settingsOpengroupPruning,
settingsMessageFormatting
};
11 changes: 11 additions & 0 deletions ts/mains/main_renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ Storage.onready(async () => {
window.setMenuBarVisibility(!value);
},

getMessageFormatting: () => Storage.get('message-formatting', true),
setMessageFormatting: async (value: boolean) => {
await Storage.put('message-formatting', value);
},

getSpellCheck: () => Storage.get('spell-check', true),
setSpellCheck: async (value: boolean) => {
await Storage.put('spell-check', value);
Expand Down Expand Up @@ -303,6 +308,12 @@ async function start() {
window.Events.setHideMenuBar(!current);
};

window.toggleMessageFormatting = () => {
const currentValue = window.getSettingValue('message-formatting');
const newValue = currentValue !== undefined ? !currentValue : true;
window.Events.setMessageFormatting(newValue);
};

window.toggleSpellCheck = () => {
const currentValue = window.getSettingValue('spell-check');
// if undefined, it means 'default' so true. but we have to toggle it, so false
Expand Down
1 change: 1 addition & 0 deletions ts/markdown-it.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'markdown-it';
2 changes: 2 additions & 0 deletions ts/types/LocalizerKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export type LocalizerKeys =
| 'fileSizeWarning'
| 'openGroupURL'
| 'hideMenuBarDescription'
| 'messageFormattingDescription'
| 'pickClosedGroupMember'
| 'ByUsingThisService...'
| 'startConversation'
Expand Down Expand Up @@ -255,6 +256,7 @@ export type LocalizerKeys =
| 'editMenuDeleteContact'
| 'hideMenuBarTitle'
| 'reactionPopupOne'
| 'messageFormattingTitle'
| 'imageCaptionIconAlt'
| 'sendRecoveryPhraseTitle'
| 'multipleJoinedTheGroup'
Expand Down
3 changes: 3 additions & 0 deletions ts/util/accountManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ async function createAccount(identityKeyPair: SessionKeyPair) {
await Storage.put(SettingsKey.settingsOpengroupPruning, true);
await window.setOpengroupPruning(true);

// Disable message formatting by default.
await Storage.put(SettingsKey.settingsMessageFormatting, false);

await setLocalPubKey(pubKeyString);
}

Expand Down
1 change: 1 addition & 0 deletions ts/window.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ declare global {
toggleCallMediaPermissionsTo: (enabled: boolean) => Promise<void>;
getCallMediaPermissions: () => boolean;
toggleMenuBar: () => void;
toggleMessageFormatting: () => void;
toggleSpellCheck: any;
setTheme: (newTheme: string) => any;
isDev?: () => boolean;
Expand Down
74 changes: 72 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3877,7 +3877,7 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==

entities@^3.0.1:
entities@^3.0.1, entities@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
Expand Down Expand Up @@ -5154,6 +5154,11 @@ he@1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==

highlight.js@^11.5.1:
version "11.6.0"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.6.0.tgz#a50e9da05763f1bb0c1322c8f4f755242cff3f5a"
integrity sha512-ig1eqDzJaB0pqEvlPVIpSSyMaO92bH1N2rJpLMN/nX396wTpDA4Eq0uK+7I/2XG17pFaaKE0kjV/XPeGt7Evjw==

hmac-drbg@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
Expand Down Expand Up @@ -6047,6 +6052,13 @@ linkify-it@3.0.2:
dependencies:
uc.micro "^1.0.1"

linkify-it@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec"
integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==
dependencies:
uc.micro "^1.0.1"

livereload-js@^2.3.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.4.0.tgz#447c31cf1ea9ab52fc20db615c5ddf678f78009c"
Expand Down Expand Up @@ -6231,6 +6243,59 @@ map-cache@^0.2.0:
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=

markdown-it-abbr@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz#d66b5364521cbb3dd8aa59dadfba2fb6865c8fd8"
integrity sha512-ZeA4Z4SaBbYysZap5iZcxKmlPL6bYA8grqhzJIHB1ikn7njnzaP8uwbtuXc4YXD5LicI4/2Xmc0VwmSiFV04gg==

markdown-it-container@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-3.0.0.tgz#1d19b06040a020f9a827577bb7dbf67aa5de9a5b"
integrity sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==

markdown-it-footnote@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz#e0e4c0d67390a4c5f0c75f73be605c7c190ca4d8"
integrity sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w==

markdown-it-highlightjs@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/markdown-it-highlightjs/-/markdown-it-highlightjs-4.0.1.tgz#6b8eb6a3b971ed592db1ff160cfa5ce9f2e44232"
integrity sha512-EPXwFEN6P5nqR3G4KjT20r20xbGYKMMA/360hhSYFmeoGXTE6hsLtJAiB/8ID8slVH4CWHHEL7GX0YenyIstVQ==
dependencies:
highlight.js "^11.5.1"

markdown-it-ins@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/markdown-it-ins/-/markdown-it-ins-3.0.1.tgz#c09356b917cf1dbf73add0b275d67ab8c73d4b4d"
integrity sha512-32SSfZqSzqyAmmQ4SHvhxbFqSzPDqsZgMHDwxqPzp+v+t8RsmqsBZRG+RfRQskJko9PfKC2/oxyOs4Yg/CfiRw==

markdown-it-mark@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz#51257db58787d78aaf46dc13418d99a9f3f0ebd3"
integrity sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A==

markdown-it-sub@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz#375fd6026eae7ddcb012497f6411195ea1e3afe8"
integrity sha512-z2Rm/LzEE1wzwTSDrI+FlPEveAAbgdAdPhdWarq/ZGJrGW/uCQbKAnhoCsE4hAbc3SEym26+W2z/VQB0cQiA9Q==

markdown-it-sup@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz#cb9c9ff91a5255ac08f3fd3d63286e15df0a1fc3"
integrity sha512-E32m0nV9iyhRR7CrhnzL5msqic7rL1juWre6TQNxsnApg7Uf+F97JOKxUijg5YwXz86lZ0mqfOnutoryyNdntQ==

markdown-it@^13.0.1:
version "13.0.1"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430"
integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==
dependencies:
argparse "^2.0.1"
entities "~3.0.1"
linkify-it "^4.0.1"
mdurl "^1.0.1"
uc.micro "^1.0.5"

matcher@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
Expand All @@ -6252,6 +6317,11 @@ mdn-data@2.0.14:
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==

mdurl@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==

mem@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/mem/-/mem-5.1.1.tgz#7059b67bf9ac2c924c9f1cff7155a064394adfb3"
Expand Down Expand Up @@ -8856,7 +8926,7 @@ typescript@^4.6.3:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==

uc.micro@^1.0.1:
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
Expand Down