Skip to content

Commit 2f0c07b

Browse files
committed
Merge branch 'clearnet' into theming_hotfixes
2 parents adc40f9 + 8f426a5 commit 2f0c07b

34 files changed

+279
-176
lines changed

_locales/en/messages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"noSearchResults": "No results found for \"$searchTerm$\"",
7373
"conversationsHeader": "Contacts and Groups",
7474
"contactsHeader": "Contacts",
75-
"messagesHeader": "Messages",
75+
"messagesHeader": "Conversations",
7676
"settingsHeader": "Settings",
7777
"typingAlt": "Typing animation for this conversation",
7878
"contactAvatarAlt": "Avatar for contact $name$",

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "session-desktop",
33
"productName": "Session",
44
"description": "Private messaging from your desktop",
5-
"version": "1.10.2",
5+
"version": "1.10.4",
66
"license": "GPL-3.0",
77
"author": {
88
"name": "Oxen Labs",
@@ -306,7 +306,8 @@
306306
"libnss3",
307307
"libasound2",
308308
"libxss1"
309-
]
309+
],
310+
"packageCategory": "net"
310311
},
311312
"files": [
312313
"package.json",

ts/components/SessionScrollButton.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const SessionScrollButtonDiv = styled.div`
1313
1414
.session-icon-button {
1515
background-color: var(--message-bubbles-received-background-color);
16+
box-shadow: var(--scroll-button-shadow);
1617
}
1718
`;
1819

ts/components/dialog/SessionPasswordDialog.tsx

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,18 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
4242
}
4343

4444
public componentDidMount() {
45+
document.addEventListener('keyup', this.onEnterPressed);
46+
4547
setTimeout(() => {
4648
// tslint:disable-next-line: no-unused-expression
4749
this.passportInput && this.passportInput.focus();
4850
}, 1);
4951
}
5052

53+
public componentWillUnmount() {
54+
document.removeEventListener('keyup', this.onEnterPressed);
55+
}
56+
5157
public render() {
5258
const { passwordAction } = this.props;
5359
let placeholders: Array<string> = [];
@@ -93,15 +99,17 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
9399
this.passportInput = input;
94100
}}
95101
placeholder={placeholders[0]}
96-
onKeyUp={this.onPasswordInput}
102+
onChange={this.onPasswordInput}
103+
onPaste={this.onPasswordInput}
97104
data-testid="password-input"
98105
/>
99106
{passwordAction !== 'enter' && passwordAction !== 'remove' && (
100107
<input
101108
type="password"
102109
id="password-modal-input-confirm"
103110
placeholder={placeholders[1]}
104-
onKeyUp={this.onPasswordConfirmInput}
111+
onChange={this.onPasswordConfirmInput}
112+
onPaste={this.onPasswordConfirmInput}
105113
data-testid="password-input-confirm"
106114
/>
107115
)}
@@ -110,7 +118,8 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
110118
type="password"
111119
id="password-modal-input-reconfirm"
112120
placeholder={placeholders[2]}
113-
onKeyUp={this.onPasswordRetypeInput}
121+
onPaste={this.onPasswordRetypeInput}
122+
onChange={this.onPasswordRetypeInput}
114123
data-testid="password-input-reconfirm"
115124
/>
116125
)}
@@ -258,6 +267,13 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
258267
this.closeDialog();
259268
}
260269

