Compare commits

..

10 Commits

Author SHA1 Message Date
Ajay Bura
0b70c7e490 v2.0.1 2022-05-13 16:39:54 +05:30
Ajay Bura
0539836714 Fix space and enter focus message field 2022-05-13 15:38:18 +05:30
Ash
c08b0e654b Add allowCustomHomeservers config option (#525)
* feat: Add allowCustomHomeservers config option

* fix: Do not lock the homeserver input when the selection is changed
2022-05-12 17:13:14 +05:30
Dean Bassett
b3cb48319a Add the ability to focus on paste (#545)
* pasting should focus the message field

also refactored a small amount to use KeyEvent.code
instead of KeyEvent.keyCode, which is deprecated.

fixes ajbura/cinny#544

* fix lint

* comments
2022-05-12 16:58:19 +05:30
Ajay Bura
44553cc375 Fix crash in room without create state event (#546) 2022-05-12 16:32:39 +05:30
Ajay Bura
fbe287a702 Fix message edit isn't reflected in reply #421 2022-05-12 13:45:23 +05:30
Ajay Bura
5863dcdf67 Fix join with alias (#533) 2022-05-11 20:56:49 +05:30
Ajay Bura
f77bee25ef Remove forget room on leave 2022-05-11 20:53:21 +05:30
Ajay Bura
c11328a064 Fix crash on leaving room (#532) 2022-05-11 20:25:54 +05:30
Ajay Bura
d04de2fba0 Add badges 2022-05-08 13:52:05 +05:30
11 changed files with 74 additions and 30 deletions

View File

@@ -1,5 +1,10 @@
# Cinny
[![Star](https://img.shields.io/github/stars/ajbura/cinny)](https://github.com/ajbura/cinny/tree/dev)
[![Chat](https://img.shields.io/badge/chat-on%20matrix-orange)](https://matrix.to/#/#cinny:matrix.org)
[![Twitter](https://img.shields.io/twitter/url?url=https://twitter.com/@cinnyapp)](https://twitter.com/@cinnyapp)
[![Support](https://img.shields.io/badge/sponsor-open%20collective-blue.svg)](https://opencollective.com/cinny)
## Table of Contents
- [About](#about)

View File

@@ -7,5 +7,6 @@
"kde.org",
"matrix.org",
"chat.mozilla.org"
]
],
"allowCustomHomeservers": true
}

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "cinny",
"version": "2.0.0",
"version": "2.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cinny",
"version": "2.0.0",
"version": "2.0.1",
"license": "MIT",
"dependencies": {
"@fontsource/inter": "^4.5.10",

View File

@@ -1,6 +1,6 @@
{
"name": "cinny",
"version": "2.0.0",
"version": "2.0.1",
"description": "Yet another matrix client",
"main": "index.js",
"engines": {

View File

@@ -123,17 +123,26 @@ const MessageReplyWrapper = React.memo(({ roomTimeline, eventId }) => {
const eTimeline = await mx.getEventTimeline(timelineSet, eventId);
await roomTimeline.decryptAllEventsOfTimeline(eTimeline);
const mEvent = eTimeline.getTimelineSet().findEventById(eventId);
let mEvent = eTimeline.getTimelineSet().findEventById(eventId);
const editedList = roomTimeline.editedTimeline.get(mEvent.getId());
if (editedList) {
mEvent = editedList[editedList.length - 1];
}
const rawBody = mEvent.getContent().body;
const username = getUsernameOfRoomMember(mEvent.sender);
if (isMountedRef.current === false) return;
const fallbackBody = mEvent.isRedacted() ? '*** This message has been deleted ***' : '*** Unable to load reply ***';
let parsedBody = parseReply(rawBody)?.body ?? rawBody ?? fallbackBody;
if (editedList && parsedBody.startsWith(' * ')) {
parsedBody = parsedBody.slice(3);
}
setReply({
to: username,
color: colorMXID(mEvent.getSender()),
body: parseReply(rawBody)?.body ?? rawBody ?? fallbackBody,
body: parsedBody,
event: mEvent,
});
} catch {

View File

@@ -70,7 +70,7 @@ function RoomVisibility({ roomId }) {
const noSpaceParent = currentState.getStateEvents('m.space.parent').length === 0;
const mCreate = currentState.getStateEvents('m.room.create')[0]?.getContent();
const roomVersion = Number(mCreate.room_version);
const roomVersion = Number(mCreate?.room_version ?? 0);
const myPowerlevel = room.getMember(mx.getUserId())?.powerLevel || 0;
const canChange = room.currentState.hasSufficientPowerLevelFor('state_default', myPowerlevel);

View File

@@ -63,7 +63,7 @@ function JoinAliasContent({ term, requestClose }) {
if (alias.startsWith('#')) {
try {
const aliasData = await mx.resolveRoomAlias(alias);
via = aliasData?.servers || [];
via = aliasData?.servers.slice(0, 3) || [];
if (mountStore.getItem()) {
setProcess(`Joining ${alias}...`);
}

View File

@@ -93,12 +93,13 @@ function Homeserver({ onChange }) {
const result = await (await fetch(configFileUrl, { method: 'GET' })).json();
const selectedHs = result?.defaultHomeserver;
const hsList = result?.homeserverList;
const allowCustom = result?.allowCustomHomeservers ?? true;
if (!hsList?.length > 0 || selectedHs < 0 || selectedHs >= hsList?.length) {
throw new Error();
}
setHs({ selected: hsList[selectedHs], list: hsList });
setHs({ selected: hsList[selectedHs], list: hsList, allowCustom: allowCustom });
} catch {
setHs({ selected: 'matrix.org', list: ['matrix.org'] });
setHs({ selected: 'matrix.org', list: ['matrix.org'], allowCustom: true });
}
}, []);
@@ -106,14 +107,15 @@ function Homeserver({ onChange }) {
const { value } = e.target;
setProcess({ isLoading: false });
debounce._(async () => {
setHs({ selected: value.trim(), list: hs.list });
setHs({ ...hs, selected: value.trim() });
}, 700)();
};
return (
<>
<div className="homeserver-form">
<Input name="homeserver" onChange={handleHsInput} value={hs?.selected} forwardRef={hsRef} label="Homeserver" />
<Input name="homeserver" onChange={handleHsInput} value={hs?.selected} forwardRef={hsRef} label="Homeserver"
disabled={hs === null || !hs.allowCustom} />
<ContextMenu
placement="right"
content={(hideMenu) => (
@@ -126,7 +128,7 @@ function Homeserver({ onChange }) {
onClick={() => {
hideMenu();
hsRef.current.value = hsName;
setHs({ selected: hsName, list: hs.list });
setHs({ ...hs, selected: hsName });
}}
>
{hsName}

View File

@@ -118,7 +118,6 @@ async function leave(roomId) {
const isDM = initMatrix.roomList.directs.has(roomId);
try {
await mx.leave(roomId);
await mx.forget(roomId);
appDispatcher.dispatch({
type: cons.actions.room.LEAVE,
roomId,

View File

@@ -2,25 +2,57 @@ import { openSearch, toggleRoomSettings } from '../action/navigation';
import navigation from '../state/navigation';
import { markAsRead } from '../action/notifications';
function shouldFocusMessageField(code) {
// do not focus on F keys
if (/^F\d+$/.test(code)) return false;
// do not focus on numlock/scroll lock
if (
code.metaKey
|| code.startsWith('OS')
|| code.startsWith('Meta')
|| code.startsWith('Shift')
|| code.startsWith('Alt')
|| code.startsWith('Control')
|| code.startsWith('Arrow')
|| code === 'Tab'
|| code === 'Space'
|| code === 'Enter'
|| code === 'NumLock'
|| code === 'ScrollLock'
) {
return false;
}
return true;
}
function listenKeyboard(event) {
// Ctrl/Cmd +
if (event.ctrlKey || event.metaKey) {
// k - for search Modal
if (event.keyCode === 75) {
// open search modal
if (event.code === 'KeyK') {
event.preventDefault();
if (navigation.isRawModalVisible) return;
if (navigation.isRawModalVisible) {
return;
}
openSearch();
}
// focus message field on paste
if (event.code === 'KeyV') {
const msgTextarea = document.getElementById('message-textarea');
msgTextarea?.focus();
}
}
if (!event.ctrlKey && !event.altKey) {
if (!event.ctrlKey && !event.altKey && !event.metaKey) {
if (navigation.isRawModalVisible) return;
if (['text', 'textarea'].includes(document.activeElement.type)) {
return;
}
// esc
if (event.keyCode === 27) {
if (event.code === 'Escape') {
if (navigation.isRoomSettings) {
toggleRoomSettings();
return;
@@ -31,16 +63,12 @@ function listenKeyboard(event) {
}
}
// Don't allow these keys to type/focus message field
if ((event.keyCode !== 8 && event.keyCode < 48)
|| (event.keyCode >= 91 && event.keyCode <= 93)
|| (event.keyCode >= 112 && event.keyCode <= 183)) {
return;
// focus the text field on most keypresses
if (shouldFocusMessageField(event.code)) {
// press any key to focus and type in message field
const msgTextarea = document.getElementById('message-textarea');
msgTextarea?.focus();
}
// press any key to focus and type in message field
const msgTextarea = document.getElementById('message-textarea');
msgTextarea?.focus();
}
}

View File

@@ -1,5 +1,5 @@
const cons = {
version: '2.0.0',
version: '2.0.1',
secretKey: {
ACCESS_TOKEN: 'cinny_access_token',
DEVICE_ID: 'cinny_device_id',