Merge pull request #839 from vincentbavitz/clearnet

Stylistic improvements and bug fixes
pull/841/head
Vince 5 years ago committed by GitHub
commit ae3e89ee83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -41,7 +41,6 @@
<script type='text/x-tmpl-mustache' id='two-column'> <script type='text/x-tmpl-mustache' id='two-column'>
<div id='session-toast-container'></div> <div id='session-toast-container'></div>
<div id='session-confirm-container'></div>
<div class='gutter'> <div class='gutter'>
<div class='network-status-container'></div> <div class='network-status-container'></div>
<div class='left-pane-placeholder'></div> <div class='left-pane-placeholder'></div>
@ -156,75 +155,6 @@
</div> </div>
</div> </div>
</script> </script>
<script type='text/x-tmpl-mustache' id='password-change-dialog'>
<div class="content">
{{ #title }}
<h4>{{ title }}</h4>
{{ /title }}
<input type='password' id='old-password' placeholder='Old password' autofocus>
<input type='password' id='new-password' placeholder='New password' autofocus>
<input type='password' id='new-password-confirmation' placeholder='Type in your new password again' autofocus>
<div class='error'></div>
<div class='buttons'>
<button class='cancel' tabindex='2'>{{ cancel }}</button>
<button class='ok' tabindex='1'>{{ ok }}</button>
</div>
</div>
</script>
<script type='text/x-tmpl-mustache' id='nickname-dialog'>
<div class="content">
{{ #title }}
<h4>{{ title }}</h4>
{{ /title }}
<input type='text' name='name' class='name' placeholder='Type a name' autofocus maxlength='25'>
{{ #message }}
<div class='message'>{{ message }}</div>
{{ /message }}
<div class='buttons'>
<button class='cancel' tabindex='2'>{{ cancel }}</button>
<button class='ok' tabindex='1'>{{ ok }}</button>
</div>
</div>
</script>
<script type='text/x-tmpl-mustache' id='device-pairing-words-dialog'>
<div class="content">
<h4>{{ title }}</h4>
<p>{{ secretWords }}</p>
<button id='close'>{{ closeText }}</button>
</div>
</script>
<script type='text/x-tmpl-mustache' id='connecting-to-server-template'>
<div class="content">
{{ #title }}
<h4>{{ title }}</h4>
{{ /title }}
<div class='buttons'>
<button class='cancel' tabindex='2'>{{ cancel }}</button>
</div>
</div>
</script>
<script type='text/x-tmpl-mustache' id='add-server-template'>
<div class="content">
{{ #title }}
<h4>{{ title }}</h4>
{{ /title }}
<input type='text' id='server-url' placeholder='Server Url' autofocus>
<div class='error'></div>
<div class='buttons'>
<button class='cancel' tabindex='2'>{{ cancel }}</button>
<button class='ok' tabindex='1'>{{ ok }}</button>
</div>
</div>
</script>
<script type='text/x-tmpl-mustache' id='qr-code-template'>
<div class="content">
<div id="qr">
</div>
<button class='ok' tabindex='1'>{{ ok }}</button>
</div>
</script>
<script type='text/x-tmpl-mustache' id='identicon-svg'> <script type='text/x-tmpl-mustache' id='identicon-svg'>
<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'> <svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'>
<circle cx='50' cy='50' r='40' fill='{{ color }}' /> <circle cx='50' cy='50' r='40' fill='{{ color }}' />

@ -802,7 +802,7 @@
window.confirmationDialog = params => { window.confirmationDialog = params => {
const confirmDialog = new Whisper.SessionConfirmView({ const confirmDialog = new Whisper.SessionConfirmView({
el: $('#session-confirm-container'), el: $('body'),
title: params.title, title: params.title,
message: params.message, message: params.message,
messageSub: params.messageSub || undefined, messageSub: params.messageSub || undefined,
@ -969,7 +969,7 @@
window.toasts.set( window.toasts.set(
toastID, toastID,
new Whisper.SessionToastView({ new Whisper.SessionToastView({
el: $('#session-toast-container'), el: $('body'),
}) })
); );

@ -181,11 +181,11 @@
}, },
showEditProfileDialog(options) { showEditProfileDialog(options) {
const dialog = new Whisper.EditProfileDialogView(options); const dialog = new Whisper.EditProfileDialogView(options);
this.el.append(dialog.el); this.el.prepend(dialog.el);
}, },
showUserDetailsDialog(options) { showUserDetailsDialog(options) {
const dialog = new Whisper.UserDetailsDialogView(options); const dialog = new Whisper.UserDetailsDialogView(options);
this.el.append(dialog.el); this.el.prepend(dialog.el);
}, },
showNicknameDialog({ pubKey, title, message, nickname, onOk, onCancel }) { showNicknameDialog({ pubKey, title, message, nickname, onOk, onCancel }) {
const _title = title || `Change nickname for ${pubKey}`; const _title = title || `Change nickname for ${pubKey}`;
@ -196,16 +196,16 @@
resolve: onOk, resolve: onOk,
reject: onCancel, reject: onCancel,
}); });
this.el.append(dialog.el); this.el.prepend(dialog.el);
dialog.focusInput(); dialog.focusInput();
}, },
showPasswordDialog(options) { showPasswordDialog(options) {
const dialog = new Whisper.PasswordDialogView(options); const dialog = new Whisper.PasswordDialogView(options);
this.el.append(dialog.el); this.el.prepend(dialog.el);
}, },
showSeedDialog() { showSeedDialog() {
const dialog = new Whisper.SeedDialogView(); const dialog = new Whisper.SeedDialogView();
this.el.append(dialog.el); this.el.prepend(dialog.el);
}, },
showQRDialog(string) { showQRDialog(string) {
const dialog = new Whisper.QRDialogView({ const dialog = new Whisper.QRDialogView({
@ -215,12 +215,11 @@
}, },
showDevicePairingDialog(options) { showDevicePairingDialog(options) {
const dialog = new Whisper.DevicePairingDialogView(options); const dialog = new Whisper.DevicePairingDialogView(options);
this.el.prepend(dialog.el);
this.el.append(dialog.el);
}, },
showDevicePairingWordsDialog() { showDevicePairingWordsDialog() {
const dialog = new Whisper.DevicePairingWordsDialogView(); const dialog = new Whisper.DevicePairingWordsDialogView();
this.el.append(dialog.el); this.el.prepend(dialog.el);
}, },
showCreateGroup() { showCreateGroup() {
// TODO: make it impossible to open 2 dialogs as once // TODO: make it impossible to open 2 dialogs as once
@ -231,7 +230,7 @@
}, },
showUpdateGroupDialog(groupConvo) { showUpdateGroupDialog(groupConvo) {
const dialog = new Whisper.UpdateGroupDialogView(groupConvo); const dialog = new Whisper.UpdateGroupDialogView(groupConvo);
this.el.append(dialog.el); this.el.prepend(dialog.el);
}, },
showSessionRestoreConfirmation(options) { showSessionRestoreConfirmation(options) {
const dialog = new Whisper.ConfirmSessionResetView(options); const dialog = new Whisper.ConfirmSessionResetView(options);

@ -28,12 +28,12 @@
this.$('.session-confirm-wrapper').remove(); this.$('.session-confirm-wrapper').remove();
this.confirmView = new Whisper.ReactWrapperView({ this.confirmView = new Whisper.ReactWrapperView({
className: 'session-confirm-wrapper', className: 'loki-dialog modal session-confirm-wrapper',
Component: window.Signal.Components.SessionConfirm, Component: window.Signal.Components.SessionConfirm,
props: this.props, props: this.props,
}); });
this.$el.append(this.confirmView.el); this.$el.prepend(this.confirmView.el);
}, },
ok() { ok() {

@ -25,7 +25,7 @@
props: this.props, props: this.props,
}); });
this.$el.append(this.toastView.el); this.$el.prepend(this.toastView.el);
}, },
update(options) { update(options) {

@ -67,6 +67,8 @@ window.CONSTANTS = {
MAX_GROUP_NAME_LENGTH: 64, MAX_GROUP_NAME_LENGTH: 64,
DEFAULT_PUBLIC_CHAT_URL: appConfig.get('defaultPublicChatServer'), DEFAULT_PUBLIC_CHAT_URL: appConfig.get('defaultPublicChatServer'),
MAX_CONNECTION_DURATION: 5000, MAX_CONNECTION_DURATION: 5000,
// Limited due to the proof-of-work requirement
SMALL_GROUP_SIZE_LIMIT: 10,
}; };
window.versionInfo = { window.versionInfo = {
@ -492,9 +494,6 @@ window.shortenPubkey = pubkey => `(...${pubkey.substring(pubkey.length - 6)})`;
window.pubkeyPattern = /@[a-fA-F0-9]{64,66}\b/g; window.pubkeyPattern = /@[a-fA-F0-9]{64,66}\b/g;
// Limited due to the proof-of-work requirement
window.SMALL_GROUP_SIZE_LIMIT = 10;
// TODO: activate SealedSender once it is ready on all platforms // TODO: activate SealedSender once it is ready on all platforms
window.lokiFeatureFlags = { window.lokiFeatureFlags = {
multiDeviceUnpairing: true, multiDeviceUnpairing: true,

@ -94,8 +94,10 @@
.friend-selection-list { .friend-selection-list {
max-height: 240px; max-height: 240px;
overflow-y: scroll; overflow-y: auto;
margin: 4px; margin: 4px;
border-top: 1px solid #2f2f2f;
border-bottom: 1px solid #2f2f2f;
.check-mark { .check-mark {
float: right; float: right;

@ -111,7 +111,7 @@ $session-font-h3: 20px;
$session-font-h4: 16px; $session-font-h4: 16px;
$session-search-input-height: 34px; $session-search-input-height: 34px;
$main-view-header-height: 85px; $main-view-header-height: 63px;
$session-left-pane-width: 300px; $session-left-pane-width: 300px;
$session-left-pane-sections-container-width: 80px; $session-left-pane-sections-container-width: 80px;
@ -134,6 +134,12 @@ div.spacer-lg {
color: rgba($color, 0.6); color: rgba($color, 0.6);
} }
// Blur for modals
.loki-dialog ~ .index.inbox {
filter: blur(1px);
transition: filter 0.1s;
}
.text-subtle { .text-subtle {
opacity: 0.6; opacity: 0.6;
} }
@ -224,7 +230,7 @@ $session_message-container-border-radius: 5px;
pointer-events: none; pointer-events: none;
} }
.overlay { .overlay {
display: block !important; display: flex !important;
z-index: 1; z-index: 1;
} }
@ -572,12 +578,15 @@ label {
.message-selection-overlay { .message-selection-overlay {
display: none; display: none;
position: absolute; position: absolute;
right: $session-margin-sm; left: 0px;
left: $session-margin-md; right: 0px;
margin: 0px $session-margin-sm;
align-items: center;
justify-content: space-between;
height: 48px;
.close-button { .close-button {
float: left; float: left;
margin: 17px 0px 0px 0px;
} }
} }
.message-selection-overlay div[role='button'] { .message-selection-overlay div[role='button'] {
@ -586,7 +595,6 @@ label {
.message-selection-overlay .button-group { .message-selection-overlay .button-group {
float: right; float: right;
margin-top: 13.5px;
} }
.hidden { .hidden {
@ -597,7 +605,7 @@ label {
cursor: pointer; cursor: pointer;
} }
#session-toast-container { .session-toast-wrapper {
position: fixed; position: fixed;
right: $session-margin-lg; right: $session-margin-lg;
bottom: $session-margin-lg; bottom: $session-margin-lg;
@ -1285,8 +1293,16 @@ label {
.module-message { .module-message {
font-family: 'SF Pro Text'; font-family: 'SF Pro Text';
border-radius: 5px; border-radius: 5px;
&__text--incoming {
/* Add padding to large emojis in chat */
img.emoji.jumbo {
margin: $session-margin-sm 0px;
} }
} }
}
}
.bottom-bar { .bottom-bar {
.compose { .compose {
@ -1761,3 +1777,8 @@ input {
opacity: 0.8; opacity: 0.8;
} }
} }
.invite-friends-container {
height: $session-icon-size-lg;
width: $session-icon-size-lg;
}

@ -19,7 +19,8 @@
margin: auto; margin: auto;
} }
.session-icon-button { .session-icon-button,
.invite-friends-container {
margin: 0 $session-margin-md; margin: 0 $session-margin-md;
} }
} }

@ -135,7 +135,7 @@ $session-compose-margin: 20px;
} }
.module-left-pane { .module-left-pane {
border-right: none !important; border-right: 1px solid rgba($session-color-white, 0.1) !important;
width: $session-left-pane-width; width: $session-left-pane-width;
position: relative; position: relative;
height: -webkit-fill-available; height: -webkit-fill-available;
@ -213,6 +213,8 @@ $session-compose-margin: 20px;
&__list { &__list {
height: -webkit-fill-available; height: -webkit-fill-available;
border-top: 1px solid rgba(255,255,255,0.05);
&-popup { &-popup {
width: -webkit-fill-available; width: -webkit-fill-available;
height: -webkit-fill-available; height: -webkit-fill-available;
@ -485,6 +487,8 @@ $session-compose-margin: 20px;
flex-grow: 1; flex-grow: 1;
.module-conversation-list-item { .module-conversation-list-item {
background-color: $session-shade-4;
&--has-friend-request { &--has-friend-request {
&:first-child { &:first-child {
border-top: none !important; border-top: none !important;
@ -496,6 +500,11 @@ $session-compose-margin: 20px;
.module-conversation__user__profile-name { .module-conversation__user__profile-name {
font-size: 13px !important; font-size: 13px !important;
} }
}
&__header__date, &__message {
display: none;
} }
&__buttons { &__buttons {
@ -550,11 +559,11 @@ $session-compose-margin: 20px;
} }
&.active { &.active {
background-color: $session-shade-9; background-color: $session-shade-5;
} }
&:hover { &:hover {
background-color: $session-shade-7; background-color: $session-shade-6;
} }
&__buttons { &__buttons {

@ -197,10 +197,10 @@ export class CreateGroupDialog extends React.Component<Props, State> {
if ( if (
updatedFriends.filter(d => d.checkmarked).length > updatedFriends.filter(d => d.checkmarked).length >
window.SMALL_GROUP_SIZE_LIMIT - 1 window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT - 1
) { ) {
const msg = `${this.props.i18n('maxGroupMembersError')} ${ const msg = `${this.props.i18n('maxGroupMembersError')} ${
window.SMALL_GROUP_SIZE_LIMIT window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT
}`; }`;
this.onShowError(msg); this.onShowError(msg);

@ -1,8 +1,11 @@
import React from 'react'; import React from 'react';
import { Contact, MemberList } from './MemberList';
import { SessionModal } from '../session/SessionModal'; import { SessionModal } from '../session/SessionModal';
import { SessionButton } from '../session/SessionButton'; import { SessionButton } from '../session/SessionButton';
import {
ContactType,
SessionMemberListItem,
} from '../session/SessionMemberListItem';
interface Props { interface Props {
friendList: Array<any>; friendList: Array<any>;
@ -11,14 +14,8 @@ interface Props {
onClose: any; onClose: any;
} }
declare global {
interface Window {
i18n: any;
}
}
interface State { interface State {
friendList: Array<Contact>; friendList: Array<ContactType>;
} }
export class InviteFriendsDialog extends React.Component<Props, State> { export class InviteFriendsDialog extends React.Component<Props, State> {
@ -73,14 +70,7 @@ export class InviteFriendsDialog extends React.Component<Props, State> {
> >
<div className="spacer-lg" /> <div className="spacer-lg" />
<div className="friend-selection-list"> <div className="friend-selection-list">{this.renderMemberList()}</div>
<MemberList
members={this.state.friendList}
selected={{}}
i18n={window.i18n}
onMemberClicked={this.onMemberClicked}
/>
</div>
{hasFriends ? null : ( {hasFriends ? null : (
<> <>
<div className="spacer-lg" /> <div className="spacer-lg" />
@ -115,6 +105,23 @@ export class InviteFriendsDialog extends React.Component<Props, State> {
this.closeDialog(); this.closeDialog();
} }
private renderMemberList() {
const members = this.state.friendList;
return members.map((member: ContactType) => (
<SessionMemberListItem
member={member}
isSelected={false}
onSelect={(selectedMember: ContactType) => {
this.onMemberClicked(selectedMember);
}}
onUnselect={(selectedMember: ContactType) => {
this.onMemberClicked(selectedMember);
}}
/>
));
}
private onKeyUp(event: any) { private onKeyUp(event: any) {
switch (event.key) { switch (event.key) {
case 'Enter': case 'Enter':
@ -128,15 +135,9 @@ export class InviteFriendsDialog extends React.Component<Props, State> {
} }
} }
private closeDialog() { private onMemberClicked(clickedMember: ContactType) {
window.removeEventListener('keyup', this.onKeyUp);
this.props.onClose();
}
private onMemberClicked(selected: any) {
const updatedFriends = this.state.friendList.map(member => { const updatedFriends = this.state.friendList.map(member => {
if (member.id === selected.id) { if (member.id === clickedMember.id) {
return { ...member, checkmarked: !member.checkmarked }; return { ...member, checkmarked: !member.checkmarked };
} else { } else {
return member; return member;
@ -150,4 +151,9 @@ export class InviteFriendsDialog extends React.Component<Props, State> {
}; };
}); });
} }
private closeDialog() {
window.removeEventListener('keyup', this.onKeyUp);
this.props.onClose();
}
} }

@ -4,13 +4,6 @@ import { Contact, MemberList } from './MemberList';
import { SessionModal } from './../session/SessionModal'; import { SessionModal } from './../session/SessionModal';
declare global {
interface Window {
SMALL_GROUP_SIZE_LIMIT: number;
Lodash: any;
}
}
interface Props { interface Props {
titleText: string; titleText: string;
groupName: string; groupName: string;
@ -229,9 +222,9 @@ export class UpdateGroupDialog extends React.Component<Props, State> {
const newMemberCount = this.getMemberCount(updatedFriends); const newMemberCount = this.getMemberCount(updatedFriends);
if (newMemberCount > window.SMALL_GROUP_SIZE_LIMIT) { if (newMemberCount > window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT) {
const msg = `${this.props.i18n('maxGroupMembersError')} ${ const msg = `${this.props.i18n('maxGroupMembersError')} ${
window.SMALL_GROUP_SIZE_LIMIT window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT
}`; }`;
this.onShowError(msg); this.onShowError(msg);

@ -76,8 +76,6 @@ export class LeftPaneSettingSection extends React.Component<any, State> {
> >
<div> <div>
<strong>{item.title}</strong> <strong>{item.title}</strong>
<br />
<span className="text-subtle">{item.description}</span>
</div> </div>
<div> <div>
@ -181,31 +179,26 @@ export class LeftPaneSettingSection extends React.Component<any, State> {
{ {
id: SessionSettingCategory.Appearance, id: SessionSettingCategory.Appearance,
title: window.i18n('appearanceSettingsTitle'), title: window.i18n('appearanceSettingsTitle'),
description: window.i18n('appearanceSettingsDescription'),
hidden: false, hidden: false,
}, },
{ {
id: SessionSettingCategory.Privacy, id: SessionSettingCategory.Privacy,
title: window.i18n('privacySettingsTitle'), title: window.i18n('privacySettingsTitle'),
description: window.i18n('privacySettingsDescription'),
hidden: false, hidden: false,
}, },
{ {
id: SessionSettingCategory.Permissions, id: SessionSettingCategory.Permissions,
title: window.i18n('permissionSettingsTitle'), title: window.i18n('permissionSettingsTitle'),
description: window.i18n('permissionSettingsDescription'),
hidden: true, hidden: true,
}, },
{ {
id: SessionSettingCategory.Notifications, id: SessionSettingCategory.Notifications,
title: window.i18n('notificationSettingsTitle'), title: window.i18n('notificationSettingsTitle'),
description: window.i18n('notificationSettingsDescription'),
hidden: false, hidden: false,
}, },
{ {
id: SessionSettingCategory.Devices, id: SessionSettingCategory.Devices,
title: window.i18n('devicesSettingsTitle'), title: window.i18n('devicesSettingsTitle'),
description: window.i18n('devicesSettingsDescription'),
}, },
]; ];
} }

@ -50,6 +50,9 @@ export class SessionChannelSettings extends React.Component<Props, any> {
} }
public componentDidUpdate() { public componentDidUpdate() {
const mediaScanInterval = 1000;
setTimeout(() => {
this.getMediaGalleryProps() this.getMediaGalleryProps()
.then(({ documents, media, onItemClick }) => { .then(({ documents, media, onItemClick }) => {
this.setState({ this.setState({
@ -59,6 +62,7 @@ export class SessionChannelSettings extends React.Component<Props, any> {
}); });
}) })
.ignore(); .ignore();
}, mediaScanInterval);
} }
public async getMediaGalleryProps() { public async getMediaGalleryProps() {
@ -244,6 +248,7 @@ export class SessionChannelSettings extends React.Component<Props, any> {
private renderHeader() { private renderHeader() {
const { id, onGoBack, onInviteFriends, avatarPath } = this.props; const { id, onGoBack, onInviteFriends, avatarPath } = this.props;
const shouldShowInviteFriends = !this.props.isPublic;
return ( return (
<div className="group-settings-header"> <div className="group-settings-header">
@ -259,11 +264,16 @@ export class SessionChannelSettings extends React.Component<Props, any> {
conversationType="group" conversationType="group"
size={80} size={80}
/> />
<div className="invite-friends-container">
{shouldShowInviteFriends && (
<SessionIconButton <SessionIconButton
iconType={SessionIconType.AddUser} iconType={SessionIconType.AddUser}
iconSize={SessionIconSize.Medium} iconSize={SessionIconSize.Medium}
onClick={onInviteFriends} onClick={onInviteFriends}
/> />
)}
</div>
</div> </div>
); );
} }

1
ts/global.d.ts vendored

@ -3,6 +3,7 @@ interface Window {
versionInfo: any; versionInfo: any;
Events: any; Events: any;
Lodash: any;
deleteAllData: any; deleteAllData: any;
clearLocalData: any; clearLocalData: any;
getAccountManager: any; getAccountManager: any;

Loading…
Cancel
Save