CLosed groups ui initial listprops

pull/790/head
Vincent 4 years ago
parent 8ba78df919
commit de4edf9252

@ -1105,7 +1105,7 @@
"Placeholder text in the message entry field when it is disabled while we are waiting for a friend request approval"
},
"sendMessageFriendRequest": {
"message": "Hi there! This is ...!",
"message": "Send your first message",
"description":
"Placeholder text in the message entry field when it is the first message sent to that contact"
},
@ -1437,7 +1437,7 @@
"description": "Header for notification settings"
},
"readReceiptSettingDescription": {
"message": "Enable the sending and receiving of read receipts",
"message": "See and share when messages have been read (enables read receipts in all sessions).",
"description": "Description of the read receipts setting"
},
"readReceiptSettingTitle": {
@ -2605,6 +2605,9 @@
"message": "Complete Sign Up"
},
"compose": {
"message": "Compose"
},
"newSession": {
"message": "New Session"
},
"searchForAKeyPhrase": {
@ -2650,11 +2653,11 @@
"decline": {
"message": "Decline"
},
"generalSettingsTitle": {
"message": "General"
"appearanceSettingsTitle": {
"message": "Appearance"
},
"generalSettingsDescription": {
"message": "General settings and configuration"
"appearanceSettingsDescription": {
"message": "Appearance and interface options"
},
"accountSettingsTitle": {
"message": "Account"
@ -2678,13 +2681,13 @@
"message": "Notifications"
},
"notificationSettingsDescription": {
"message": "Choose what you're notified about"
"message": "Configure notification options"
},
"devicesSettingsTitle": {
"message": "Devices"
},
"devicesSettingsDescription": {
"message": "Manage linked devices"
"message": "Manage your linked devices"
},
"mnemonicEmpty": {
"message": "Seed is mandatory"
@ -2713,11 +2716,26 @@
"addChannel": {
"message": "Join Open Group"
},
"joinOpenGroup": {
"message": "Join Open Group"
},
"createClosedGroup": {
"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."
},
"createClosedGroupNamePrompt": {
"message": "Group Name"
},
"createClosedGroupPlaceholder": {
"message": "Enter a group name"
},
"enterChannelURL": {
"message": "Enter Open Group URL"
},
"channelUrlPlaceholder": {
"message": "https://chat.lokinet.org"
"message": "chat.getsession.org"
},
"addChannelDescription": {
"message": "Enter an open group URL."

@ -902,7 +902,7 @@ async function updateToLokiSchemaVersion1(currentVersion, instance) {
rssFeed: 'https://loki.network/feed/',
closable: true,
name: 'Loki.network News',
profileAvatar: 'images/loki/session_icon.png',
profileAvatar: 'images/session/session_chat_icon.png',
};
const updatesRssFeedData = {
@ -911,7 +911,7 @@ async function updateToLokiSchemaVersion1(currentVersion, instance) {
rssFeed: 'https://loki.network/category/messenger-updates/feed/',
closable: false,
name: 'Messenger updates',
profileAvatar: 'images/loki/session_icon.png',
profileAvatar: 'images/session/session_chat_icon.png',
};
const autoJoinLokiChats = false;

@ -35,6 +35,6 @@
"-----BEGIN CERTIFICATE-----\nMIID7zCCAtegAwIBAgIJAIm6LatK5PNiMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j\naXNjbzEdMBsGA1UECgwUT3BlbiBXaGlzcGVyIFN5c3RlbXMxHTAbBgNVBAsMFE9w\nZW4gV2hpc3BlciBTeXN0ZW1zMRMwEQYDVQQDDApUZXh0U2VjdXJlMB4XDTEzMDMy\nNTIyMTgzNVoXDTIzMDMyMzIyMTgzNVowgY0xCzAJBgNVBAYTAlVTMRMwEQYDVQQI\nDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMR0wGwYDVQQKDBRP\ncGVuIFdoaXNwZXIgU3lzdGVtczEdMBsGA1UECwwUT3BlbiBXaGlzcGVyIFN5c3Rl\nbXMxEzARBgNVBAMMClRleHRTZWN1cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQDBSWBpOCBDF0i4q2d4jAXkSXUGpbeWugVPQCjaL6qD9QDOxeW1afvf\nPo863i6Crq1KDxHpB36EwzVcjwLkFTIMeo7t9s1FQolAt3mErV2U0vie6Ves+yj6\ngrSfxwIDAcdsKmI0a1SQCZlr3Q1tcHAkAKFRxYNawADyps5B+Zmqcgf653TXS5/0\nIPPQLocLn8GWLwOYNnYfBvILKDMItmZTtEbucdigxEA9mfIvvHADEbteLtVgwBm9\nR5vVvtwrD6CCxI3pgH7EH7kMP0Od93wLisvn1yhHY7FuYlrkYqdkMvWUrKoASVw4\njb69vaeJCUdU+HCoXOSP1PQcL6WenNCHAgMBAAGjUDBOMB0GA1UdDgQWBBQBixjx\nP/s5GURuhYa+lGUypzI8kDAfBgNVHSMEGDAWgBQBixjxP/s5GURuhYa+lGUypzI8\nkDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQB+Hr4hC56m0LvJAu1R\nK6NuPDbTMEN7/jMojFHxH4P3XPFfupjR+bkDq0pPOU6JjIxnrD1XD/EVmTTaTVY5\niOheyv7UzJOefb2pLOc9qsuvI4fnaESh9bhzln+LXxtCrRPGhkxA1IMIo3J/s2WF\n/KVYZyciu6b4ubJ91XPAuBNZwImug7/srWvbpk0hq6A6z140WTVSKtJG7EP41kJe\n/oF4usY5J7LPkxK3LWzMJnb5EIJDmRvyH8pyRwWg6Qm6qiGFaI4nL8QU4La1x2en\n4DGXRaLMPRwjELNgQPodR38zoCMuA8gHZfZYYoZ7D7Q1wNUiVHcxuFrEeBaYJbLE\nrwLV\n-----END CERTIFICATE-----\n",
"import": false,
"serverTrustRoot": "BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx",
"defaultPublicChatServer": "https://chat.lokinet.org/",
"defaultPublicChatServer": "https://chat.getsession.org",
"defaultFileServer": "https://file.lokinet.org"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

@ -121,7 +121,6 @@
'x.svg',
'x_white.svg',
'icon-paste.svg',
'loki/loki_icon_text.png',
'loki/session_icon_128.png',
]);
@ -988,6 +987,19 @@
return toastID;
};
window.getFriendsFromContacts = contacts => {
// To call from TypeScript, input / output are both
// of type Array<ConversationType>
let friendList = contacts;
if (friendList !== undefined) {
friendList = friendList.filter(
friend => friend.type === 'direct' && !friend.isMe
);
}
return friendList;
}
// Get memberlist. This function is not accurate >>
// window.getMemberList = window.lokiPublicChatAPI.getListOfMembers();

@ -347,7 +347,7 @@ $session_message-container-border-radius: 5px;
min-width: 165px;
height: 45px;
line-height: 40px;
padding: 0;
padding: 0px $session-margin-lg;
font-size: $session-font-md;
font-family: $session-font-family;
border-radius: 500px;
@ -553,6 +553,11 @@ label {
position: relative;
}
.module-left-pane-overlay {
h3 {
margin-bottom: 6px;
}
}
.message-selection-overlay {
display: none;
position: absolute;
@ -1380,6 +1385,7 @@ input {
background-color: $session-shade-4;
border: $session-separator-element-border;
display: flex;
align-items: center;
transition: $session-transition-duration;
.module-avatar,

@ -292,7 +292,8 @@ $session-compose-margin: 20px;
}
.session-description-long {
font-size: 14px;
font-size: $session-font-sm;
line-height: $session-font-h3;
margin: 0px 20px;
}

@ -177,6 +177,7 @@ export class LeftPane extends React.Component<Props, State> {
private renderChannelSection() {
const {
friends,
openConversationInternal,
conversations,
searchResults,
@ -189,6 +190,7 @@ export class LeftPane extends React.Component<Props, State> {
return (
<LeftPaneChannelSection
friends={friends}
openConversationInternal={openConversationInternal}
conversations={conversations}
searchResults={searchResults}

@ -23,7 +23,7 @@ export class GroupInvitation extends React.Component<Props> {
<div className="contents">
<img
alt="group-avatar"
src="images/loki/session_icon.png"
src="images/session/session_chat_icon.png"
className="invite-group-avatar"
/>
<span className="group-details">

@ -19,14 +19,16 @@ import {
import { SearchOptions } from '../../types/Search';
import { debounce } from 'lodash';
import { cleanSearchTerm } from '../../util/cleanSearchTerm';
import { ConversationType } from '../../state/ducks/conversations';
import { SessionSearchInput } from './SessionSearchInput';
import { SessionClosableOverlay } from './SessionClosableOverlay';
import { MainViewController } from '../MainViewController';
export interface Props {
friends: Array<ConversationType>;
searchTerm: string;
isSecondaryDevice: boolean;
conversations?: Array<ConversationListItemPropsType>;
searchResults?: SearchResultsProps;
@ -37,11 +39,17 @@ export interface Props {
clearSearch: () => void;
}
export enum SessionGroupType {
Open = 'open-group',
Closed = 'closed-group',
}
interface State {
showAddChannelView: boolean;
channelUrlPasted: string;
loading: boolean;
connectSuccess: boolean;
// The type of group that is being added. Undefined in default view.
groupAddType: SessionGroupType | undefined;
}
export class LeftPaneChannelSection extends React.Component<Props, State> {
@ -51,10 +59,10 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
public constructor(props: Props) {
super(props);
this.state = {
showAddChannelView: false,
channelUrlPasted: '',
loading: false,
connectSuccess: false,
groupAddType: undefined,
};
this.handleOnPasteUrl = this.handleOnPasteUrl.bind(this);
@ -178,12 +186,14 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
}
public render(): JSX.Element {
return (
<div className="session-left-pane-section-content">
{this.renderHeader()}
{this.state.showAddChannelView
? this.renderClosableOverlay()
: this.renderGroups()}
{this.state.groupAddType
? this.renderClosableOverlay(this.state.groupAddType)
: this.renderGroups()
}
</div>
);
}
@ -247,32 +257,68 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
}
}
private handleToggleOverlay() {
this.setState(prevState => ({
showAddChannelView: !prevState.showAddChannelView,
}));
private handleToggleOverlay(groupType?: SessionGroupType) {
// If no groupType, return to default view.
// Close the overlay with handleToggleOverlay(undefined)
switch (groupType) {
case SessionGroupType.Open:
this.setState({
groupAddType: SessionGroupType.Open,
});
break;
case SessionGroupType.Closed:
this.setState({
groupAddType: SessionGroupType.Closed,
});
break;
default:
// Exit overlay
this.setState({
groupAddType: undefined,
});
break;
}
}
private renderClosableOverlay() {
const { searchTerm } = this.props;
private renderClosableOverlay(groupType: SessionGroupType) {
const { searchTerm, friends } = this.props;
const { loading } = this.state;
return (
const openGroupElement = (
<SessionClosableOverlay
overlayMode="channel"
overlayMode={SessionGroupType.Open}
onChangeSessionID={this.handleOnPasteUrl}
onCloseClick={this.handleToggleOverlay}
onCloseClick={() => this.handleToggleOverlay(undefined)}
onButtonClick={this.handleJoinChannelButtonClick}
searchTerm={searchTerm}
updateSearch={this.updateSearchBound}
showSpinner={loading}
/>
);
const closedGroupElement = (
<SessionClosableOverlay
friends={friends}
overlayMode={SessionGroupType.Closed}
onChangeSessionID={this.handleOnPasteUrl}
onCloseClick={() => this.handleToggleOverlay(undefined)}
onButtonClick={this.handleCreateClosedGroupButtonClick}
searchTerm={searchTerm}
updateSearch={this.updateSearchBound}
showSpinner={loading}
/>
);
const renderElement = groupType === SessionGroupType.Open ? openGroupElement : closedGroupElement;
return renderElement;
}
private renderBottomButtons(): JSX.Element {
const edit = window.i18n('edit');
const addChannel = window.i18n('addChannel');
const joinOpenGroup = window.i18n('joinOpenGroup');
const createClosedGroup = window.i18n('createClosedGroup');
const showEditButton = false;
return (
@ -284,11 +330,18 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
buttonColor={SessionButtonColor.White}
/>
)}
<SessionButton
text={addChannel}
text={joinOpenGroup}
buttonType={SessionButtonType.SquareOutline}
buttonColor={SessionButtonColor.Green}
onClick={this.handleToggleOverlay}
onClick={() => this.handleToggleOverlay(SessionGroupType.Open)}
/>
<SessionButton
text={createClosedGroup}
buttonType={SessionButtonType.SquareOutline}
buttonColor={SessionButtonColor.White}
onClick={() => this.handleToggleOverlay(SessionGroupType.Closed)}
/>
</div>
);
@ -327,8 +380,14 @@ export class LeftPaneChannelSection extends React.Component<Props, State> {
return false;
}
joinChannelStateManager(this, channelUrlPasted, this.handleToggleOverlay);
joinChannelStateManager(this, channelUrlPasted, this.handleToggleOverlay(SessionGroupType.Open));
return true;
}
private handleCreateClosedGroupButtonClick() {
alert("creating closed group!");
return true;
}
}

@ -140,7 +140,7 @@ export class LeftPaneContactSection extends React.Component<Props, State> {
style,
}: RowRendererParamsType): JSX.Element | undefined => {
const { sentFriendsRequest } = this.props;
const friends = this.getCurrentFriends();
const friends = window.getFriendsFromContacts(this.props.friends);
const combined = [...sentFriendsRequest, ...friends];
const item = combined[index];
@ -211,19 +211,6 @@ export class LeftPaneContactSection extends React.Component<Props, State> {
);
}
private getCurrentFriends(): Array<ConversationType> {
const { friends } = this.props;
let friendList = friends;
if (friendList !== undefined) {
friendList = friendList.filter(
friend => friend.type === 'direct' && !friend.isMe
);
}
return friendList;
}
private handleToggleOverlay() {
this.setState((prevState: { showAddContactView: boolean }) => ({
showAddContactView: !prevState.showAddContactView,
@ -334,7 +321,7 @@ export class LeftPaneContactSection extends React.Component<Props, State> {
private renderList() {
const { sentFriendsRequest } = this.props;
const friends = this.getCurrentFriends();
const friends = window.getFriendsFromContacts(this.props.friends);
const length = sentFriendsRequest.length + friends.length;
const combined = [...sentFriendsRequest, ...friends];

@ -191,7 +191,7 @@ export class LeftPaneMessageSection extends React.Component<Props, any> {
return LeftPane.RENDER_HEADER(
labels,
null,
window.i18n('compose'),
window.i18n('newSession'),
this.handleToggleOverlay
);
}

@ -82,7 +82,7 @@ export class LeftPaneSectionHeader extends React.Component<Props, State> {
if (buttonLabel) {
children.push(
<SessionButton
text={window.i18n('compose')}
text={window.i18n('newSession')}
onClick={buttonClicked}
key="compose"
disabled={false}

@ -25,7 +25,7 @@ export class LeftPaneSettingSection extends React.Component<any, State> {
super(props);
this.state = {
settingCategory: SessionSettingCategory.General,
settingCategory: SessionSettingCategory.Appearance,
searchQuery: '',
};
@ -179,9 +179,9 @@ export class LeftPaneSettingSection extends React.Component<any, State> {
public getCategories() {
return [
{
id: SessionSettingCategory.General,
title: window.i18n('generalSettingsTitle'),
description: window.i18n('generalSettingsDescription'),
id: SessionSettingCategory.Appearance,
title: window.i18n('appearanceSettingsTitle'),
description: window.i18n('appearanceSettingsDescription'),
hidden: false,
},
{

@ -3,18 +3,22 @@ import React from 'react';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { SessionIdEditable } from './SessionIdEditable';
import { UserSearchDropdown } from './UserSearchDropdown';
import { MemberList } from '../conversation/MemberList';
import { ConversationType } from '../../state/ducks/conversations';
import {
SessionButton,
SessionButtonColor,
SessionButtonType,
} from './SessionButton';
import { SessionSpinner } from './SessionSpinner';
import { SessionGroupType } from './LeftPaneChannelSection';
interface Props {
overlayMode: 'message' | 'contact' | 'channel';
overlayMode: 'message' | 'contact' | SessionGroupType;
onChangeSessionID: any;
onCloseClick: any;
onButtonClick: any;
friends?: Array<ConversationType>;
searchTerm?: string;
searchResults?: any;
updateSearch?: any;
@ -50,7 +54,9 @@ export class SessionClosableOverlay extends React.Component<Props> {
const isAddContactView = overlayMode === 'contact';
const isMessageView = overlayMode === 'message';
// const isChannelView = overlayMode === 'channel';
// const isOpenGroupView = overlayMode === SessionGroupType.Open;
const isClosedGroupView = overlayMode === SessionGroupType.Closed;
let title;
let buttonText;
@ -59,7 +65,7 @@ export class SessionClosableOverlay extends React.Component<Props> {
let placeholder;
switch (overlayMode) {
case 'message':
title = window.i18n('enterRecipient');
title = window.i18n('newSession');
buttonText = window.i18n('next');
descriptionLong = window.i18n('usersCanShareTheir...');
subtitle = window.i18n('enterSessionID');
@ -72,16 +78,28 @@ export class SessionClosableOverlay extends React.Component<Props> {
subtitle = window.i18n('enterSessionID');
placeholder = window.i18n('pasteSessionIDRecipient');
break;
case 'channel':
default:
case 'open-group':
title = window.i18n('addChannel');
buttonText = window.i18n('joinChannel');
descriptionLong = window.i18n('addChannelDescription');
subtitle = window.i18n('enterChannelURL');
placeholder = window.i18n('channelUrlPlaceholder');
break;
case 'closed-group':
title = window.i18n('createClosedGroup');
buttonText = window.i18n('createClosedGroup');
descriptionLong = window.i18n('createClosedGroupDescription');
subtitle = window.i18n('createClosedGroupNamePrompt');
placeholder = window.i18n('createClosedGroupPlaceholder');
break;
default:
break;
}
const ourSessionID = window.textsecure.storage.user.getNumber();
const friends = window.getFriendsFromContacts(this.props.friends);
console.log(this.props.friends);
console.log(window.getFriendsFromContacts(this.props.friends));
return (
<div className="module-left-pane-overlay">
@ -105,6 +123,18 @@ export class SessionClosableOverlay extends React.Component<Props> {
onChange={onChangeSessionID}
/>
{showSpinner && <SessionSpinner />}
{isClosedGroupView && (
<div className="friend-selection-list">
<MemberList
members={friends}
selected={{}}
i18n={window.i18n}
onMemberClicked={() => null }//this.onMemberClicked}
/>
</div>
)}
<div className="session-description-long">{descriptionLong}</div>
{isMessageView && <h4>{window.i18n('or')}</h4>}
@ -130,6 +160,7 @@ export class SessionClosableOverlay extends React.Component<Props> {
text={ourSessionID}
/>
)}
<SessionButton
buttonColor={SessionButtonColor.Green}
buttonType={SessionButtonType.BrandOutline}

@ -9,7 +9,7 @@ import {
} from '../SessionButton';
export enum SessionSettingCategory {
General = 'general',
Appearance = 'appearance',
Account = 'account',
Privacy = 'privacy',
Permissions = 'permissions',
@ -326,7 +326,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
hidden: true,
comparisonValue: 'light',
type: SessionSettingType.Toggle,
category: SessionSettingCategory.General,
category: SessionSettingCategory.Appearance,
setFn: window.toggleTheme,
content: undefined,
onClick: undefined,
@ -338,7 +338,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
description: window.i18n('hideMenuBarDescription'),
hidden: !Settings.isHideMenuBarSupported(),
type: SessionSettingType.Toggle,
category: SessionSettingCategory.General,
category: SessionSettingCategory.Appearance,
setFn: window.toggleMenuBar,
content: { defaultValue: true },
comparisonValue: undefined,
@ -351,7 +351,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
description: window.i18n('spellCheckDescription'),
hidden: false,
type: SessionSettingType.Toggle,
category: SessionSettingCategory.General,
category: SessionSettingCategory.Appearance,
setFn: window.toggleSpellCheck,
content: undefined,
comparisonValue: undefined,
@ -364,7 +364,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
description: window.i18n('linkPreviewDescription'),
hidden: false,
type: SessionSettingType.Toggle,
category: SessionSettingCategory.General,
category: SessionSettingCategory.Appearance,
setFn: window.toggleLinkPreview,
content: undefined,
comparisonValue: undefined,

1
ts/global.d.ts vendored

@ -6,6 +6,7 @@ interface Window {
deleteAllData: any;
clearLocalData: any;
getAccountManager: any;
getFriendsFromContacts: any;
mnemonic: any;
clipboard: any;
attemptConnection: any;

Loading…
Cancel
Save