Skip to content

Commit 41c168c

Browse files
committed
Merge remote-tracking branch 'upstream/dev' into delete-msg-options-updated
2 parents 8a87b9c + cab1e6a commit 41c168c

File tree

14 files changed

+110
-72
lines changed

14 files changed

+110
-72
lines changed

.github/workflows/build-binaries.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ jobs:
7878
makeLatest: false
7979
omitBodyDuringUpdate: true
8080
omitNameDuringUpdate: true
81+
commit: master # needed so that the "target" of the release is correct on github
8182

8283
lint:
8384
runs-on: ubuntu-22.04

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ See [node-gyp installation instructions](https://github.com/nodejs/node-gyp#inst
6767
<summary>Fedora</summary>
6868

6969
```sh
70-
sudo dnf install make automake gcc gcc-c++ kernel-devel
70+
sudo dnf install make cmake automake gcc gcc-c++ kernel-devel
7171
```
7272

7373
</details>

dynamic_assets

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"name": "session-desktop",
55
"productName": "Session",
66
"description": "Private messaging from your desktop",
7-
"version": "1.17.10",
7+
"version": "1.17.12",
88
"license": "GPL-3.0",
99
"author": {
1010
"name": "Session Foundation",

pnpm-workspace.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ onlyBuiltDependencies:
66
- libsession_util_nodejs
77
- protobufjs
88
- sharp
9+
publicHoistPattern:
10+
- '@img/*'

ts/components/SessionPopover.tsx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import styled from 'styled-components';
22
import { type ReactNode, useMemo, useRef } from 'react';
33
import { getFeatureFlagMemo } from '../state/ducks/types/releasedFeaturesReduxTypes';
44
import { clampNumber } from '../util/maths';
5-
import { defaultTriggerPos, PopoverTriggerPosition } from './SessionTooltip';
5+
import { PopoverTriggerPosition } from './SessionTooltip';
66

77
const TIP_LENGTH = 18;
88
const VIEWPORT_MARGIN = 4;
@@ -95,7 +95,7 @@ const StyledPopover = styled.div<{
9595
export type PopoverProps = {
9696
children: ReactNode;
9797
pointerOffset?: number;
98-
triggerPosition: PopoverTriggerPosition;
98+
triggerPosition: PopoverTriggerPosition | null;
9999
open: boolean;
100100
loading?: boolean;
101101
maxWidth?: string;
@@ -124,7 +124,7 @@ export const SessionPopoverContent = (props: PopoverProps) => {
124124
loading,
125125
maxWidth,
126126
onClick,
127-
triggerPosition = defaultTriggerPos,
127+
triggerPosition,
128128
isTooltip,
129129
contentMargin = 0,
130130
containerMarginTop = VIEWPORT_MARGIN,
@@ -146,8 +146,10 @@ export const SessionPopoverContent = (props: PopoverProps) => {
146146
const viewportWidth = window.innerWidth;
147147
const viewportHeight = window.innerHeight;
148148

149+
const show = open && !loading && !!triggerPosition;
150+
149151
const { x, y, pointerOffset, anchorX, finalVerticalPos, bounds } = useMemo(() => {
150-
if (!open || loading) {
152+
if (!show) {
151153
return {
152154
x: 0,
153155
y: 0,
@@ -217,15 +219,10 @@ export const SessionPopoverContent = (props: PopoverProps) => {
217219
bounds: { x1: minX, y1: minY, x2: maxX, y2: maxY },
218220
};
219221
}, [
220-
open,
221-
loading,
222+
show,
222223
contentWidth,
223224
isTooltip,
224-
triggerPosition.x,
225-
triggerPosition.y,
226-
triggerPosition.width,
227-
triggerPosition.height,
228-
triggerPosition.offsetX,
225+
triggerPosition,
229226
horizontalPosition,
230227
viewportWidth,
231228
verticalPosition,
@@ -244,7 +241,7 @@ export const SessionPopoverContent = (props: PopoverProps) => {
244241
<>
245242
<StyledPopover
246243
ref={ref}
247-
$readyToShow={open && !loading}
244+
$readyToShow={show}
248245
onClick={onClick}
249246
x={x}
250247
y={y}
@@ -257,7 +254,7 @@ export const SessionPopoverContent = (props: PopoverProps) => {
257254
>
258255
{children}
259256
</StyledPopover>
260-
{showPopoverAnchors && open ? (
257+
{showPopoverAnchors && show ? (
261258
// NOTE: these are only rendered when the debug option is enabled
262259
<>
263260
<StyledCoordinateRectangleMarker title="allowedArea" $bounds={bounds} />

ts/components/SessionTooltip.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,12 @@ export const getTriggerPositionFromId = (id: string): PopoverTriggerPosition =>
7272
return getTriggerPositionFromBoundingClientRect(el.getBoundingClientRect());
7373
};
7474

75-
export const useTriggerPosition = (ref: RefObject<HTMLElement | null>): PopoverTriggerPosition => {
75+
// Returns null if the ref is null
76+
export const useTriggerPosition = (
77+
ref: RefObject<HTMLElement | null>
78+
): PopoverTriggerPosition | null => {
7679
if (!ref.current) {
77-
return defaultTriggerPos;
80+
return null;
7881
}
7982
return getTriggerPositionFromBoundingClientRect(ref.current.getBoundingClientRect());
8083
};

ts/components/conversation/SessionEmojiPanelPopover.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { RefObject } from 'react';
2-
import { useTriggerPosition } from '../SessionTooltip';
2+
import { type PopoverTriggerPosition } from '../SessionTooltip';
33
import { SessionEmojiPanel } from './SessionEmojiPanel';
44
import { SessionPopoverContent } from '../SessionPopover';
55
import { FixedBaseEmoji } from '../../types/Reaction';
@@ -9,30 +9,30 @@ const EMOJI_PANEL_WIDTH_PX = 354;
99
const EMOJI_PANEL_HEIGHT_PX = 435;
1010

1111
export function SessionEmojiPanelPopover({
12-
triggerRef,
12+
triggerPos,
1313
emojiPanelRef,
1414
onEmojiClicked,
1515
open,
1616
onClose,
1717
}: {
18-
triggerRef: RefObject<HTMLButtonElement | null>;
18+
triggerPos: PopoverTriggerPosition | null;
1919
open: boolean;
2020
emojiPanelRef: RefObject<HTMLDivElement | null>;
2121
onEmojiClicked: (emoji: FixedBaseEmoji) => void;
2222
onClose: () => void;
2323
}) {
24-
const triggerPos = useTriggerPosition(triggerRef);
24+
const _open = open && !!triggerPos;
2525
return (
2626
<SessionPopoverContent
2727
triggerPosition={triggerPos}
28-
open={open}
28+
open={_open}
2929
isTooltip={false}
3030
verticalPosition="bottom"
3131
horizontalPosition="center"
3232
fallbackContentWidth={EMOJI_PANEL_WIDTH_PX}
3333
fallbackContentHeight={EMOJI_PANEL_HEIGHT_PX}
3434
>
35-
{open ? (
35+
{_open ? (
3636
<SessionEmojiPanel
3737
ref={emojiPanelRef}
3838
show={true}

ts/components/conversation/SessionEmojiReactBarPopover.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect, useRef, useState } from 'react';
22
import useClickAway from 'react-use/lib/useClickAway';
3-
import type { PopoverTriggerPosition } from '../SessionTooltip';
3+
import { useTriggerPosition, type PopoverTriggerPosition } from '../SessionTooltip';
44
import { SessionPopoverContent } from '../SessionPopover';
55
import { MessageReactBar } from './message/message-content/MessageReactBar';
66
import { THEME_GLOBALS } from '../../themes/globals';
@@ -22,14 +22,14 @@ export function SessionEmojiReactBarPopover({
2222
onClickAwayFromReactionBar: () => void;
2323
}) {
2424
const emojiPanelTriggerRef = useRef<HTMLButtonElement>(null);
25+
const emojiPanelTriggerPos = useTriggerPosition(emojiPanelTriggerRef);
2526
const emojiPanelRef = useRef<HTMLDivElement>(null);
2627
const emojiReactionBarRef = useRef<HTMLDivElement>(null);
2728
const [showEmojiPanel, setShowEmojiPanel] = useState<boolean>(false);
2829
const reactToMessage = useReactToMessage(messageId);
2930
const focusedMessageId = useFocusedMessageId();
3031

3132
const closeEmojiPanel = () => {
32-
closeContextMenus();
3333
setShowEmojiPanel(false);
3434
};
3535

@@ -66,7 +66,7 @@ export function SessionEmojiReactBarPopover({
6666
<>
6767
<SessionEmojiPanelPopover
6868
emojiPanelRef={emojiPanelRef}
69-
triggerRef={emojiPanelTriggerRef}
69+
triggerPos={emojiPanelTriggerPos}
7070
// eslint-disable-next-line @typescript-eslint/no-misused-promises
7171
onEmojiClicked={onEmojiClick}
7272
open={showEmojiPanel}

ts/components/conversation/message/message-item/GenericReadableMessage.tsx

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { type MouseEvent, type KeyboardEvent, useCallback, useRef, useState } from 'react';
1+
import {
2+
type MouseEvent,
3+
type KeyboardEvent,
4+
useCallback,
5+
useRef,
6+
useState,
7+
useEffect,
8+
} from 'react';
29
import clsx from 'clsx';
310

411
import styled, { keyframes } from 'styled-components';
@@ -31,6 +38,7 @@ import { GroupUpdateMessage } from './GroupUpdateMessage';
3138
import { CallNotification } from './notification-bubble/CallNotification';
3239
import { InteractionNotification } from './InteractionNotification';
3340
import { MessageRequestResponse } from './MessageRequestResponse';
41+
import { useFocusScope, useIsInScope } from '../../../../state/focus';
3442

3543
export type GenericReadableMessageSelectorProps = Pick<
3644
MessageRenderingProps,
@@ -44,6 +52,7 @@ const highlightedMessageAnimation = keyframes`
4452
const StyledReadableMessage = styled.div<{
4553
selected: boolean;
4654
$isDetailView: boolean;
55+
$focusedKeyboard: boolean;
4756
}>`
4857
display: flex;
4958
align-items: center;
@@ -59,9 +68,12 @@ const StyledReadableMessage = styled.div<{
5968
margin-top: var(--margins-xs);
6069
}
6170
62-
&:focus-visible {
71+
${props =>
72+
props.$focusedKeyboard
73+
? `&:focus-visible {
6374
background-color: var(--conversation-tab-background-selected-color);
64-
}
75+
}`
76+
: ''}
6577
`;
6678

6779
function getMessageComponent(messageType: UIMessageType) {
@@ -104,8 +116,10 @@ export const GenericReadableMessage = ({ messageId }: WithMessageId) => {
104116

105117
const ref = useRef<HTMLDivElement>(null);
106118
const pointerDownRef = useRef(false);
107-
const keyboardFocusedRef = useRef(false);
108119
const [triggerPosition, setTriggerPosition] = useState<PopoverTriggerPosition | null>(null);
120+
const isInFocusScope = useIsInScope({ scope: 'message', scopeId: messageId });
121+
const { focusedMessageId } = useFocusScope();
122+
const isAnotherMessageFocused = focusedMessageId && !isInFocusScope;
109123

110124
const getMessageContainerTriggerPosition = (): PopoverTriggerPosition | null => {
111125
if (!ref.current) {
@@ -180,6 +194,12 @@ export const GenericReadableMessage = ({ messageId }: WithMessageId) => {
180194

181195
const messageType = useMessageType(messageId);
182196

197+
useEffect(() => {
198+
if (isAnotherMessageFocused) {
199+
setTriggerPosition(null);
200+
}
201+
}, [isAnotherMessageFocused]);
202+
183203
if (!convoId || !messageId || !messageType) {
184204
return null;
185205
}
@@ -200,23 +220,16 @@ export const GenericReadableMessage = ({ messageId }: WithMessageId) => {
200220
onContextMenu={handleContextMenu}
201221
key={`readable-message-${messageId}`}
202222
onKeyDown={onKeyDown}
223+
$focusedKeyboard={!pointerDownRef.current}
203224
tabIndex={0}
204225
onPointerDown={() => {
205226
pointerDownRef.current = true;
206227
}}
207228
onFocus={() => {
208-
if (!pointerDownRef.current) {
209-
keyboardFocusedRef.current = true;
210-
onFocus();
211-
}
229+
onFocus();
212230
pointerDownRef.current = false;
213231
}}
214-
onBlur={() => {
215-
if (keyboardFocusedRef.current) {
216-
keyboardFocusedRef.current = false;
217-
onBlur();
218-
}
219-
}}
232+
onBlur={onBlur}
220233
>
221234
<CmpToRender
222235
contextMenuId={ctxMenuID}

0 commit comments

Comments
 (0)