Closed group joining completed w/o backend

pull/790/head
Vincent 5 years ago
parent 4fd2126fbe
commit b341ceaf76

@ -1440,7 +1440,8 @@
"description": "Header for notification settings"
},
"readReceiptSettingDescription": {
"message": "See and share when messages have been read (enables read receipts in all sessions).",
"message":
"See and share when messages have been read (enables read receipts in all sessions).",
"description": "Description of the read receipts setting"
},
"readReceiptSettingTitle": {
@ -2728,7 +2729,8 @@
"message": "Create Closed Group"
},
"createClosedGroupDescription": {
"message": "Closed groups are end-to-end encrypted group chats for up to 10 members. They provide the same privacy protections as one-on-one sessions."
"message":
"Closed groups are end-to-end encrypted group chats for up to 10 members. They provide the same privacy protections as one-on-one sessions."
},
"createClosedGroupNamePrompt": {
"message": "Group Name"

@ -987,7 +987,6 @@
return toastID;
};
window.getFriendsFromContacts = contacts => {
// To call from TypeScript, input / output are both
// of type Array<ConversationType>
@ -998,7 +997,7 @@
);
}
return friendList;
}
};
// Get memberlist. This function is not accurate >>
// window.getMemberList = window.lokiPublicChatAPI.getListOfMembers();

