Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69b6055353 | ||
|
|
1bdd0449e0 | ||
|
|
a6fdf9010b | ||
|
|
941dae0625 | ||
|
|
4a715bfd17 | ||
|
|
0b70c7e490 | ||
|
|
0539836714 | ||
|
|
c08b0e654b | ||
|
|
b3cb48319a | ||
|
|
44553cc375 | ||
|
|
fbe287a702 | ||
|
|
5863dcdf67 | ||
|
|
f77bee25ef | ||
|
|
c11328a064 | ||
|
|
d04de2fba0 |
@@ -1,5 +1,10 @@
|
||||
# Cinny
|
||||
|
||||
[](https://github.com/ajbura/cinny/tree/dev)
|
||||
[](https://matrix.to/#/#cinny:matrix.org)
|
||||
[](https://twitter.com/@cinnyapp)
|
||||
[](https://opencollective.com/cinny)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [About](#about)
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"kde.org",
|
||||
"matrix.org",
|
||||
"chat.mozilla.org"
|
||||
]
|
||||
],
|
||||
"allowCustomHomeservers": true
|
||||
}
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "cinny",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cinny",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fontsource/inter": "^4.5.10",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cinny",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.3",
|
||||
"description": "Yet another matrix client",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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}...`);
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,25 +2,60 @@ 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;
|
||||
openSearch();
|
||||
}
|
||||
|
||||
// focus message field on paste
|
||||
if (event.code === 'KeyV') {
|
||||
if (navigation.isRawModalVisible) return;
|
||||
const msgTextarea = document.getElementById('message-textarea');
|
||||
const { activeElement } = document;
|
||||
if (activeElement !== msgTextarea
|
||||
&& ['input', 'textarea'].includes(activeElement.tagName.toLowerCase())
|
||||
) return;
|
||||
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)) {
|
||||
if (['input', 'textarea'].includes(document.activeElement.tagName.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// esc
|
||||
if (event.keyCode === 27) {
|
||||
if (event.code === 'Escape') {
|
||||
if (navigation.isRoomSettings) {
|
||||
toggleRoomSettings();
|
||||
return;
|
||||
@@ -31,16 +66,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const cons = {
|
||||
version: '2.0.0',
|
||||
version: '2.0.3',
|
||||
secretKey: {
|
||||
ACCESS_TOKEN: 'cinny_access_token',
|
||||
DEVICE_ID: 'cinny_device_id',
|
||||
|
||||
@@ -14,7 +14,7 @@ class Navigation extends EventEmitter {
|
||||
this.isRoomSettings = false;
|
||||
this.recentRooms = [];
|
||||
|
||||
this.isRawModalVisible = false;
|
||||
this.rawModelStack = [];
|
||||
}
|
||||
|
||||
_setSpacePath(roomId) {
|
||||
@@ -47,8 +47,13 @@ class Navigation extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
get isRawModalVisible() {
|
||||
return this.rawModelStack.length > 0;
|
||||
}
|
||||
|
||||
setIsRawModalVisible(visible) {
|
||||
this.isRawModalVisible = visible;
|
||||
if (visible) this.rawModelStack.push(true);
|
||||
else this.rawModelStack.pop();
|
||||
}
|
||||
|
||||
navigate(action) {
|
||||
|
||||
Reference in New Issue
Block a user