Merge remote-tracking branch 'upstream/clearnet' into webrtc-calls-p2

pull/1978/head
Audric Ackermann 4 years ago
commit 251309656b
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -73,6 +73,7 @@
"attemptingReconnection": "Attempting reconnect in $reconnect_duration_in_seconds$ seconds",
"submitDebugLog": "Debug log",
"debugLog": "Debug Log",
"showDebugLog": "Show Debug Log",
"goToReleaseNotes": "Go to Release Notes",
"goToSupportPage": "Go to Support Page",
"menuReportIssue": "Report an Issue",
@ -421,6 +422,7 @@
"unpinConversation": "Unpin Conversation",
"pinConversationLimitTitle": "Pinned conversations limit",
"pinConversationLimitToastDescription": "You can only pin $number$ conversations",
"showUserDetails": "Show User Details",
"latestUnreadIsAbove": "First unread message is above",
"sendRecoveryPhraseTitle": "Sending Recovery Phrase",
"sendRecoveryPhraseMessage": "You are attempting to send your recovery phrase which can be used to access your account. Are you sure you want to send this message?",

@ -22,5 +22,9 @@ window.getNodeVersion = () => config.node_version;
window.getEnvironment = () => config.environment;
require('./js/logging');
const os = require('os');
window.getOSRelease = () => `${os.type()} ${os.release} ${os.platform()}`;
window.getCommitHash = () => config.commitHash;
window.closeDebugLog = () => ipcRenderer.send('close-debug-log');