@ -496,7 +496,9 @@ class LokiAppDotNetServerAPI {
));
} else {
// disable check for .loki
process.env.NODE_TLS_REJECT_UNAUTHORIZED = endpoint.match(/\.loki\//) ? 0 : 1;
process.env.NODE_TLS_REJECT_UNAUTHORIZED = endpoint.match(/\.loki\//)
? 0
: 1;
result = await nodeFetch(url, fetchOptions);
// always make sure this check is enabled
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 1;
@ -505,7 +507,12 @@ class LokiAppDotNetServerAPI {
}
} catch (e) {
if (txtResponse) {
log.info(`serverRequest ${mode} error`, e.code, e.message, `json: ${txtResponse}`);
log.info(
`serverRequest ${mode} error`,
e.code,
e.message,
`json: ${txtResponse}`
);
} else {
log.info(`serverRequest ${mode} error`, e.code, e.message);
}

@ -1683,15 +1683,13 @@ input {
}
}
.group-member-list {
&__container {
padding: 2px 0px;
width: 100%;
max-height: 400px;
overflow-y: auto;
box-shadow:
inset 0px 14px 7px -15px $session-color-dark-grey,
box-shadow: inset 0px 14px 7px -15px $session-color-dark-grey,
inset 0px -14px 7px -15px $session-color-dark-grey;
}
@ -1699,7 +1697,6 @@ input {
height: 100%;
display: flex;
flex-direction: column;
}
}
.create-group-name-input {
@ -1708,14 +1705,13 @@ input {
textarea {
padding-bottom: 0px !important;
}
}
}
}
.session-member-item {
font-family: "SF Pro Text";
cursor: pointer;
font-family: 'SF Pro Text';
padding: 0px $session-margin-sm;
height: 50px;
display: flex;
@ -1726,17 +1722,17 @@ input {
background-color: $session-shade-4;
}
&__checkmark {
opacity: 0;
transition: $session-transition-duration;
&.selected{
&.selected {
opacity: 1;
}
}
&__info, &__checkmark{
&__info,
&__checkmark {
display: flex;
align-items: center;
}
@ -1749,4 +1745,4 @@ input {
margin-left: 5px;
opacity: 0.8;
}
}
}

@ -271,8 +271,8 @@ $session-compose-margin: 20px;
position: relative;
height: 1px;
opacity: 0.3;
margin-top: -10px;
margin-bottom: 50px;
margin-top: 2px;
margin-bottom: 40px;
}
.exit {
@ -291,10 +291,9 @@ $session-compose-margin: 20px;
}
.session-description-long {
<<<<<<<headfont-size: $session-font-sm;
font-size: $session-font-sm;
line-height: $session-font-h3;
=======font-size: 13px;
>>>>>>>9732c4f4d074c1024f308cf7369fc535c26724b4margin: 0px 20px;
margin: 0px 20px;
font-family: 'SF Pro Display';
}

@ -96,7 +96,7 @@ export class CreateGroupDialog extends React.Component<Props, State> {
return (
<SessionModal title={titleText} onClose={() => null} onOk={() => null}>
<div className="spacer-lg"></div>
<div className="spacer-lg" />
<p className={errorMessageClasses}>{this.state.errorMessage}</p>
<input
@ -120,8 +120,8 @@ export class CreateGroupDialog extends React.Component<Props, State> {
/>
</div>
<div className="spacer-lg"></div>
<div className="spacer-lg" />
<div className="buttons">
<button className="cancel" tabIndex={0} onClick={this.closeDialog}>
{cancelText}

@ -32,9 +32,6 @@ export class InviteFriendsDialog extends React.Component<Props, State> {
let friends = this.props.friendList;
console.log("Contacts from invitefriendsDialog before filter::");
console.log(friends);
friends = friends.map(d => {
const lokiProfile = d.getLokiProfile();
const name = lokiProfile ? lokiProfile.displayName : 'Anonymous';
@ -54,9 +51,6 @@ export class InviteFriendsDialog extends React.Component<Props, State> {
};
});
console.log("Ideal friends list from inviteDialog");
console.log(friends);
this.state = {
friendList: friends,
};
@ -77,8 +71,8 @@ export class InviteFriendsDialog extends React.Component<Props, State> {
onOk={() => null}
onClose={this.closeDialog}
>
<div className="spacer-lg"></div>
<div className="spacer-lg" />
<div className="friend-selection-list">
<MemberList
members={this.state.friendList}
@ -95,7 +89,7 @@ export class InviteFriendsDialog extends React.Component<Props, State> {
</>
)}
<div className="spacer-lg"></div>
<div className="spacer-lg" />
<div className="session-modal__button-group">
<SessionButton text={cancelText} onClick={this.closeDialog} />

@ -274,7 +274,6 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
this.setState({
groupAddType: undefined,
});
break;
}
}
@ -286,7 +285,9 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
<SessionClosableOverlay
overlayMode={SessionGroupType.Open}
onChangeSessionID={this.handleOnPasteUrl}
onCloseClick={() => this.handleToggleOverlay(undefined)}
onCloseClick={() => {
this.handleToggleOverlay(undefined);
}}
onButtonClick={this.handleJoinChannelButtonClick}
searchTerm={searchTerm}
updateSearch={this.updateSearchBound}
@ -298,22 +299,22 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
<SessionClosableOverlay
overlayMode={SessionGroupType.Closed}
onChangeSessionID={this.handleOnPasteUrl}
onCloseClick={() => this.handleToggleOverlay(undefined)}
onButtonClick={(groupName: string, groupMembers: Array<ContactType>) =>
this.onCreateClosedGroup(groupName, groupMembers)
}
onCloseClick={() => {
this.handleToggleOverlay(undefined);
}}
onButtonClick={async (
groupName: string,
groupMembers: Array<ContactType>
) => this.onCreateClosedGroup(groupName, groupMembers)}
searchTerm={searchTerm}
updateSearch={this.updateSearchBound}
showSpinner={loading}
/>
);
const renderElement =
groupType === SessionGroupType.Open
? openGroupElement
: closedGroupElement;
return renderElement;
return groupType === SessionGroupType.Open
? openGroupElement
: closedGroupElement;
}
private renderBottomButtons(): JSX.Element {
@ -336,13 +337,17 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
text={joinOpenGroup}
buttonType={SessionButtonType.SquareOutline}
buttonColor={SessionButtonColor.Green}
onClick={() => this.handleToggleOverlay(SessionGroupType.Open)}
onClick={() => {
this.handleToggleOverlay(SessionGroupType.Open);
}}
/>
<SessionButton
text={createClosedGroup}
buttonType={SessionButtonType.SquareOutline}
buttonColor={SessionButtonColor.White}
onClick={() => this.handleToggleOverlay(SessionGroupType.Closed)}
onClick={() => {
this.handleToggleOverlay(SessionGroupType.Closed);
}}
/>
</div>
);
@ -381,11 +386,9 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
return false;
}
joinChannelStateManager(
this,
channelUrlPasted,
this.handleToggleOverlay(SessionGroupType.Open)
);
joinChannelStateManager(this, channelUrlPasted, () => {
this.handleToggleOverlay(SessionGroupType.Open);
});
return true;
}