270+
private async onEnterPressed(event: any) {
271+
if (event.key === 'Enter') {
272+
event.stopPropagation();
273+
return this.setPassword();
274+
}
275+
}
276+
261277
private async handleActionEnter(enteredPassword: string) {
262278
// be sure the password is valid
263279
if (!this.validatePassword(enteredPassword)) {
@@ -321,30 +337,18 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
321337
window.inboxStore?.dispatch(sessionPassword(null));
322338
}
323339

324-
private async onPasswordInput(event: any) {
325-
if (event.key === 'Enter') {
326-
return this.setPassword();
327-
}
340+
private onPasswordInput(event: any) {
328341
const currentPasswordEntered = event.target.value;
329-
330342
this.setState({ currentPasswordEntered });
331343
}
332344

333-
private async onPasswordConfirmInput(event: any) {
334-
if (event.key === 'Enter') {
335-
return this.setPassword();
336-
}
345+
private onPasswordConfirmInput(event: any) {
337346
const currentPasswordConfirmEntered = event.target.value;
338-
339347
this.setState({ currentPasswordConfirmEntered });
340348
}
341349

342-
private async onPasswordRetypeInput(event: any) {
343-
if (event.key === 'Enter') {
344-
return this.setPassword();
345-
}
350+
private onPasswordRetypeInput(event: any) {
346351
const currentPasswordRetypeEntered = event.target.value;
347-
348352
this.setState({ currentPasswordRetypeEntered });
349353
}
350354
}

ts/components/icon/SessionNotificationCount.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ type Props = {
77

88
const StyledCountContainer = styled.div<{ shouldRender: boolean }>`
99
position: absolute;
10-
width: 24px;
11-
height: 12px;
1210
font-size: 18px;
1311
top: 27px;
1412
right: 8px;
15-
padding: 3px;
13+
padding: 0 6px;
1614
opacity: 1;
1715
display: flex;
1816
align-items: center;
@@ -29,19 +27,19 @@ const StyledCountContainer = styled.div<{ shouldRender: boolean }>`
2927

3028
const StyledCount = styled.div`
3129
position: relative;
32-
font-size: 0.6em;
30+
font-size: 0.6rem;
3331
`;
3432

3533
export const SessionNotificationCount = (props: Props) => {
3634
const { count } = props;
37-
const overflow = Boolean(count && count > 9);
35+
const overflow = Boolean(count && count > 99);
3836
const shouldRender = Boolean(count && count > 0);
3937

4038
if (overflow) {
4139
return (
4240
<StyledCountContainer shouldRender={shouldRender}>
4341
<StyledCount>
44-
{9}
42+
{99}
4543
<span>+</span>
4644
</StyledCount>
4745
</StyledCountContainer>

ts/components/leftpane/ActionsPanel.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ const Section = (props: { type: SectionType }) => {
117117
iconSize="medium"
118118
dataTestId="settings-section"
119119
iconType={'gear'}
120-
notificationCount={unreadToShow}
121120
onClick={handleClick}
122121
isSelected={isSelected}
123122
/>
@@ -138,7 +137,6 @@ const Section = (props: { type: SectionType }) => {
138137
iconSize="medium"
139138
iconType={isDarkMode ? 'moon' : 'sun'}
140139
dataTestId="theme-section"
141-
notificationCount={unreadToShow}
142140
onClick={handleClick}
143141
isSelected={isSelected}
144142
/>

ts/components/settings/section/CategoryPrivacy.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export const SettingsCategoryPrivacy = (props: {
9797
displayPasswordModal('change', props.onPasswordUpdated);
9898
}}
9999
buttonText={window.i18n('changePassword')}
100+
dataTestId="change-password-settings-button"
100101
/>
101102
)}
102103
{props.hasPassword && (
@@ -108,6 +109,7 @@ export const SettingsCategoryPrivacy = (props: {
108109
}}
109110
buttonColor={SessionButtonColor.Danger}
110111
buttonText={window.i18n('removePassword')}
112+
dataTestId="remove-password-settings-button"
111113
/>
112114
)}
113115
</>

ts/data/data.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,9 +493,17 @@ async function getUnreadByConversation(conversationId: string): Promise<MessageC
493493
}
494494

495495
async function markAllAsReadByConversationNoExpiration(
496-
conversationId: string
496+
conversationId: string,
497+
returnMessagesUpdated: boolean // for performance reason we do not return them because usually they are not needed
497498
): Promise<Array<number>> {
498-
const messagesIds = await channels.markAllAsReadByConversationNoExpiration(conversationId);
499+
// tslint:disable-next-line: no-console
500+
console.time('markAllAsReadByConversationNoExpiration');
501+
const messagesIds = await channels.markAllAsReadByConversationNoExpiration(
502+
conversationId,
503+
returnMessagesUpdated
504+
);
505+
// tslint:disable-next-line: no-console
506+
console.timeEnd('markAllAsReadByConversationNoExpiration');
499507
return messagesIds;
500508
}
501509

ts/interactions/conversationInteractions.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,6 @@ export function showLeaveGroupByConvoId(conversationId: string) {
254254
export function showInviteContactByConvoId(conversationId: string) {
255255
window.inboxStore?.dispatch(updateInviteContactModal({ conversationId }));
256256
}
257-
export async function onMarkAllReadByConvoId(conversationId: string) {
258-
const conversation = getConversationController().get(conversationId);
259-
260-
await conversation.markReadBouncy(Date.now());
261-
}
262257

263258
export function showAddModeratorsByConvoId(conversationId: string) {
264259
window.inboxStore?.dispatch(updateAddModeratorsModal({ conversationId }));

ts/models/conversation.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
actions as conversationActions,
3333
conversationChanged,
3434
conversationsChanged,
35+
markConversationFullyRead,
3536
MessageModelPropsWithoutConvoProps,
3637
ReduxConversationType,
3738
} from '../state/ducks/conversations';
@@ -1231,27 +1232,38 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
12311232
* Send read receipt if needed.
12321233
*/
12331234
public async markAllAsRead() {
1234-
if (this.isOpenGroupV2()) {
1235+
/**
1236+
* when marking all as read, there is a bunch of things we need to do.
1237+
* - we need to update all the messages in the DB not read yet for that conversation
1238+
* - we need to send the read receipts if there is one needed for those messages
1239+
* - we need to trigger a change on the redux store, so those messages are read AND mark the whole convo as read.
1240+
* - we need to remove any notifications related to this conversation ID.
1241+
*
1242+
*
1243+
* (if there is an expireTimer, we do it the slow way, handling each message separately)
1244+
*/
1245+
const expireTimerSet = !!this.get('expireTimer');
1246+
if (this.isOpenGroupV2() || !expireTimerSet) {
12351247
// for opengroups, we batch everything as there is no expiration timer to take care (and potentially a lot of messages)
12361248

1237-
await Data.markAllAsReadByConversationNoExpiration(this.id);
1249+
const isOpenGroup = this.isOpenGroupV2();
1250+
// if this is an opengroup there is no need to send read receipt, and so no need to fetch messages updated.
1251+
const allReadMessages = await Data.markAllAsReadByConversationNoExpiration(
1252+
this.id,
1253+
!isOpenGroup
1254+
);
12381255
this.set({ mentionedUs: false, unreadCount: 0 });
12391256

12401257
await this.commit();
1241-
return;
1242-
}
1243-
1244-
// if the conversation has no expiration timer, we can also batch everything, but we also need to send read receipts potentially
1245-
// so we grab them from the db
1246-
if (!this.get('expireTimer')) {
1247-
const allReadMessages = await Data.markAllAsReadByConversationNoExpiration(this.id);
1248-
this.set({ mentionedUs: false, unreadCount: 0 });
1249-
await this.commit();
1250-
if (allReadMessages.length) {
1258+
if (!this.isOpenGroupV2() && allReadMessages.length) {
12511259
await this.sendReadReceiptsIfNeeded(uniq(allReadMessages));
12521260
}
1261+
Notifications.clearByConversationID(this.id);
1262+
window.inboxStore?.dispatch(markConversationFullyRead(this.id));
1263+
12531264
return;
12541265
}
1266+
// otherwise, do it the slow way
12551267
await this.markReadBouncy(Date.now());
12561268
}
12571269

0 commit comments

Comments
 (0)