merge: upstream cinny v4.12.7 into lotus
Brings the 4.12.7 fixes: "%" sign wrapping below the composer input and
emoji autocompletion overwriting the preceding element. The release's
security half (sanitize-html, react-router-dom) was already applied in
91def3ad (we are on newer versions than upstream ships).
Resolved: kept our package.json/lockfile (the fork is ahead on every
dependency — React 19, router 7, i18next 26…), version 4.12.7-lotus, our
README/CONTRIBUTING, our "Lotus Chat vN" branding via pkg.version, and
the deleted GitHub-only workflows stay deleted. Note upstream announces
it is replacing matrix-js-sdk with its own SDK and pausing PRs; future
syncs will get harder.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -57,7 +57,7 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Environement
|
label: Environment
|
||||||
description: |
|
description: |
|
||||||
Please provide information about your environment. Include the following:
|
Please provide information about your environment. Include the following:
|
||||||
- OS:
|
- OS:
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
### Description
|
||||||
|
|
||||||
|
<!-- Please include a summary of the change. -->
|
||||||
|
|
||||||
|
Fixes #
|
||||||
|
|
||||||
|
### Checklist:
|
||||||
|
|
||||||
|
- [ ] I have read and understood the [Contribution policy](https://github.com/ajbura/cinny/blob/dev/CONTRIBUTING.md).
|
||||||
+1
-2
@@ -2,5 +2,4 @@ dist
|
|||||||
node_modules
|
node_modules
|
||||||
package.json
|
package.json
|
||||||
package-lock.json
|
package-lock.json
|
||||||
LICENSE
|
LICENSE
|
||||||
README.md
|
|
||||||
+1
-1
@@ -11,7 +11,7 @@ RUN npm run build
|
|||||||
|
|
||||||
|
|
||||||
## App
|
## App
|
||||||
FROM nginx:1.29.8-alpine
|
FROM nginx:1.31.5-alpine
|
||||||
|
|
||||||
COPY --from=builder /src/dist /app
|
COPY --from=builder /src/dist /app
|
||||||
COPY --from=builder /src/docker-nginx.conf /etc/nginx/conf.d/default.conf
|
COPY --from=builder /src/docker-nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
# Developing Cinny
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> We recommend using a version manager as versions change very quickly.
|
||||||
|
> You will likely need to switch between multiple Node.js versions based
|
||||||
|
> on the needs of different projects you're working on. [NVM-windows]
|
||||||
|
> on Windows and [nvm] on Linux/macOS are pretty good choices. Recommended
|
||||||
|
> nodejs version is Krypton LTS (v24.13.1).
|
||||||
|
|
||||||
|
[nvm-windows]: https://github.com/coreybutler/nvm-windows#installation--upgrades
|
||||||
|
[nvm]: https://github.com/nvm-sh/nvm
|
||||||
|
|
||||||
|
Execute the following commands to start a development server:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm ci # Installs all dependencies
|
||||||
|
npm start # Serve a development version
|
||||||
|
```
|
||||||
|
|
||||||
|
To build the app:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run build # Compiles the app into the dist/ directory
|
||||||
|
```
|
||||||
|
|
||||||
|
To commit changes:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run commit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running with Docker
|
||||||
|
|
||||||
|
This repository includes a Dockerfile, which builds the application from
|
||||||
|
source and serves it with Nginx on port 80. To use this locally, you can
|
||||||
|
build the container like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker build -t cinny:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then run the container you've built with a command similar to this:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -p 8080:80 cinny:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
This will forward your `localhost` port 8080 to the container's port 80.
|
||||||
|
You can visit the app in your browser by navigating to `http://localhost:8080`.
|
||||||
|
|
||||||
|
## Code formatting
|
||||||
|
|
||||||
|
We use [ESLint](https://eslint.org/) for clean and stylistically
|
||||||
|
consistent code syntax, so make sure your pull request follow it.
|
||||||
|
|
||||||
|
## 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/index.html)
|
||||||
@@ -129,12 +129,12 @@ Lotus Chat has a desktop app for Windows, macOS, and Linux. It wraps the same we
|
|||||||
|
|
||||||
### Download
|
### Download
|
||||||
|
|
||||||
Operating System | Download
|
| Operating System | Download |
|
||||||
---|---
|
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
Windows | [Get the installer (.exe)](https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64-setup.exe)
|
| Windows | [Get the installer (.exe)](https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64-setup.exe) |
|
||||||
Linux (AppImage, any distro) | [Get the AppImage](https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64.AppImage)
|
| Linux (AppImage, any distro) | [Get the AppImage](https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64.AppImage) |
|
||||||
Linux (Debian/Ubuntu) | [Get the .deb](https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64.deb)
|
| Linux (Debian/Ubuntu) | [Get the .deb](https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64.deb) |
|
||||||
Linux (Arch/CachyOS/EndeavourOS) | [Get the .pkg.tar.zst](https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64.pkg.tar.zst) — install with `pacman -U LotusChat-x86_64.pkg.tar.zst`
|
| Linux (Arch/CachyOS/EndeavourOS) | [Get the .pkg.tar.zst](https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64.pkg.tar.zst) — install with `pacman -U LotusChat-x86_64.pkg.tar.zst` |
|
||||||
|
|
||||||
All Linux builds need `webkit2gtk-4.1` and, for calls to work, GStreamer's `good`/`bad`/`ugly`/`libav` plugin sets (the pacman package pulls these in automatically; on the AppImage/.deb, install them via your package manager if joining a call shows "browser does not support WebRTC").
|
All Linux builds need `webkit2gtk-4.1` and, for calls to work, GStreamer's `good`/`bad`/`ugly`/`libav` plugin sets (the pacman package pulls these in automatically; on the AppImage/.deb, install them via your package manager if joining a call shows "browser does not support WebRTC").
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
## Insert wasm type into nginx mime.types file so they load correctly.
|
## Insert wasm type into nginx mime.types file so they load correctly.
|
||||||
|
|
||||||
`/etc/nginx/mime.types`:
|
`/etc/nginx/mime.types`:
|
||||||
|
|
||||||
```
|
```
|
||||||
types {
|
types {
|
||||||
..
|
..
|
||||||
|
|||||||
+13
-9
@@ -39,6 +39,7 @@ services:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 1a. MAS `config.yaml` — the parts that matter
|
### 1a. MAS `config.yaml` — the parts that matter
|
||||||
|
|
||||||
After `config generate` (which fills in `secrets.keys` + `encryption`), set:
|
After `config generate` (which fills in `secrets.keys` + `encryption`), set:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -48,18 +49,19 @@ http:
|
|||||||
database:
|
database:
|
||||||
uri: postgresql://synapse:pw@postgres/synapse
|
uri: postgresql://synapse:pw@postgres/synapse
|
||||||
matrix:
|
matrix:
|
||||||
homeserver: localhost # the server_name
|
homeserver: localhost # the server_name
|
||||||
endpoint: http://synapse:8008/
|
endpoint: http://synapse:8008/
|
||||||
secret: "REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN"
|
secret: 'REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN'
|
||||||
clients:
|
clients:
|
||||||
- client_id: "0000000000000000000SYNAPSE"
|
- client_id: '0000000000000000000SYNAPSE'
|
||||||
client_auth_method: client_secret_basic
|
client_auth_method: client_secret_basic
|
||||||
client_secret: "REPLACE_WITH_A_SHARED_CLIENT_SECRET"
|
client_secret: 'REPLACE_WITH_A_SHARED_CLIENT_SECRET'
|
||||||
passwords: # so you can create a local test account in the MAS UI
|
passwords: # so you can create a local test account in the MAS UI
|
||||||
enabled: true
|
enabled: true
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1b. Synapse `homeserver.yaml` — delegate auth to MAS
|
### 1b. Synapse `homeserver.yaml` — delegate auth to MAS
|
||||||
|
|
||||||
See `synapse-msc3861.yaml` in this folder; the key block is:
|
See `synapse-msc3861.yaml` in this folder; the key block is:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -67,17 +69,18 @@ experimental_features:
|
|||||||
msc3861:
|
msc3861:
|
||||||
enabled: true
|
enabled: true
|
||||||
issuer: http://localhost:8090/
|
issuer: http://localhost:8090/
|
||||||
client_id: "0000000000000000000SYNAPSE"
|
client_id: '0000000000000000000SYNAPSE'
|
||||||
client_auth_method: client_secret_basic
|
client_auth_method: client_secret_basic
|
||||||
client_secret: "REPLACE_WITH_A_SHARED_CLIENT_SECRET" # == MAS clients[].client_secret
|
client_secret: 'REPLACE_WITH_A_SHARED_CLIENT_SECRET' # == MAS clients[].client_secret
|
||||||
admin_token: "REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN" # == MAS matrix.secret
|
admin_token: 'REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN' # == MAS matrix.secret
|
||||||
account_management_url: "http://localhost:8090/account"
|
account_management_url: 'http://localhost:8090/account'
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a test user via the MAS UI (`http://localhost:8090/`) or
|
Create a test user via the MAS UI (`http://localhost:8090/`) or
|
||||||
`docker compose exec mas mas-cli manage register-user`.
|
`docker compose exec mas mas-cli manage register-user`.
|
||||||
|
|
||||||
Sanity check discovery (the client relies on this):
|
Sanity check discovery (the client relies on this):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -s http://localhost:8008/.well-known/matrix/client | jq '."m.authentication"'
|
curl -s http://localhost:8008/.well-known/matrix/client | jq '."m.authentication"'
|
||||||
# -> { "issuer": "http://localhost:8090/", "account": "http://localhost:8090/account" }
|
# -> { "issuer": "http://localhost:8090/", "account": "http://localhost:8090/account" }
|
||||||
@@ -108,5 +111,6 @@ See **section N** of `../../LOTUS_TESTING.md` for the actual pass/fail steps
|
|||||||
revocation, account-management link, and the non-OIDC-regression check).
|
revocation, account-management link, and the non-OIDC-regression check).
|
||||||
|
|
||||||
## Files here
|
## Files here
|
||||||
|
|
||||||
- `synapse-msc3861.yaml` — the Synapse experimental-features delta.
|
- `synapse-msc3861.yaml` — the Synapse experimental-features delta.
|
||||||
- `config.local.json` — the Lotus `public/config.json` override.
|
- `config.local.json` — the Lotus `public/config.json` override.
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "lotus-chat",
|
"name": "lotus-chat",
|
||||||
"version": "4.12.3-lotus",
|
"version": "4.12.7-lotus",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "lotus-chat",
|
"name": "lotus-chat",
|
||||||
"version": "4.12.3-lotus",
|
"version": "4.12.7-lotus",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lotus-chat",
|
"name": "lotus-chat",
|
||||||
"version": "4.12.3-lotus",
|
"version": "4.12.7-lotus",
|
||||||
"description": "Lotus Chat — Matrix client for Lotus Guild",
|
"description": "Lotus Chat — Matrix client for Lotus Guild",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -268,15 +268,15 @@ export const getPointUntilChar = (
|
|||||||
return targetPoint;
|
return targetPoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getPrevWorldRange = (editor: Editor): BaseRange | undefined => {
|
export const getPrevWordRange = (editor: Editor): BaseRange | undefined => {
|
||||||
const { selection } = editor;
|
const { selection } = editor;
|
||||||
if (!selection || !Range.isCollapsed(selection)) return undefined;
|
if (!selection || !Range.isCollapsed(selection)) return undefined;
|
||||||
const [cursorPoint] = Range.edges(selection);
|
const [cursorPoint] = Range.edges(selection);
|
||||||
const worldStartPoint = getPointUntilChar(editor, cursorPoint, {
|
const wordStartPoint = getPointUntilChar(editor, cursorPoint, {
|
||||||
reverse: true,
|
reverse: true,
|
||||||
match: (char) => char === ' ',
|
match: (char) => char === ' ' || char === '',
|
||||||
});
|
});
|
||||||
return worldStartPoint && Editor.range(editor, worldStartPoint, cursorPoint);
|
return wordStartPoint && Editor.range(editor, wordStartPoint, cursorPoint);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isEmptyEditor = (editor: Editor): boolean => {
|
export const isEmptyEditor = (editor: Editor): boolean => {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import {
|
|||||||
AutocompletePrefix,
|
AutocompletePrefix,
|
||||||
AutocompleteQuery,
|
AutocompleteQuery,
|
||||||
getAutocompleteQuery,
|
getAutocompleteQuery,
|
||||||
getPrevWorldRange,
|
getPrevWordRange,
|
||||||
resetEditor,
|
resetEditor,
|
||||||
RoomMentionAutocomplete,
|
RoomMentionAutocomplete,
|
||||||
UserMentionAutocomplete,
|
UserMentionAutocomplete,
|
||||||
@@ -806,7 +806,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
|||||||
sendTypingStatus(!isEmptyEditor(editor));
|
sendTypingStatus(!isEmptyEditor(editor));
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevWordRange = getPrevWorldRange(editor);
|
const prevWordRange = getPrevWordRange(editor);
|
||||||
const query = prevWordRange
|
const query = prevWordRange
|
||||||
? getAutocompleteQuery<AutocompletePrefix>(editor, prevWordRange, AUTOCOMPLETE_PREFIXES)
|
? getAutocompleteQuery<AutocompletePrefix>(editor, prevWordRange, AUTOCOMPLETE_PREFIXES)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import {
|
|||||||
createEmoticonElement,
|
createEmoticonElement,
|
||||||
customHtmlEqualsPlainText,
|
customHtmlEqualsPlainText,
|
||||||
getAutocompleteQuery,
|
getAutocompleteQuery,
|
||||||
getPrevWorldRange,
|
getPrevWordRange,
|
||||||
htmlToEditorInput,
|
htmlToEditorInput,
|
||||||
moveCursor,
|
moveCursor,
|
||||||
plainToEditorInput,
|
plainToEditorInput,
|
||||||
@@ -281,7 +281,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevWordRange = getPrevWorldRange(editor);
|
const prevWordRange = getPrevWordRange(editor);
|
||||||
const query = prevWordRange
|
const query = prevWordRange
|
||||||
? getAutocompleteQuery<AutocompletePrefix>(editor, prevWordRange, AUTOCOMPLETE_PREFIXES)
|
? getAutocompleteQuery<AutocompletePrefix>(editor, prevWordRange, AUTOCOMPLETE_PREFIXES)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ export const useAccountManagementActions = () => {
|
|||||||
const actions = useMemo(
|
const actions = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
profile: 'org.matrix.profile',
|
profile: 'org.matrix.profile',
|
||||||
sessionsList: 'org.matrix.sessions_list',
|
sessionsList: 'org.matrix.devices_list',
|
||||||
sessionView: 'org.matrix.session_view',
|
sessionView: 'org.matrix.device_view',
|
||||||
sessionEnd: 'org.matrix.session_end',
|
sessionEnd: 'org.matrix.device_delete',
|
||||||
accountDeactivate: 'org.matrix.account_deactivate',
|
accountDeactivate: 'org.matrix.account_deactivate',
|
||||||
crossSigningReset: 'org.matrix.cross_signing_reset',
|
crossSigningReset: 'org.matrix.cross_signing_reset',
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user