Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86b77ac9f3 |
@@ -47,12 +47,8 @@ import {
|
||||
recentForwardTargetsAtom,
|
||||
addRecentForwardTarget,
|
||||
} from '../../../state/recentForwardTargets';
|
||||
import {
|
||||
buildForwardContent,
|
||||
buildPlaintextAttachmentContent,
|
||||
forwardEncryptionWarning,
|
||||
} from './forwardContent';
|
||||
import { useLocalRoomNames, getLocalRoomName } from '../../../hooks/useRoomMeta';
|
||||
import { buildForwardContent, buildPlaintextAttachmentContent } from './forwardContent';
|
||||
import { useLocalRoomNames } from '../../../hooks/useRoomMeta';
|
||||
|
||||
type RoomRowProps = {
|
||||
room: Room;
|
||||
@@ -279,14 +275,6 @@ export function ForwardMessageDialog({ mEvent, onClose }: Props) {
|
||||
// Selection persists across query changes: a room selected then filtered out
|
||||
// of the rendered slice stays selected.
|
||||
const [selectedRoomIds, setSelectedRoomIds] = useState<Set<string>>(new Set());
|
||||
const encryptionWarning = forwardEncryptionWarning(
|
||||
!!mx.getRoom(mEvent.getRoomId() ?? '')?.hasEncryptionStateEvent(),
|
||||
[...selectedRoomIds]
|
||||
.map((id) => mx.getRoom(id))
|
||||
.filter((r): r is Room => !!r && !r.hasEncryptionStateEvent())
|
||||
// The name the user sees (their own "Rename for me" name, if set).
|
||||
.map((r) => getLocalRoomName(mx, r.roomId) ?? r.name),
|
||||
);
|
||||
|
||||
const toggleRoom = useCallback((roomId: string) => {
|
||||
setSelectedRoomIds((prev) => {
|
||||
@@ -602,13 +590,7 @@ export function ForwardMessageDialog({ mEvent, onClose }: Props) {
|
||||
shrink="No"
|
||||
direction="Column"
|
||||
style={{ padding: `${config.space.S200} ${config.space.S400}` }}
|
||||
gap="200"
|
||||
>
|
||||
{encryptionWarning && (
|
||||
<Text size="T200" role="note" style={{ color: color.Warning.Main }}>
|
||||
{encryptionWarning}
|
||||
</Text>
|
||||
)}
|
||||
<Button
|
||||
variant="Primary"
|
||||
size="400"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { MatrixClient, MatrixEvent } from 'matrix-js-sdk';
|
||||
import { buildForwardContent, forwardEncryptionWarning, getForwardedMeta } from './forwardContent';
|
||||
import { buildForwardContent, getForwardedMeta } from './forwardContent';
|
||||
|
||||
// Pure content builder buildForwardContent: refuses undecryptable events, forwards
|
||||
// the latest edit (`m.new_content`), and strips reply fallbacks + `m.relates_to`.
|
||||
@@ -171,16 +171,3 @@ test('getForwardedMeta rejects malformed metadata', () => {
|
||||
assert.equal(getForwardedMeta({ 'io.lotus.forwarded': { sender: 1 } }), undefined);
|
||||
assert.equal(getForwardedMeta({}), undefined);
|
||||
});
|
||||
|
||||
test('forwardEncryptionWarning: only from an encrypted room into unencrypted ones (#330)', () => {
|
||||
assert.equal(forwardEncryptionWarning(false, ['general']), undefined);
|
||||
assert.equal(forwardEncryptionWarning(true, []), undefined);
|
||||
assert.match(
|
||||
forwardEncryptionWarning(true, ['general']) ?? '',
|
||||
/^general isn't encrypted\..*that room, along with who originally wrote it\.$/,
|
||||
);
|
||||
assert.match(
|
||||
forwardEncryptionWarning(true, ['a', 'b']) ?? '',
|
||||
/^2 of the rooms you picked aren't encrypted\..*those rooms/,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -122,23 +122,3 @@ export async function buildPlaintextAttachmentContent(
|
||||
|
||||
return plainContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Gitea #330] The note shown when forwarding out of an encrypted room into
|
||||
* rooms that aren't: the text (and a re-uploaded attachment) becomes readable
|
||||
* by the server, and the original author is shown with it. Undefined when
|
||||
* there's nothing to warn about.
|
||||
*/
|
||||
export function forwardEncryptionWarning(
|
||||
sourceEncrypted: boolean,
|
||||
unencryptedDestNames: string[],
|
||||
): string | undefined {
|
||||
if (!sourceEncrypted || unencryptedDestNames.length === 0) return undefined;
|
||||
const where =
|
||||
unencryptedDestNames.length === 1
|
||||
? `${unencryptedDestNames[0]} isn't encrypted.`
|
||||
: `${unencryptedDestNames.length} of the rooms you picked aren't encrypted.`;
|
||||
return `${where} The forwarded message (and any attachment) will be readable by the server and everyone in ${
|
||||
unencryptedDestNames.length === 1 ? 'that room' : 'those rooms'
|
||||
}, along with who originally wrote it.`;
|
||||
}
|
||||
|
||||
@@ -596,10 +596,6 @@ function Appearance() {
|
||||
/>
|
||||
</SequenceCard>
|
||||
|
||||
<DesktopChromeSetting />
|
||||
<AutostartSetting />
|
||||
<KeychainMirrorSetting />
|
||||
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="Twitter Emoji"
|
||||
@@ -2856,6 +2852,23 @@ function PackageUpdate({ help }: { help: NonNullable<ReturnType<typeof packageUp
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Gitea #290] Desktop-only settings in their own section (they used to sit
|
||||
* inside Appearance, between Monochrome Mode and Twitter Emoji). Renders
|
||||
* nothing outside the desktop app.
|
||||
*/
|
||||
function DesktopSettings() {
|
||||
if (!isTauriEnv()) return null;
|
||||
return (
|
||||
<Box direction="Column" gap="100">
|
||||
<Text size="L400">Desktop</Text>
|
||||
<AutostartSetting />
|
||||
<KeychainMirrorSetting />
|
||||
<DesktopChromeSetting />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function AppUpdates() {
|
||||
const { isTauri, status, check, install, installKind } = useTauriUpdater();
|
||||
if (!isTauri) return null;
|
||||
@@ -2964,6 +2977,7 @@ export function General({ requestClose }: GeneralProps) {
|
||||
<StorageUsage />
|
||||
<SettingsSyncSection />
|
||||
<Calls />
|
||||
<DesktopSettings />
|
||||
<AppUpdates />
|
||||
</Box>
|
||||
</PageContent>
|
||||
|
||||
Reference in New Issue
Block a user