Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use nix
24 changes: 24 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {

name = "session-desktop";
packages = with pkgs; [
nodejs_24
nodeenv
python314
cmake
gnumake
nodeenv
(pkgs.yarn.override { nodejs = null; })
];

env = {
};

shellHook = ''
'';

LD_LIBRARY_PATH = with pkgs; pkgs.lib.makeLibraryPath [ nss nspr dbus cups gtk3 libxcomposite libgbm expat libxkbcommon alsa-lib ];

}
2 changes: 2 additions & 0 deletions stylesheets/_global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,5 @@ fieldset {
// This hides the outline altogether. We might consider adding a new variable linked to a theme setting to fix this, for all users
outline: none;
}

$mobile-ui-breakpoint: 799px;
2 changes: 1 addition & 1 deletion stylesheets/_modules.scss
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@
// Module: Conversation List Item

.module-conversation-list-item {
max-width: 300px;
max-width: 100%;
display: flex;
flex-direction: row;
padding-inline-end: 16px;
Expand Down
21 changes: 18 additions & 3 deletions stylesheets/_session_conversation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,20 @@
}

.session-conversation {
position: relative;
flex-grow: 1;
width: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
flex-direction: column;
width: var(--main-panel-content-width);
flex-grow: 1;
height: 100%;
@media screen and (min-width: $mobile-ui-breakpoint) {
width: var(--main-panel-content-width);
position: relative;
}

.selection-mode {
.messages-container > *:not(.message-selected) {
Expand All @@ -34,6 +42,13 @@
}
}

.mobile-close-conversation {
display: block;
@media screen and (min-width: $mobile-ui-breakpoint) {
display: none;
}
}

.conversation-content {
display: flex;
flex-grow: 1;
Expand Down
17 changes: 17 additions & 0 deletions stylesheets/_session_left_pane.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,20 @@
flex-grow: 0;
padding-inline-end: 5px;
}

.module-session-inbox-view__styled_gutter {
transition: none;
width: 100%;
@media screen and (min-width: $mobile-ui-breakpoint) {
width: var(--left-panel-width);
}
}
.mobile-active-conversation {
width: 1px;
margin-left: -1px;
@media screen and (min-width: $mobile-ui-breakpoint) {
width: 100%;
margin-left: 0px;
max-width: var(--left-panel-width);
}
}
37 changes: 28 additions & 9 deletions ts/components/SessionInboxView.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
import { Provider } from 'react-redux';
import styled from 'styled-components';
import { AnimatePresence } from 'framer-motion';
import { LeftPane } from './leftpane/LeftPane';
import { SessionMainPanel } from './SessionMainPanel';
import { SessionTheme } from '../themes/SessionTheme';
import { Flex } from './basic/Flex';
import { useSelectedConversationKey } from '../state/selectors/selectedConversation';
import styled, { css } from 'styled-components';
import { ReactiveFlex } from './basic/ReactiveFlex';

const StyledGutter = styled.div`
width: var(--left-panel-width) !important;
transition: none;
const StyledGutter = styled.div<{ $conversationActive: boolean }>`
@media screen and (min-width: 799px) {
position: inherit;
width: var(--left-panel-width);
}

${({ $conversationActive }) =>
$conversationActive
? css``
: css`
z-index: 1;
width: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
`}
`;

const MobileStyledGutter = (props: any) => (
<StyledGutter {...props} $conversationActive={Boolean(useSelectedConversationKey())} />
);

export const SessionInboxView = () => {
if (!window.inboxStore) {
throw new Error('window.inboxStore is undefined in SessionInboxView');
Expand All @@ -21,12 +40,12 @@ export const SessionInboxView = () => {
<Provider store={window.inboxStore}>
<SessionTheme>
<AnimatePresence>
<Flex $container={true} height="0" $flexShrink={100} $flexGrow={1}>
<StyledGutter>
<ReactiveFlex $container={true} height="0" $flexShrink={100} $flexGrow={1}>
<MobileStyledGutter>
<LeftPane />
</StyledGutter>
</MobileStyledGutter>
<SessionMainPanel />
</Flex>
</ReactiveFlex>
</AnimatePresence>
</SessionTheme>
</Provider>
Expand Down
1 change: 0 additions & 1 deletion ts/components/SessionMainPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useAppIsFocused } from '../hooks/useAppFocused';

import { SmartSessionConversation } from '../state/smart/SessionConversation';
import { useHTMLDirection } from '../util/i18n/rtlSupport';

Expand Down
2 changes: 1 addition & 1 deletion ts/components/SplitViewContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const TopSplitViewPanel = ({
topHeight: number | undefined;
setTopHeight: (value: number) => void;
}) => {
const topRef = useRef<HTMLDivElement>(null);
const topRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (topRef.current) {
if (!topHeight) {
Expand Down
110 changes: 110 additions & 0 deletions ts/components/basic/ReactiveFlex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { HTMLMotionProps, motion } from 'framer-motion';
import styled from 'styled-components';
import { HTMLDirection } from '../../util/i18n/rtlSupport';

export interface FlexProps {
children?: any;
className?: string;
$container?: boolean;
// Container Props
$flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
$justifyContent?:
| 'flex-start'
| 'flex-end'
| 'center'
| 'space-between'
| 'space-around'
| 'space-evenly'
| 'initial'
| 'inherit';
$flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse';
$flexGap?: string;
$alignItems?:
| 'stretch'
| 'center'
| 'flex-start'
| 'flex-end'
| 'baseline'
| 'initial'
| 'inherit';
// Child Props
$flexGrow?: number;
$flexShrink?: number;
$flexBasis?: number;
// Common Layout Props
$padding?: string;
$margin?: string;
width?: string;
$maxWidth?: string;
$minWidth?: string;
height?: string;
$maxHeight?: string;
$minHeight?: string;
$overflow?: 'hidden' | 'visible' | 'scroll' | 'auto';
$overflowX?: 'hidden' | 'visible' | 'scroll' | 'auto';
$overflowY?: 'hidden' | 'visible' | 'scroll' | 'auto';
// RTL support
dir?: HTMLDirection;
$paddingInline?: string;
$paddingBlock?: string;
$marginInline?: string;
$marginBlock?: string;
}

export const ReactiveFlex = styled.div<FlexProps>`
display: block;

@media screen and (min-width: 799px) {
display: ${props => (props.$container ? 'flex' : 'block')};
justify-content: ${props => props.$justifyContent || 'flex-start'};
flex-direction: ${props => props.$flexDirection || 'row'};
flex-grow: ${props => (props.$flexGrow !== undefined ? props.$flexGrow : '0')};
flex-basis: ${props => (props.$flexBasis !== undefined ? props.$flexBasis : 'auto')};
flex-shrink: ${props => (props.$flexShrink !== undefined ? props.$flexShrink : '1')};
flex-wrap: ${props => (props.$flexWrap !== undefined ? props.$flexWrap : 'nowrap')};
gap: ${props => props.$flexGap || undefined};
align-items: ${props => props.$alignItems || 'stretch'};
margin: ${props => props.$margin || ''};
padding: ${props => props.$padding || ''};
width: ${props => props.width || 'auto'};
max-width: ${props => props.$maxWidth || 'none'};
min-width: ${props => props.$minWidth || 'none'};
height: ${props => props.height || 'auto'};
max-height: ${props => props.$maxHeight || 'none'};
min-height: ${props => props.$minHeight || 'none'};
overflow: ${props => (props.$overflow !== undefined ? props.$overflow : undefined)};
overflow-x: ${props => (props.$overflowX !== undefined ? props.$overflowX : undefined)};
overflow-y: ${props => (props.$overflowY !== undefined ? props.$overflowY : undefined)};
direction: ${props => props.dir || undefined};
padding-inline: ${props => props.$paddingInline || undefined};
padding-block: ${props => props.$paddingBlock || undefined};
margin-inline: ${props => props.$marginInline || undefined};
margin-block: ${props => props.$marginBlock || undefined};
}
`;

export const AnimatedFlex = styled(motion.div) <HTMLMotionProps<'div'> & FlexProps>`
display: ${props => (props.$container ? 'flex' : 'block')};
justify-content: ${props => props.$justifyContent || 'flex-start'};
flex-direction: ${props => props.$flexDirection || 'row'};
flex-grow: ${props => (props.$flexGrow !== undefined ? props.$flexGrow : '0')};
flex-basis: ${props => (props.$flexBasis !== undefined ? props.$flexBasis : 'auto')};
flex-shrink: ${props => (props.$flexShrink !== undefined ? props.$flexShrink : '1')};
flex-wrap: ${props => (props.$flexWrap !== undefined ? props.$flexWrap : 'nowrap')};
gap: ${props => props.$flexGap || undefined};
align-items: ${props => props.$alignItems || 'stretch'};
margin: ${props => props.$margin || '0'};
padding: ${props => props.$padding || '0'};
width: ${props => props.width || 'auto'};
max-width: ${props => props.$maxWidth || 'none'};
min-width: ${props => props.$minWidth || 'none'};
height: ${props => props.height || 'auto'};
max-height: ${props => props.$maxHeight || 'none'};
min-height: ${props => props.$minHeight || 'none'};
overflow: ${props => (props.$overflow !== undefined ? props.$overflow : undefined)};
direction: ${props => props.dir || undefined};
padding-inline: ${props => props.$paddingInline || undefined};
padding-block: ${props => props.$paddingBlock || undefined};
margin-inline: ${props => props.$marginInline || undefined};
margin-block: ${props => props.$marginBlock || undefined};
`;
19 changes: 16 additions & 3 deletions ts/components/conversation/header/ConversationHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,21 @@ import { ConversationTypeEnum } from '../../../models/types';
import { Constants } from '../../../session';
import { useShowConversationSettingsFor } from '../../menuAndSettingsHooks/useShowConversationSettingsFor';
import { sectionActions } from '../../../state/ducks/section';
import { SessionLucideIconButton } from '../../icon/SessionIconButton';
import { LUCIDE_ICONS_UNICODE } from '../../icon/lucide';
import { resetConversationExternal } from '../../../state/ducks/conversations';

const StyledConversationHeader = styled.div`
display: flex;
flex-direction: row;
align-items: center;
height: var(--main-view-header-height);
position: relative;
padding: 0px var(--margins-lg) 0px var(--margins-sm);
background: var(--background-primary-color);
padding: 0px var(--margins-lg) 0px var(--margins-lg);
@media screen and (min-width: 799px) {
padding: 0px var(--margins-lg) 0px var(--margins-sm);
}
`;

export const ConversationHeaderWithDetails = () => {
Expand All @@ -62,6 +68,13 @@ export const ConversationHeaderWithDetails = () => {
width="100%"
$flexGrow={1}
>
<div className="mobile-close-conversation">
<SessionLucideIconButton
iconSize={'large'}
unicode={LUCIDE_ICONS_UNICODE.X}
onClick={() => window?.inboxStore?.dispatch(resetConversationExternal())}
/>
</div>
<ConversationHeaderTitle
showSubtitle={!isOutgoingRequest && !isIncomingRequest && !isBlocked}
/>
Expand All @@ -80,8 +93,8 @@ export const ConversationHeaderWithDetails = () => {
onAvatarClick={
showConvoSettingsCb
? () => {
showConvoSettingsCb({ settingsModalPage: 'default' });
}
showConvoSettingsCb({ settingsModalPage: 'default' });
}
: undefined
}
pubkey={selectedConvoKey}
Expand Down
18 changes: 14 additions & 4 deletions ts/components/leftpane/LeftPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ import { useIsRtl } from '../../util/i18n/rtlSupport';
export const leftPaneListWidth = 300; // var(--left-panel-width) without the 80px of the action gutter

const StyledLeftPane = styled.div<{ $isRtl: boolean }>`
width: ${() => `${leftPaneListWidth}px`};
height: 100%;
width: 100%;
@media screen and (min-width: 799px) {
width: ${() => `${leftPaneListWidth}px`};
height: 100%;
border-left: 1px solid var(--border-color);
border-right: 1px solid var(--border-color);
}
height: calc(100% - 76px);
display: inline-flex;
flex-direction: column;
position: relative;
flex-shrink: 0;
border-left: 1px solid var(--border-color);
border-right: 1px solid var(--border-color);
direction: ${({ $isRtl }) => ($isRtl ? 'rtl' : 'ltr')};
`;

Expand All @@ -38,7 +42,13 @@ const CallContainer = () => {

const StyledLeftPaneSession = styled.div`
display: flex;
flex-direction: column-reverse;
height: 100%;
width: 100%;

@media screen and (min-width: 799px) {
flex-direction: row;
}
`;

export const LeftPane = () => {
Expand Down
1 change: 1 addition & 0 deletions ts/components/leftpane/LeftPaneList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import styled from 'styled-components';

export const StyledLeftPaneList = styled.div`

height: 100%;
flex-grow: 1;
flex-shrink: 1;
Expand Down
Loading