Upgrade typescript, finding messaages

pull/1102/head
Vincent 5 years ago
parent 2c5e2df817
commit ea4dc05009

@ -1,7 +1,7 @@
{
"name": "loki-messenger",
"name": "session-desktop",
"version": "0.0.0",
"homepage": "https://github.com/loki-project/loki-messenger",
"homepage": "https://github.com/loki-project/session-desktop",
"license": "GPLV3",
"private": true,
"dependencies": {

@ -988,11 +988,16 @@
return toastID;
};
window.renderConversationView = () => {
window.renderConversationView = conversationKey => {
const sessionConversation = new Whisper.SessionConversationView({
el: $('#main-view'),
conversationKey,
});
sessionConversation.render();
console.log(conversationKey);
console.log(conversationKey);
console.log(conversationKey);
};
window.getFriendsFromContacts = contacts => {

@ -59,6 +59,25 @@
window.getInboxCollection = () => inboxCollection;
window.getConversations = () => conversations;
window.getConversationByKey = key => {
// Key is pubkey or public chat name
const conversation = conversations.models.filter(conv => conv.id === key)[0] || null;
return conversation;
}
window.getMessagesByKey = async key => {
const conversation = window.getConversationByKey(key);
// Grab messages and push to conv object.
await conversation.fetchMessages();
const messagesModel = conversation.messageCollection.models;
const messages = messagesModel.map(conv => conv.attributes);
return messages;
}
window.ConversationController = {
get(id) {
if (!this._initialFetchComplete) {

@ -131,6 +131,7 @@
this.messageCollection.on('change:errors', this.handleMessageError, this);
this.messageCollection.on('send-error', this.onMessageError, this);
this.throttledBumpTyping = _.throttle(this.bumpTyping, 300);
const debouncedUpdateLastMessage = _.debounce(
this.updateLastMessage.bind(this),

@ -58,7 +58,9 @@ const { UserDetailsDialog } = require('../../ts/components/UserDetailsDialog');
const {
DevicePairingDialog,
} = require('../../ts/components/DevicePairingDialog');
const { SessionConversation } = require('../../ts/components/session/SessionConversation');
const {
SessionConversation,
} = require('../../ts/components/session/SessionConversation');
const {
SettingsView,
} = require('../../ts/components/session/settings/SessionSettings');

@ -2,27 +2,25 @@
// eslint-disable-next-line func-names
(function() {
'use strict';
window.Whisper = window.Whisper || {};
Whisper.SessionConversationView = Whisper.View.extend({
initialize(options) {
this.props = {
...options,
};
},
render() {
this.conversationView = new Whisper.ReactWrapperView({
className: 'session-conversation-wrapper',
Component: window.Signal.Components.SessionConversation,
props: this.props,
});
this.$el.prepend(this.conversationView.el);
},
});
})();
'use strict';
window.Whisper = window.Whisper || {};
Whisper.SessionConversationView = Whisper.View.extend({
initialize(options) {
this.props = {
...options,
};
},
render() {
this.conversationView = new Whisper.ReactWrapperView({
className: 'session-conversation-wrapper',
Component: window.Signal.Components.SessionConversation,
props: this.props,
});
this.$el.prepend(this.conversationView.el);
},
});
})();

@ -1,7 +1,7 @@
{
"name": "session-messenger-desktop",
"name": "session-desktop",
"productName": "Session",
"description": "Private messaging from your desktop",
"description": "Send messages not metadata",
"repository": "https://github.com/loki-project/loki-messenger.git",
"version": "1.0.1",
"license": "GPL-3.0",
@ -199,7 +199,7 @@
"tslint": "5.13.0",
"tslint-microsoft-contrib": "6.0.0",
"tslint-react": "3.6.0",
"typescript": "3.3.3333",
"typescript": "^3.7",
"webpack": "4.4.1"
},
"engines": {

@ -1,69 +1,102 @@
$composition-container-height: 60px;
.conversation-item {
display: flex;
flex-grow: 1;
flex-direction: column;
height: 100%;
display: flex;
flex-grow: 1;
flex-direction: column;
height: 100%;
}
.session-conversation-wrapper {
position: absolute;
width: 100%;
height: 100%;
background-color: $session-shade-2;
position: absolute;
width: 100%;
height: 100%;
background-color: $session-shade-2;
}
.messages-container{
display: flex;
flex-grow: 1;
flex-direction: column;
.messages-container {
display: flex;
flex-grow: 1;
flex-direction: column;
padding: $session-margin-lg;
}
.composition-container {
display: flex;
justify-content: center;
align-items: center;
background-color: $session-shade-4;
padding: 0px $session-margin-md;
min-height: $composition-container-height;
& > .session-icon-button {
margin-right: $session-margin-sm;
}
.session-icon-button {
opacity: 0.8;
.send {
background-color: $session-shade-14;
padding: $session-margin-xs;
border-radius: 50%;
height: 30px;
width: 30px;
}
}
.send-message-input {
display: flex;
justify-content: center;
align-items: center;
background-color: $session-shade-4;
padding: 0px $session-margin-md;
flex-grow: 1;
min-height: $composition-container-height;
& > .session-icon-button {
margin-right: $session-margin-sm;
}
.session-icon-button {
opacity: 0.8;
.send {
background-color: $session-shade-14;
padding: $session-margin-xs;
border-radius: 50%;
height: 30px;
width: 30px;
}
}
.send-message-input {
padding: $composition-container-height / 3 0px;
textarea {
font-family: 'SF Pro Text';
min-height: $composition-container-height / 3;
max-height: 2 * $composition-container-height;
margin-right: $session-margin-md;
color: $session-color-white;
resize: none;
display: flex;
flex-grow: 1;
min-height: $composition-container-height
textarea {
min-height: $composition-container-height / 3;
max-height: 3 * $composition-container-height;
margin-right: $session-margin-md;
color: $session-color-white;
resize: none;
display: flex;
flex-grow: 1;
background: transparent;
outline: none;
border: none;
font-size: $session-font-md;
line-height: $session-font-h2;
padding: $composition-container-height / 3 0px;
}
background: transparent;
outline: none;
border: none;
font-size: $session-font-md;
line-height: $session-font-h2;
letter-spacing: 0.5px;
}
}
}
.session-emoji-panel {
position: absolute;
bottom: 68px;
right: 0px;
min-height: 400px;
min-width: 400px;
background-color: $session-shade-4;
border: 1px solid $session-shade-6;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
padding: $session-margin-lg;
}
.session-progress {
position: relative;
background-color: rgba(30, 30, 30, 0.5);
&__progress {
transition: opacity 0.15s;
position: absolute;
left: 0px;
font-size: 0px;
height: 3px;
background-color: $session-color-green;
}
}

@ -109,7 +109,7 @@ export class LeftPaneMessageSection extends React.Component<Props, any> {
key,
style,
}: RowRendererParamsType): JSX.Element => {
const { openConversationInternal } = this.props;
// const { openConversationInternal } = this.props;
const conversations = this.getCurrentConversations();
@ -118,13 +118,14 @@ export class LeftPaneMessageSection extends React.Component<Props, any> {
}
const conversation = conversations[index];
const conversationKey = conversation.id;
return (
<ConversationListItem
key={key}
style={style}
{...conversation}
onClick={window.renderConversationView}
onClick={() => window.renderConversationView(conversationKey)}
i18n={window.i18n}
/>
);

@ -234,7 +234,7 @@ export class SessionChannelSettings extends React.Component<Props, any> {
<div className="text-subtle">
{window.i18n('members', memberCount)}
</div>
<div className="spacer-lg" />
<div className="spacer-lg" />
</>
)}
<input

@ -0,0 +1,85 @@
import React from 'react';
import TextareaAutosize from 'react-autosize-textarea';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { SessionEmojiPanel } from './SessionEmojiPanel';
interface Props {
placeholder?: string;
onSendMessage: any;
}
interface State {
message: string;
showEmojiPanel: boolean;
}
export class SessionCompositionBox extends React.Component<Props, State> {
private textarea: React.RefObject<HTMLTextAreaElement>;
constructor(props: any) {
super(props);
this.state = {
message: '',
showEmojiPanel: false,
};
this.textarea = React.createRef();
this.toggleEmojiPanel = this.toggleEmojiPanel.bind(this);
}
render() {
const { placeholder } = this.props;
const { showEmojiPanel } = this.state;
return (
<div className="composition-container">
<SessionIconButton
iconType={SessionIconType.CirclePlus}
iconSize={SessionIconSize.Large}
/>
<SessionIconButton
iconType={SessionIconType.Microphone}
iconSize={SessionIconSize.Large}
/>
<div className="send-message-input">
<TextareaAutosize
rows={1}
maxRows={6}
ref={this.textarea}
placeholder={placeholder}
maxLength={window.CONSTANTS.MAX_MESSAGE_BODY_LENGTH}
/>
</div>
<SessionIconButton
iconType={SessionIconType.Emoji}
iconSize={SessionIconSize.Large}
onClick={this.toggleEmojiPanel}
/>
<div className="send-message-button">
<SessionIconButton
iconType={SessionIconType.Send}
iconSize={SessionIconSize.Large}
iconColor={'#FFFFFF'}
iconRotation={90}
/>
</div>
{ showEmojiPanel &&
( <SessionEmojiPanel/> )
}
</div>
);
}
public toggleEmojiPanel() {
this.setState({
showEmojiPanel: !this.state.showEmojiPanel,
})
}
}

@ -1,120 +1,218 @@
import React from 'react';
import TextareaAutosize from 'react-autosize-textarea';
import { ConversationHeader } from '../conversation/ConversationHeader';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { SessionCompositionBox } from './SessionCompositionBox';
import { SessionProgress } from './SessionProgress'
import { Message } from '../conversation/Message';
interface Props {
getHeaderProps: any;
conversationKey: any;
}
interface State {
sendingProgess: number;
prevSendingProgess: number;
loadingMessages: boolean;
messages: any;
}
export class SessionConversation extends React.Component<Props, State> {
constructor(props: any) {
super(props);
this.state = {
sendingProgess: 0,
prevSendingProgess: 0,
loadingMessages: false,
messages: {},
};
}
interface Props{
getHeaderProps: any;
async componentWillMount() {
const { conversationKey } = this.props;
this.setState({
messages: await window.getMessagesByKey(conversationKey)
})
};
interface State{};
export class SessionConversation extends React.Component<Props, State> {
constructor(props: any) {
super(props);
this.state = {};
}
render() {
// const headerProps = this.props.getHeaderProps;
// TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL
// SessionConversationStack is created
const conversation = window.getConversations().models[0];
return (
<div className={`conversation-item conversation-${conversation.cid}`}>
<div className="conversation-header">
{this.renderHeader(conversation)}
</div>
<div className="messages-container">
THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW THIS IS AN INBOX VIEW
</div>
<div className="composition-container">
<SessionIconButton
iconType={SessionIconType.CirclePlus}
iconSize={SessionIconSize.Large}
/>
<SessionIconButton
iconType={SessionIconType.Microphone}
iconSize={SessionIconSize.Large}
/>
<div className="send-message-input">
<TextareaAutosize
rows={1}
maxRows={6}
/>
</div>
<SessionIconButton
iconType={SessionIconType.Emoji}
iconSize={SessionIconSize.Large}
/>
<div className="send-message-button">
<SessionIconButton
iconType={SessionIconType.Send}
iconSize={SessionIconSize.Large}
iconColor={'#FFFFFF'}
iconRotation={90}
/>
</div>
</div>
</div>
)
}
renderHeader(conversation: any) {
return (
<ConversationHeader
id={conversation.cid}
phoneNumber={conversation.id}
isVerified={true}
isMe={false}
isFriend={true}
i18n={window.i18n}
isGroup={false}
isArchived={false}
isPublic={false}
isRss={false}
amMod={false}
members={[]}
showBackButton={false}
timerOptions={[]}
isBlocked={false}
hasNickname={false}
isFriendRequestPending={false}
isOnline={true}
selectedMessages={null}
onSetDisappearingMessages={() => null}
onDeleteMessages={() => null}
onDeleteContact={() => null}
onResetSession={() => null}
onCloseOverlay={() => null}
onDeleteSelectedMessages={() => null}
onArchive={() => null}
onMoveToInbox={() => null}
onShowSafetyNumber={() => null}
onShowAllMedia={() => null}
onShowGroupMembers={() => null}
onGoBack={() => null}
onBlockUser={() => null}
onUnblockUser={() => null}
onClearNickname={() => null}
onChangeNickname={() => null}
onCopyPublicKey={() => null}
onLeaveGroup={() => null}
onAddModerators={() => null}
onRemoveModerators={() => null}
onInviteFriends={() => null}
/>
);
}
}
}
render() {
// const headerProps = this.props.getHeaderProps;
const { conversationKey } = this.props;
// TMEPORARY SOLUTION TO GETTING CONVERSATION UNTIL
// SessionConversationStack is created
// Get conversation by Key (NOT cid)
const conversation = window.getConversationByKey(conversationKey);
console.log(`Conversation key: `, conversationKey);
return (
<div className={`conversation-item conversation-${conversation.cid}`}>
<div className="conversation-header">
{this.renderHeader(conversation)}
</div>
<SessionProgress
visible={true}
value={this.state.sendingProgess}
prevValue={this.state.prevSendingProgess}
/>
<div className="messages-container">
{this.renderMessages(conversationKey)}
</div>
<SessionCompositionBox
onSendMessage={() => null}
/>
</div>
);
}
public renderMessages(conversationKey: string ) {
const { messages } = this.state;
// FIXME PAY ATTENTION; ONLY RENDER MESSAGES THAT ARE VISIBLE
const messagesLength = messages.length;
console.log(`Messages`, messages);
let messageList = [];
messages?.keys.map(key => {
const message = messages[key];
return (<>THIS IS A MESSAGE</>)
});
console.log(messages);
return messages;
// for(let i = messagesLength - 1; i > 0; i--){
// messageList.push({
// isDeletable: true,
// text: 'fdgdfg',
// direction: 'incoming',
// timestamp: '1581565995228',
// i18n: window.i18n,
// authorPhoneNumber: messages[i].source,
// conversationType: 'direct',
// previews: [],
// isExpired: false,
// convoId: messages[i].conversationId,
// selected: false,
// multiSelectMode: false,
// onSelectMessage: () => null,
// onSelectMessageUnchecked: () => null,
// onShowDetail : () => null,
// onShowUserDetails: () => null,
// });
// }
// console.log(`[vince] MessageList: `, messageList);
// return messages && (
// <Message
// isDeletable = {false}
// text = {messages[0].body}
// direction = {'incoming'}
// timestamp = {1581565995228}
// i18n = {window.i18n}
// authorPhoneNumber = {messages[0].source}
// conversationType = {'direct'}
// previews = {[]}
// isExpired = {false}
// convoId = {messages[0].conversationId}
// selected = {false}
// multiSelectMode = {false}
// onSelectMessage = {() => null}
// onSelectMessageUnchecked = {() => null}
// onShowDetail = {() => null}
// onShowUserDetails = {() => null}
// />
// )
// return (
// <>
// {
// messageList.map(message => {
// return (
// <Message
// isDeletable = {message.isDeletable}
// text = {message.text}
// direction = {'incoming'}
// timestamp = {1581565995228}
// i18n = {message.i18n}
// authorPhoneNumber = {message.authorPhoneNumber}
// conversationType = {'direct'}
// previews = {message.previews}
// isExpired = {message.isExpired}
// convoId = {message.convoId}
// selected = {message.selected}
// multiSelectMode = {message.multiSelectMode}
// onSelectMessage = {message.onSelectMessage}
// onSelectMessageUnchecked = {message.onSelectMessageUnchecked}
// onShowDetail = {message.onShowDetail}
// onShowUserDetails = {message.onShowUserDetails}
// />
// )}
// );
// }
// </>
// );
}
public renderHeader(conversation: any) {
return (
<ConversationHeader
id={conversation.cid}
phoneNumber={conversation.id}
isVerified={true}
isMe={false}
isFriend={true}
i18n={window.i18n}
isGroup={false}
isArchived={false}
isPublic={false}
isRss={false}
amMod={false}
members={[]}
showBackButton={false}
timerOptions={[]}
isBlocked={false}
hasNickname={false}
isFriendRequestPending={false}
isOnline={true}
selectedMessages={null}
onSetDisappearingMessages={() => null}
onDeleteMessages={() => null}
onDeleteContact={() => null}
onResetSession={() => null}
onCloseOverlay={() => null}
onDeleteSelectedMessages={() => null}
onArchive={() => null}
onMoveToInbox={() => null}
onShowSafetyNumber={() => null}
onShowAllMedia={() => null}
onShowGroupMembers={() => null}
onGoBack={() => null}
onBlockUser={() => null}
onUnblockUser={() => null}
onClearNickname={() => null}
onChangeNickname={() => null}
onCopyPublicKey={() => null}
onLeaveGroup={() => null}
onAddModerators={() => null}
onRemoveModerators={() => null}
onInviteFriends={() => null}
/>
);
}
}

@ -0,0 +1,29 @@
import React from 'react';
interface Props {}
interface State {
// FIXME Use Emoji-Mart categories
category: null
}
export class SessionEmojiPanel extends React.Component<Props, State> {
constructor(props: any) {
super(props);
this.state = {
category: null,
};
}
render() {
return (
<div className='session-emoji-panel'>
THIS IS EMOJI STUFF
</div>
);
}
}

@ -238,7 +238,7 @@ export class SessionGroupSettings extends React.Component<Props, any> {
<div role="button" className="text-subtle">
{window.i18n('members', memberCount)}
</div>
<div className="spacer-lg" />
<div className="spacer-lg" />
</>
)}
<input

@ -0,0 +1,106 @@
import React from 'react';
interface Props {
// Value ranges from 0 to 100
value: number;
// Optional. Load with initial value and have
// it shoot to new value immediately
prevValue?: number;
visible: boolean;
fadeOnComplete: boolean;
}
interface State {
value: number;
visible: boolean;
startFade: boolean;
}
export class SessionProgress extends React.PureComponent<Props, State> {
public static defaultProps = {
fadeOnComplete: true,
};
constructor(props: any) {
super(props);
const { visible, value, prevValue } = this.props;
this.state = {
visible,
startFade: false,
value: prevValue || value,
};
}
public componentWillMount() {
setTimeout(() => {
this.setState({
value: this.props.value,
});
}, 20);
}
public render() {
const { startFade, value } = this.state;
const { prevValue } = this.props;
// Duration will be the decimal (in seconds) of
// the percentage differnce, else 0.25s;
// Minimum shift duration of 0.25s;
const shiftDuration = this.getShiftDuration(this.props.value, prevValue);
// 1. Width depends on progress.
// 2. Opacity is the inverse of fade.
// 3. Transition duration scales with the
// distance it needs to travel
const style = {
width: `${this.state.value}%`,
opacity: `${Number(!startFade)}`,
transition: `width ${shiftDuration.toFixed(2)}s cubic-bezier(0.25, 0.46, 0.45, 0.94)`,
};
if (value >= 100) {
this.onComplete();
}
return (
<div className="session-progress">
<div
className="session-progress__progress"
style={style}
>
&nbsp
</div>
</div>
);
}
public onComplete() {
const { fadeOnComplete } = this.props;
// Fade
if ( fadeOnComplete ) {
this.setState({
startFade: true,
});
}
}
private getShiftDuration(value: number, prevValue?: number) {
// Generates a shift duration which is based upon the distance requred to travel.
// Follows the curve of y = (1-c)*sqrt(x) + c
// Input values are between 0 and 100.
// Max time = 1.0s.
const minTime = 0.25;
if (!prevValue) {
return minTime;
}
const distance = Math.abs(value - prevValue) / 100;
return (1 - minTime) * Math.sqrt(distance) + minTime;
}
}

7
ts/global.d.ts vendored

@ -2,18 +2,19 @@ interface Window {
CONSTANTS: any;
versionInfo: any;
renderConversationView: any;
Events: any;
Lodash: any;
deleteAllData: any;
clearLocalData: any;
getAccountManager: any;
getConversations: any;
getConversationByKey: any;
getMessagesByKey: any;
getFriendsFromContacts: any;
mnemonic: any;
clipboard: any;
attemptConnection: any;

Loading…
Cancel
Save