Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91a6916f4c | ||
|
|
78374d0301 | ||
|
|
9185ee0cf9 | ||
|
|
e2de51832c | ||
|
|
759f16d5b9 | ||
|
|
d0ddedc2b2 | ||
|
|
4291005161 | ||
|
|
ee144ccb2b | ||
|
|
7fea21f221 | ||
|
|
9a4b40f242 | ||
|
|
c2d353b973 | ||
|
|
8b6cecdbf8 | ||
|
|
83d8f2821a | ||
|
|
0225204b4d | ||
|
|
478957803d | ||
|
|
0181cb26d2 | ||
|
|
2ddb3595c7 | ||
|
|
76e49d1bd0 | ||
|
|
91f1ee748e | ||
|
|
9bddf64510 | ||
|
|
2200ae143e | ||
|
|
80d9a2ca7d | ||
|
|
cbd1bf35c6 | ||
|
|
c1be57b205 |
No files matched your search
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base"
|
||||
"config:base",
|
||||
":dependencyDashboardApproval"
|
||||
],
|
||||
"labels": [ "Dependencies" ],
|
||||
"packageRules": [
|
||||
@@ -10,6 +11,5 @@
|
||||
}
|
||||
],
|
||||
"lockFileMaintenance": { "enabled": true },
|
||||
"dependencyDashboard": true,
|
||||
"dependencyDashboardApproval": true
|
||||
"dependencyDashboard": true
|
||||
}
|
||||
+1
-1
@@ -41,4 +41,4 @@ Also, we use [ESLint](https://eslint.org/) for clean and stylistically consisten
|
||||
## Helpful links
|
||||
- [BEM methodology](http://getbem.com/introduction/)
|
||||
- [Atomic design](https://bradfrost.com/blog/post/atomic-web-design/)
|
||||
- [Matrix JavaScript SDK documentation](https://matrix-org.github.io/matrix-js-sdk/19.2.0/index.html)
|
||||
- [Matrix JavaScript SDK documentation](https://matrix-org.github.io/matrix-js-sdk/index.html)
|
||||
Generated
+332
-258
File diff suppressed because it is too large.
Load diff
+12
-12
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cinny",
|
||||
"version": "2.1.3",
|
||||
"version": "2.2.2",
|
||||
"description": "Yet another matrix client",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
@@ -17,7 +17,7 @@
|
||||
"dependencies": {
|
||||
"@fontsource/inter": "4.5.12",
|
||||
"@fontsource/roboto": "4.5.8",
|
||||
"@khanacademy/simple-markdown": "0.8.3",
|
||||
"@khanacademy/simple-markdown": "0.8.4",
|
||||
"@matrix-org/olm": "3.2.12",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
"babel-polyfill": "6.26.0",
|
||||
@@ -30,9 +30,9 @@
|
||||
"formik": "2.2.9",
|
||||
"html-react-parser": "3.0.4",
|
||||
"katex": "0.16.2",
|
||||
"linkify-html": "4.0.0-beta.5",
|
||||
"linkifyjs": "4.0.0-beta.5",
|
||||
"matrix-js-sdk": "19.5.0",
|
||||
"linkify-html": "4.0.0",
|
||||
"linkifyjs": "4.0.0",
|
||||
"matrix-js-sdk": "20.0.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.2",
|
||||
"react-autosize-textarea": "7.1.0",
|
||||
@@ -42,13 +42,13 @@
|
||||
"react-dom": "17.0.2",
|
||||
"react-google-recaptcha": "2.1.0",
|
||||
"react-modal": "3.15.1",
|
||||
"sanitize-html": "2.7.1",
|
||||
"sanitize-html": "2.7.2",
|
||||
"tippy.js": "6.3.7",
|
||||
"twemoji": "14.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.19.0",
|
||||
"@babel/preset-env": "7.19.0",
|
||||
"@babel/core": "7.19.1",
|
||||
"@babel/preset-env": "7.19.1",
|
||||
"@babel/preset-react": "7.18.6",
|
||||
"assert": "2.0.0",
|
||||
"babel-loader": "8.2.5",
|
||||
@@ -59,17 +59,17 @@
|
||||
"crypto-browserify": "3.12.0",
|
||||
"css-loader": "6.7.1",
|
||||
"css-minimizer-webpack-plugin": "4.1.0",
|
||||
"eslint": "8.23.1",
|
||||
"eslint": "8.24.0",
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
"eslint-plugin-react": "7.31.8",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"html-loader": "4.1.0",
|
||||
"html-loader": "4.2.0",
|
||||
"html-webpack-plugin": "5.5.0",
|
||||
"mini-css-extract-plugin": "2.6.1",
|
||||
"path-browserify": "1.0.1",
|
||||
"sass": "1.54.9",
|
||||
"sass": "1.55.0",
|
||||
"sass-loader": "13.0.2",
|
||||
"stream-browserify": "3.0.0",
|
||||
"style-loader": "3.3.1",
|
||||
@@ -77,7 +77,7 @@
|
||||
"util": "0.12.4",
|
||||
"webpack": "5.74.0",
|
||||
"webpack-cli": "4.10.0",
|
||||
"webpack-dev-server": "4.11.0",
|
||||
"webpack-dev-server": "4.11.1",
|
||||
"webpack-merge": "5.8.0"
|
||||
}
|
||||
}
|
||||
@@ -300,12 +300,12 @@ function MessageEdit({ body, onSave, onCancel }) {
|
||||
|
||||
if (e.key === 'Enter' && e.shiftKey === false) {
|
||||
e.preventDefault();
|
||||
onSave(editInputRef.current.value);
|
||||
onSave(editInputRef.current.value, body);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form className="message__edit" onSubmit={(e) => { e.preventDefault(); onSave(editInputRef.current.value); }}>
|
||||
<form className="message__edit" onSubmit={(e) => { e.preventDefault(); onSave(editInputRef.current.value, body); }}>
|
||||
<Input
|
||||
forwardRef={editInputRef}
|
||||
onKeyDown={handleKeyDown}
|
||||
@@ -806,8 +806,8 @@ function Message({
|
||||
body={(customHTML
|
||||
? html(customHTML, { kind: 'edit', onlyPlain: true }).plain
|
||||
: plain(body, { kind: 'edit', onlyPlain: true }).plain)}
|
||||
onSave={(newBody) => {
|
||||
if (newBody !== body) {
|
||||
onSave={(newBody, oldBody) => {
|
||||
if (newBody !== oldBody) {
|
||||
initMatrix.roomsInput.sendEditedMessage(roomId, mEvent, newBody);
|
||||
}
|
||||
cancelEdit();
|
||||
|
||||
@@ -25,7 +25,7 @@ function Home({ spaceId }) {
|
||||
let directIds = [];
|
||||
|
||||
if (spaceId) {
|
||||
const spaceChildIds = roomList.getSpaceChildren(spaceId);
|
||||
const spaceChildIds = roomList.getSpaceChildren(spaceId) ?? [];
|
||||
spaceIds = spaceChildIds.filter((roomId) => spaces.has(roomId));
|
||||
roomIds = spaceChildIds.filter((roomId) => rooms.has(roomId));
|
||||
directIds = spaceChildIds.filter((roomId) => directs.has(roomId));
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
toggleSystemTheme, toggleMarkdown, toggleMembershipEvents, toggleNickAvatarEvents,
|
||||
toggleNotifications, toggleNotificationSounds,
|
||||
} from '../../../client/action/settings';
|
||||
import logout from '../../../client/action/logout';
|
||||
import { usePermission } from '../../hooks/usePermission';
|
||||
|
||||
import Text from '../../atoms/text/Text';
|
||||
@@ -239,7 +238,7 @@ function AboutSection() {
|
||||
<div className="settings-about__btns">
|
||||
<Button onClick={() => window.open('https://github.com/ajbura/cinny')}>Source code</Button>
|
||||
<Button onClick={() => window.open('https://cinny.in/#sponsor')}>Support</Button>
|
||||
<Button onClick={() => settings.clearCacheAndReload()} variant="danger">Clear cache & reload</Button>
|
||||
<Button onClick={() => initMatrix.clearCacheAndReload()} variant="danger">Clear cache & reload</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -328,7 +327,7 @@ function Settings() {
|
||||
const handleTabChange = (tabItem) => setSelectedTab(tabItem);
|
||||
const handleLogout = async () => {
|
||||
if (await confirmDialog('Logout', 'Are you sure that you want to logout your session?', 'Logout', 'danger')) {
|
||||
logout();
|
||||
initMatrix.logout();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
& pre {
|
||||
padding: var(--sp-extra-tight);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
&__card {
|
||||
|
||||
@@ -7,18 +7,21 @@ import { initRoomListListener } from '../../../client/event/roomList';
|
||||
import Text from '../../atoms/text/Text';
|
||||
import Spinner from '../../atoms/spinner/Spinner';
|
||||
import Navigation from '../../organisms/navigation/Navigation';
|
||||
import ContextMenu, { MenuItem } from '../../atoms/context-menu/ContextMenu';
|
||||
import IconButton from '../../atoms/button/IconButton';
|
||||
import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu';
|
||||
import Room from '../../organisms/room/Room';
|
||||
import Windows from '../../organisms/pw/Windows';
|
||||
import Dialogs from '../../organisms/pw/Dialogs';
|
||||
import EmojiBoardOpener from '../../organisms/emoji-board/EmojiBoardOpener';
|
||||
import logout from '../../../client/action/logout';
|
||||
|
||||
import initMatrix from '../../../client/initMatrix';
|
||||
import navigation from '../../../client/state/navigation';
|
||||
import cons from '../../../client/state/cons';
|
||||
import DragDrop from '../../organisms/drag-drop/DragDrop';
|
||||
|
||||
import VerticalMenuIC from '../../../../public/res/ic/outlined/vertical-menu.svg';
|
||||
|
||||
function Client() {
|
||||
const [isLoading, changeLoading] = useState(true);
|
||||
const [loadingMsg, setLoadingMsg] = useState('Heating up');
|
||||
@@ -74,9 +77,20 @@ function Client() {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="loading-display">
|
||||
<button className="loading__logout" onClick={logout} type="button">
|
||||
<Text variant="b3">Logout</Text>
|
||||
</button>
|
||||
<div className="loading__menu">
|
||||
<ContextMenu
|
||||
placement="bottom"
|
||||
content={(
|
||||
<>
|
||||
<MenuItem onClick={() => initMatrix.clearCacheAndReload()}>
|
||||
Clear cache & reload
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => initMatrix.logout()}>Logout</MenuItem>
|
||||
</>
|
||||
)}
|
||||
render={(toggle) => <IconButton size="extra-small" onClick={toggle} src={VerticalMenuIC} />}
|
||||
/>
|
||||
</div>
|
||||
<Spinner />
|
||||
<Text className="loading__message" variant="b2">{loadingMsg}</Text>
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@
|
||||
position: absolute;
|
||||
bottom: var(--sp-normal);
|
||||
}
|
||||
.loading__logout {
|
||||
.loading__menu {
|
||||
position: absolute;
|
||||
bottom: var(--sp-extra-tight);
|
||||
top: var(--sp-extra-tight);
|
||||
right: var(--sp-extra-tight);
|
||||
cursor: pointer;
|
||||
.text {
|
||||
color: var(--tc-link);
|
||||
.context-menu__item .text {
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import initMatrix from '../initMatrix';
|
||||
|
||||
async function logout() {
|
||||
const mx = initMatrix.matrixClient;
|
||||
mx.stopClient();
|
||||
try {
|
||||
await mx.logout();
|
||||
} catch {
|
||||
// ignore if failed to logout
|
||||
}
|
||||
mx.clearStores();
|
||||
window.localStorage.clear();
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
export default logout;
|
||||
@@ -98,13 +98,32 @@ class InitMatrix extends EventEmitter {
|
||||
}
|
||||
|
||||
listenEvents() {
|
||||
this.matrixClient.on('Session.logged_out', () => {
|
||||
this.matrixClient.on('Session.logged_out', async () => {
|
||||
this.matrixClient.stopClient();
|
||||
this.matrixClient.clearStores();
|
||||
await this.matrixClient.clearStores();
|
||||
window.localStorage.clear();
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
|
||||
async logout() {
|
||||
this.matrixClient.stopClient();
|
||||
try {
|
||||
await this.matrixClient.logout();
|
||||
} catch {
|
||||
// ignore if failed to logout
|
||||
}
|
||||
await this.matrixClient.clearStores();
|
||||
window.localStorage.clear();
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
clearCacheAndReload() {
|
||||
this.matrixClient.stopClient();
|
||||
this.matrixClient.store.deleteAllData().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const initMatrix = new InitMatrix();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const cons = {
|
||||
version: '2.1.3',
|
||||
version: '2.2.2',
|
||||
secretKey: {
|
||||
ACCESS_TOKEN: 'cinny_access_token',
|
||||
DEVICE_ID: 'cinny_device_id',
|
||||
|
||||
@@ -147,14 +147,6 @@ class Settings extends EventEmitter {
|
||||
return settings.isNotificationSounds;
|
||||
}
|
||||
|
||||
clearCacheAndReload() {
|
||||
const mx = initMatrix.matrixClient;
|
||||
mx.stopClient()
|
||||
mx.store.deleteAllData().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
|
||||
setter(action) {
|
||||
const actions = {
|
||||
[cons.actions.settings.TOGGLE_SYSTEM_THEME]: () => {
|
||||
|
||||
+29
-13
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
/* eslint-disable no-use-before-define */
|
||||
import SimpleMarkdown from '@khanacademy/simple-markdown';
|
||||
import { idRegex, parseIdUri } from './common';
|
||||
@@ -88,6 +89,10 @@ const plainRules = {
|
||||
plain: (node, output, state) => `${output(node.content, state)}\n\n`,
|
||||
html: (node, output, state) => htmlTag('p', output(node.content, state)),
|
||||
},
|
||||
escape: {
|
||||
...defaultRules.escape,
|
||||
plain: (node, output, state) => `\\${output(node.content, state)}`,
|
||||
},
|
||||
br: {
|
||||
...defaultRules.br,
|
||||
match: anyScopeRegex(/^ *\n/),
|
||||
@@ -96,7 +101,9 @@ const plainRules = {
|
||||
text: {
|
||||
...defaultRules.text,
|
||||
match: anyScopeRegex(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]| *\n|\w+:\S|$)/),
|
||||
plain: (node) => node.content.replace(/(\*|_|!\[|\[|\|\||\$\$?)/g, '\\$1'),
|
||||
plain: (node, _, state) => (state.kind === 'edit'
|
||||
? node.content.replace(/(\*|_|!\[|\[|\|\||\$\$?)/g, '\\$1')
|
||||
: node.content),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -105,7 +112,7 @@ const markdownRules = {
|
||||
...plainRules,
|
||||
heading: {
|
||||
...defaultRules.heading,
|
||||
match: blockRegex(/^ *(#{1,6})([^\n:]*?(?: [^\n]*?)?)#* *(?:\n *)+\n/),
|
||||
match: blockRegex(/^ *(#{1,6})([^\n:]*?(?: [^\n]*?)?)#* *(?:\n *)*\n/),
|
||||
plain: (node, output, state) => {
|
||||
const out = output(node.content, state);
|
||||
if (state.kind === 'edit' || state.kind === 'notification' || node.level > 2) {
|
||||
@@ -120,7 +127,7 @@ const markdownRules = {
|
||||
},
|
||||
codeBlock: {
|
||||
...defaultRules.codeBlock,
|
||||
plain: (node) => `\`\`\`${node.lang || ''}\n${node.content}\n\`\`\``,
|
||||
plain: (node) => `\`\`\`${node.lang || ''}\n${node.content}\n\`\`\`\n`,
|
||||
html: (node) => htmlTag('pre', htmlTag('code', sanitizeText(node.content), {
|
||||
class: node.lang ? `language-${node.lang}` : undefined,
|
||||
})),
|
||||
@@ -135,10 +142,22 @@ const markdownRules = {
|
||||
},
|
||||
list: {
|
||||
...defaultRules.list,
|
||||
plain: (node, output, state) => `${node.items.map((item, i) => {
|
||||
const prefix = node.ordered ? `${node.start + i}. ` : '* ';
|
||||
return prefix + output(item, state).replace(/\n/g, `\n${' '.repeat(prefix.length)}`);
|
||||
}).join('\n')}\n`,
|
||||
plain: (node, output, state) => {
|
||||
const oldList = state._list;
|
||||
state._list = true;
|
||||
|
||||
let items = node.items.map((item, i) => {
|
||||
const prefix = node.ordered ? `${node.start + i}. ` : '* ';
|
||||
return prefix + output(item, state).replace(/\n/g, `\n${' '.repeat(prefix.length)}`);
|
||||
}).join('\n');
|
||||
|
||||
state._list = oldList;
|
||||
|
||||
if (!state._list) {
|
||||
items += '\n\n';
|
||||
}
|
||||
return items;
|
||||
},
|
||||
},
|
||||
def: undefined,
|
||||
table: {
|
||||
@@ -217,10 +236,6 @@ const markdownRules = {
|
||||
match: inlineRegex(/^¯\\_\(ツ\)_\/¯/),
|
||||
parse: (capture) => ({ type: 'text', content: capture[0] }),
|
||||
},
|
||||
escape: {
|
||||
...defaultRules.escape,
|
||||
plain: (node, output, state) => `\\${output(node.content, state)}`,
|
||||
},
|
||||
tableSeparator: {
|
||||
...defaultRules.tableSeparator,
|
||||
plain: () => ' | ',
|
||||
@@ -276,6 +291,7 @@ const markdownRules = {
|
||||
},
|
||||
inlineCode: {
|
||||
...defaultRules.inlineCode,
|
||||
match: inlineRegex(/^(`+)([^\n]*?[^`\n])\1(?!`)/),
|
||||
plain: (node) => `\`${node.content}\``,
|
||||
},
|
||||
spoiler: {
|
||||
@@ -347,13 +363,13 @@ function mapElement(el) {
|
||||
case 'BLOCKQUOTE':
|
||||
return [{ type: 'blockQuote', content: mapChildren(el) }];
|
||||
case 'UL':
|
||||
return [{ type: 'list', items: mapChildren(el) }];
|
||||
return [{ type: 'list', items: Array.from(el.childNodes).map(mapNode) }];
|
||||
case 'OL':
|
||||
return [{
|
||||
type: 'list',
|
||||
ordered: true,
|
||||
start: Number(el.getAttribute('start')),
|
||||
items: mapChildren(el),
|
||||
items: Array.from(el.childNodes).map(mapNode),
|
||||
}];
|
||||
case 'TABLE': {
|
||||
const headerEl = Array.from(el.querySelector('thead > tr').childNodes);
|
||||
|
||||
Reference in new issue
Block a user