@ -322,7 +322,7 @@ export class LeftPaneContactSection extends React.Component<Props, State> {
private renderList() {
const { sentFriendsRequest } = this.props;
const friends = window.getFriendsFromContacts(this.props.friends);
const length = sentFriendsRequest.length + friends.length;
const length = Number(sentFriendsRequest.length) + Number(friends.length);
const combined = [...sentFriendsRequest, ...friends];
const list = (

@ -40,10 +40,9 @@ export class SessionClosableOverlay extends React.Component<Props, State> {
groupName: '',
selectedMembers: [],
};
this.inputRef = React.createRef();
this.onGroupNameChanged = this.onGroupNameChanged.bind(this);
}
public componentDidMount() {
@ -52,18 +51,17 @@ export class SessionClosableOverlay extends React.Component<Props, State> {
}
}
public getContacts() {
const conversations = window.getConversations();
let conversationList = conversations;
if (conversationList !== undefined) {
conversationList = conversationList.filter((conv: any) => {
return !conv.isRss() && !conv.isPublic() && conv.attributes.lastMessage
conversationList = conversationList.filter((conv: any) => {
return !conv.isRss() && !conv.isPublic() && conv.attributes.lastMessage;
});
}
let friends = conversationList.map((d: any) => {
const friends = conversationList.map((d: any) => {
const lokiProfile = d.getLokiProfile();
const name = lokiProfile ? lokiProfile.displayName : 'Anonymous';
@ -154,49 +152,48 @@ export class SessionClosableOverlay extends React.Component<Props, State> {
/>
</div>
<div className="spacer-md"></div>
<div className="spacer-md" />
<h2>{title}</h2>
<h3>{subtitle}</h3>
<div className="module-left-pane-overlay-border-container">
<hr className="white" />
<hr className="green" />
</div>
{ (isOpenGroupView || isClosedGroupView) ?
(
<div className="create-group-name-input">
<SessionIdEditable
ref={this.inputRef}
editable={true}
placeholder={placeholder}
value={this.state.groupName}
maxLength={window.CONSTANTS.MAX_GROUPNAME_LENGTH}
onChange={this.onGroupNameChanged}
/>
</div>
) : (
<h3>
{subtitle}
<hr className="green-border" />
</h3>
<hr className="white-border" />
{isOpenGroupView || isClosedGroupView ? (
<div className="create-group-name-input">
<SessionIdEditable
ref={this.inputRef}
editable={true}
placeholder={placeholder}
onChange={onChangeSessionID}
value={this.state.groupName}
maxLength={window.CONSTANTS.MAX_GROUPNAME_LENGTH}
onChange={this.onGroupNameChanged}
/>
)
}
</div>
) : (
<SessionIdEditable
ref={this.inputRef}
editable={true}
placeholder={placeholder}
onChange={onChangeSessionID}
/>
)}
{showSpinner && <SessionSpinner />}
{isClosedGroupView && (
<>
<div className="spacer-lg"></div>
<div className="spacer-lg" />
<div className="group-member-list__container">
<div className="group-member-list__selection">
{this.renderMemberList()}
</div>
</div>
<div className="spacer-lg"></div>
<div className="spacer-lg" />
</>
)}
@ -240,33 +237,36 @@ export class SessionClosableOverlay extends React.Component<Props, State> {
const members = this.getContacts();
const memberList = members.map((member: ContactType) => (
<SessionMemberListItem
member={member}
isSelected={false}
onSelect={(member: ContactType) => this.handleSelectMember(member)}
onUnselect={(member: ContactType) => this.handleUnselectMember(member)}
/>
)
);
<SessionMemberListItem
member={member}
isSelected={false}
onSelect={(selectedMember: ContactType) => {
this.handleSelectMember(selectedMember);
}}
onUnselect={(selectedMember: ContactType) => {
this.handleUnselectMember(selectedMember);
}}
/>
));
return memberList;
}
private handleSelectMember(member: ContactType){
if (this.state.selectedMembers.includes(member)){
private handleSelectMember(member: ContactType) {
if (this.state.selectedMembers.includes(member)) {
return;
}
this.setState({
selectedMembers: [...this.state.selectedMembers, member]
selectedMembers: [...this.state.selectedMembers, member],
});
}
private handleUnselectMember(member: ContactType){
private handleUnselectMember(member: ContactType) {
this.setState({
selectedMembers: this.state.selectedMembers.filter(selectedMember => {
return selectedMember !== member;
})
}),
});
}

@ -28,7 +28,7 @@ export class SessionIdEditable extends React.PureComponent<Props> {
}
public render() {
const { placeholder, editable, text, value, maxLength} = this.props;
const { placeholder, editable, text, value, maxLength } = this.props;
return (
<div

@ -2,31 +2,29 @@ import React from 'react';
import classNames from 'classnames';
import { Avatar } from '../Avatar';
import { SessionIcon, SessionIconType, SessionIconSize } from './icon';
import { SessionIcon, SessionIconSize, SessionIconType } from './icon';
export interface ContactType {
id: string;
selected: boolean;
authorProfileName: string;
authorPhoneNumber: string;
authorName: string;
authorColor: any;
authorAvatarPath: string;
checkmarked: boolean;
existingMember: boolean;
id: string;
selected: boolean;
authorProfileName: string;
authorPhoneNumber: string;
authorName: string;
authorColor: any;
authorAvatarPath: string;
checkmarked: boolean;
existingMember: boolean;
}
interface Props {
member: ContactType;
isSelected: boolean;
onSelect?: any;
onUnselect?: any;
member: ContactType;
isSelected: boolean;
onSelect?: any;
onUnselect?: any;
}
interface State {
isSelected: boolean;
isSelected: boolean;
}
export class SessionMemberListItem extends React.Component<Props, State> {
@ -38,7 +36,7 @@ export class SessionMemberListItem extends React.Component<Props, State> {
super(props);
this.state = {
isSelected: this.props.isSelected,
isSelected: this.props.isSelected,
};
this.handleSelectionAction = this.handleSelectionAction.bind(this);
@ -55,23 +53,31 @@ export class SessionMemberListItem extends React.Component<Props, State> {
const shortPubkey = window.shortenPubkey(pubkey);
return (
<div
className={classNames('session-member-item', isSelected && 'selected')}
onClick={this.handleSelectionAction}
>
<div className="session-member-item__info">
<span className="session-member-item__avatar">{this.renderAvatar()}</span>
<span className="session-member-item__name">{name}</span>
<span className="session-member-item__pubkey">{shortPubkey}</span>
</div>
<span className={classNames('session-member-item__checkmark', isSelected && 'selected')}>
<SessionIcon
iconType={SessionIconType.Check}
iconSize={SessionIconSize.Medium}
iconColor={"#00f782"}
/>
</span>
<div
className={classNames('session-member-item', isSelected && 'selected')}
onClick={this.handleSelectionAction}
role="button"
>
<div className="session-member-item__info">
<span className="session-member-item__avatar">
{this.renderAvatar()}
</span>
<span className="session-member-item__name">{name}</span>
<span className="session-member-item__pubkey">{shortPubkey}</span>
</div>
<span
className={classNames(
'session-member-item__checkmark',
isSelected && 'selected'
)}
>
<SessionIcon
iconType={SessionIconType.Check}
iconSize={SessionIconSize.Medium}
iconColor={'#00f782'}
/>
</span>
</div>
);
}
@ -92,32 +98,31 @@ export class SessionMemberListItem extends React.Component<Props, State> {
private handleSelectionAction() {
if (this.state.isSelected) {
this.unselectMember();
return;
this.unselectMember();
return;
}
this.selectMember();
}
private selectMember() {
this.setState({
isSelected: true,
});
this.setState({
isSelected: true,
});
if (this.props.onSelect){
this.props.onSelect(this.props.member);
}
if (this.props.onSelect) {
this.props.onSelect(this.props.member);
}
}
private unselectMember() {
this.setState({
isSelected: false,
isSelected: false,
});
if (this.props.onUnselect){
this.props.onUnselect(this.props.member);
if (this.props.onUnselect) {
this.props.onUnselect(this.props.member);
}
}
}
}

Loading…
Cancel
Save