@ -26,9 +26,15 @@
this.render();
this.$('textarea').val(i18n('loading'));
const operatingSystemInfo = `Operating System: ${window.getOSRelease()}`;
const commitHashInfo = window.getCommitHash() ? `Commit Hash: ${window.getCommitHash()}` : '';
// eslint-disable-next-line more/no-then
window.log.fetch().then(text => {
this.$('textarea').val(text);
const debugLogWithSystemInfo = operatingSystemInfo + commitHashInfo + text;
this.$('textarea').val(debugLogWithSystemInfo);
});
},
events: {

@ -336,6 +336,8 @@
"node_modules/socks/build/common/*.js",
"node_modules/socks/build/client/*.js",
"node_modules/smart-buffer/build/*.js",
"node_modules/react-draggable/build/cjs/*.js",
"node_modules/react-draggable/build/cjs/utils/*.js",
"!node_modules/@journeyapps/sqlcipher/deps/*",
"!node_modules/@journeyapps/sqlcipher/build/*",
"!node_modules/@journeyapps/sqlcipher/lib/binding/node-*",

@ -356,6 +356,9 @@ const ConversationListItem = (props: Props) => {
left={!!left}
type={type}
currentNotificationSetting={currentNotificationSetting || 'all'}
avatarPath={avatarPath || null}
name={name}
profileName={profileName}
/>
</Portal>
</div>

@ -360,6 +360,9 @@ export const ConversationHeaderWithDetails = () => {
left={left}
hasNickname={hasNickname}
currentNotificationSetting={currentNotificationSetting}
avatarPath={avatarPath}
name={name}
profileName={profileName}
/>
</div>

@ -1,3 +1,4 @@
import { ipcRenderer } from 'electron';
import React from 'react';
import styled from 'styled-components';
import { MessageDeliveryStatus } from '../../../models/messageType';
@ -40,8 +41,12 @@ const MessageStatusRead = () => {
};
const MessageStatusError = () => {
const showDebugLog = () => {
ipcRenderer.send('show-debug-log');
};
return (
<MessageStatusSendingContainer title={window.i18n('sendFailed')}>
<MessageStatusSendingContainer onClick={showDebugLog} title={window.i18n('sendFailed')}>
<SessionIcon iconColor={'var(--color-destructive'} iconType="error" iconSize={'tiny'} />
</MessageStatusSendingContainer>
);

@ -6,6 +6,7 @@ import useCopyToClipboard from 'react-use/lib/useCopyToClipboard';
import useKey from 'react-use/lib/useKey';
import { ConversationTypeEnum } from '../../models/conversation';
import { getConversationController } from '../../session/conversations';
import { ToastUtils } from '../../session/utils';
import { openConversationWithMessages } from '../../state/ducks/conversations';
import { updateUserDetailsModal } from '../../state/ducks/modalDialog';
import { Avatar, AvatarSize } from '../Avatar';
@ -77,6 +78,7 @@ export const UserDetailsDialog = (props: Props) => {
buttonColor={SessionButtonColor.Primary}
onClick={() => {
copyToClipboard(props.conversationId);
ToastUtils.pushCopiedToClipBoard();
}}
/>
<SessionButton

@ -15,6 +15,7 @@ import {
getNotificationForConvoMenuItem,
getPinConversationMenuItem,
getRemoveModeratorsMenuItem,
getShowUserDetailsMenuItem,
getStartCallMenuItem,
getUpdateGroupNameMenuItem,
} from './Menu';
@ -34,6 +35,9 @@ export type PropsConversationHeaderMenu = {
isPrivate: boolean;
isBlocked: boolean;
hasNickname: boolean;
name: string | undefined;
profileName: string | undefined;
avatarPath: string | null;
};
const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
@ -50,7 +54,11 @@ const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
left,
hasNickname,
currentNotificationSetting,
name,
profileName,
avatarPath,
} = props;
const userName = name || profileName || conversationId;
return (
<Menu id={triggerId} animation={animation.fade}>
@ -75,9 +83,9 @@ const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
{getRemoveModeratorsMenuItem(weAreAdmin, isPublic, isKickedFromGroup, conversationId)}
{getUpdateGroupNameMenuItem(weAreAdmin, isKickedFromGroup, left, conversationId)}
{getLeaveGroupMenuItem(isKickedFromGroup, left, isGroup, isPublic, conversationId)}
{/* TODO: add delete group */}
{getInviteContactMenuItem(isGroup, isPublic, conversationId)}
{getDeleteContactMenuItem(isGroup, isPublic, left, isKickedFromGroup, conversationId)}
{getShowUserDetailsMenuItem(isPrivate, conversationId, avatarPath, userName)}
</Menu>
);
};

@ -18,6 +18,7 @@ import {
getMarkAllReadMenuItem,
getNotificationForConvoMenuItem,
getPinConversationMenuItem,
getShowUserDetailsMenuItem,
} from './Menu';
export type PropsContextConversationItem = {
@ -33,6 +34,9 @@ export type PropsContextConversationItem = {
left: boolean;
theme?: any;
currentNotificationSetting: ConversationNotificationSettingType;
name: string | undefined;
profileName: string | undefined;
avatarPath: string | null;
};
const ConversationListItemContextMenu = (props: PropsContextConversationItem) => {
@ -48,9 +52,14 @@ const ConversationListItemContextMenu = (props: PropsContextConversationItem) =>
isKickedFromGroup,
currentNotificationSetting,
isPrivate,
name,
profileName,
avatarPath,
} = props;
const isGroup = type === 'group';
const userName = name || profileName || conversationId;
return (
<Menu id={triggerId} animation={animation.fade}>
{getNotificationForConvoMenuItem({
@ -71,6 +80,7 @@ const ConversationListItemContextMenu = (props: PropsContextConversationItem) =>
{getInviteContactMenuItem(isGroup, isPublic, conversationId)}
{getDeleteContactMenuItem(isGroup, isPublic, left, isKickedFromGroup, conversationId)}
{getLeaveGroupMenuItem(isKickedFromGroup, left, isGroup, isPublic, conversationId)}
{getShowUserDetailsMenuItem(isPrivate, conversationId, avatarPath, userName)}
</Menu>
);
};

@ -12,7 +12,11 @@ import {
ConversationNotificationSettingType,
} from '../../../models/conversation';
import { useDispatch, useSelector } from 'react-redux';
import { changeNickNameModal, updateConfirmModal } from '../../../state/ducks/modalDialog';
import {
changeNickNameModal,
updateConfirmModal,
updateUserDetailsModal,
} from '../../../state/ducks/modalDialog';
import { SectionType } from '../../../state/ducks/section';
import { getConversationController } from '../../../session/conversations';
import {
@ -242,6 +246,35 @@ export function getLeaveGroupMenuItem(
return null;
}
export function getShowUserDetailsMenuItem(
isPrivate: boolean | undefined,
conversationId: string,
avatarPath: string | null,
userName: string
): JSX.Element | null {
const dispatch = useDispatch();
if (isPrivate) {
return (
<Item
onClick={() => {
dispatch(
updateUserDetailsModal({
conversationId: conversationId,
userName,
authorAvatarPath: avatarPath,
})
);
}}
>
{window.i18n('showUserDetails')}
</Item>
);
}
return null;
}
export function getUpdateGroupNameMenuItem(
isAdmin: boolean | undefined,
isKickedFromGroup: boolean | undefined,

@ -4,9 +4,8 @@ import { SettingsHeader } from './SessionSettingsHeader';
import { SessionSettingListItem } from './SessionSettingListItem';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../SessionButton';
import { PasswordUtil } from '../../../util';
import { ConversationLookupType } from '../../../state/ducks/conversations';
import { StateType } from '../../../state/reducer';
import { getConversationLookup } from '../../../state/selectors/conversations';
import { getBlockedPubkeys } from '../../../state/selectors/conversations';
import { connect } from 'react-redux';
import { getPasswordHash } from '../../../../ts/data/data';
import { shell } from 'electron';
@ -31,9 +30,7 @@ export function getCallMediaPermissionsSettings() {
export interface SettingsViewProps {
category: SessionSettingCategory;
// pass the conversation as props, so our render is called everytime they change.
// we have to do this to make the list refresh on unblock()
conversations?: ConversationLookupType;
blockedNumbers: Array<string>;
}
interface State {
@ -121,13 +118,13 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
/* tslint:disable-next-line:max-func-body-length */
public renderSettingInCategory() {
const { category } = this.props;
const { category, blockedNumbers } = this.props;
let settings: Array<LocalSettingType>;
if (category === SessionSettingCategory.Blocked) {
// special case for blocked user
settings = getBlockedUserSettings();
settings = getBlockedUserSettings(blockedNumbers);
} else {
// Grab initial values from database on startup
// ID corresponds to installGetter parameters in preload.js
@ -151,8 +148,6 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
? storedSetting
: setting.content && setting.content.defaultValue;
if (setting.id.startsWith('call-media')) console.warn('storedSetting call: ', value);
const sliderFn =
setting.type === SessionSettingType.Slider
? (settingValue: any) => window.setSettingValue(setting.id, settingValue)
@ -298,7 +293,7 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
const mapStateToProps = (state: StateType) => {
return {
conversations: getConversationLookup(state),
blockedNumbers: getBlockedPubkeys(state),
};
};

@ -227,7 +227,7 @@ function updateReadStatus(message: MessageModel, conversation: ConversationModel
}
}
function handleSyncedReceipts(message: MessageModel, conversation: ConversationModel) {
async function handleSyncedReceipts(message: MessageModel, conversation: ConversationModel) {
const readReceipts = window.Whisper.ReadReceipts.forMessage(conversation, message);
if (readReceipts.length) {
const readBy = readReceipts.map((receipt: any) => receipt.get('reader'));
@ -245,6 +245,12 @@ function handleSyncedReceipts(message: MessageModel, conversation: ConversationM
}
message.set({ recipients });
// If the newly received message is from us, we assume that we've seen the messages up until that point
const sentTimestamp = message.get('sent_at');
if (sentTimestamp) {
await conversation.markRead(sentTimestamp);
}
}
async function handleRegularMessage(
@ -312,7 +318,7 @@ async function handleRegularMessage(
}
if (type === 'outgoing') {
handleSyncedReceipts(message, conversation);
await handleSyncedReceipts(message, conversation);
}
const conversationActiveAt = conversation.get('active_at');

Loading…
Cancel
Save