Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite MessageList store logic and refactor chat store #1161

Merged
merged 31 commits into from
Dec 8, 2019
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1d6b95a
Rewrite MessageList Store
Jikstra Nov 30, 2019
8378461
Fix bugs, scroll correct messages into view
Jikstra Nov 30, 2019
b1f8922
Debounce fetchMoreMessages
Jikstra Nov 30, 2019
d8d8d66
Implement showing incoming msgs, change page logic
Jikstra Nov 30, 2019
4592dbb
Remove unused backend code
Jikstra Nov 30, 2019
9fba83b
Performance fixes/refactorings
Jikstra Nov 30, 2019
271c010
More performance/refactoring
Jikstra Nov 30, 2019
6879899
remove unused event emitter store
Jikstra Nov 30, 2019
d7e4903
Puuh... working on sending message but this is insane
Jikstra Dec 1, 2019
f4efb10
fix message delivered
Jikstra Dec 1, 2019
522ce8d
fix bug of not loading messages
Jikstra Dec 1, 2019
6f779bf
Dont clear chat on selecting chat, overwrite it as soon we have chats
Jikstra Dec 1, 2019
7ed9aaa
Scroll to bottom after sent message
Jikstra Dec 1, 2019
da3aa99
set fixed image attachment height
Jikstra Dec 1, 2019
5919dd1
Fix message methods
Jikstra Dec 1, 2019
d3d0def
Fetch incoming message on MSGS_CHANGED event too
Jikstra Dec 1, 2019
a5a2e71
Remove DD_EVENT_MSG_UPDATE
Jikstra Dec 1, 2019
6417025
es6ify chat store
Jikstra Dec 4, 2019
e874d20
Merge chat and messagelist store
Jikstra Dec 4, 2019
38e798f
Fix unselecting chat
Jikstra Dec 4, 2019
b513213
Fix scrolling to bottom
Jikstra Dec 4, 2019
cdab64e
fix selecting chat on second click
Jikstra Dec 4, 2019
3fcee72
fix reselecting the same caht
Jikstra Dec 4, 2019
2b44bb9
Implement DayMarkers
Jikstra Dec 4, 2019
9942a2a
Fix standard
Jikstra Dec 4, 2019
dfee6e1
Change filename color in log-conventions script to yellow and remove …
Jikstra Dec 4, 2019
5cf3a57
Make selecting a chat more smooth by not setting a default state. We
Jikstra Dec 4, 2019
4e8af45
Fix accepting contact request
Jikstra Dec 4, 2019
bd1801a
Fix showing contact requests
Jikstra Dec 4, 2019
33f4e0b
Fix message deletion, fixes #712
Jikstra Dec 5, 2019
68c6532
Add comments
nicodh Dec 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/log-conventions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ require('colors')

function formattedOutput (location, lines) {
console.log(
`${'Console log function'.red} in ${location.white}
`${'Console log function'.red} in ${location.yellow}

${lines}

Expand Down
7 changes: 3 additions & 4 deletions scss/message/_message.scss
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@
}

.module-message__img-attachment {
object-fit: unset;
object-fit: cover;
width: auto;
max-width: 100%;
height: auto;
height: 400px;
min-height: unset;
}

Expand All @@ -155,7 +155,6 @@
margin-bottom: 3px;
opacity: 0.86;
}

}

// States that modify the message buble appearance
Expand Down Expand Up @@ -536,4 +535,4 @@
line-height: 16px;
letter-spacing: 0.3px;
margin-top: 3px;
}
}
1 change: 1 addition & 0 deletions scss/overwrites/_bp3-overwrites.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ $bp3-dialog-radius: 2px;
width: calc(100% + 40px);
left: -20px;
padding: 10px 20px;
border-radius: 0px;
}

.bp3-heading {
Expand Down
11 changes: 3 additions & 8 deletions src/main/deltachat/chatlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ module.exports = class DCChatList extends SplitOut {
if (chat.freshMessageCounter > 0) {
this._dc.markNoticedChat(chat.id)
chat.freshMessageCounter = 0
const messagIds = chat.messages.map((msg) => msg.id)
const messagIds = this.getMessageIds(chatId)
log.debug('markSeenMessages', messagIds)
this._dc.markSeenMessages(messagIds)
app.setBadgeCount(this._getGeneralFreshMessageCounter())
}
}
this._controller.sendToRenderer('DD_EVENT_CHAT_SELECTED', { chat })
return chat
}

onChatModified (chatId) {
Expand Down Expand Up @@ -120,10 +120,6 @@ module.exports = class DCChatList extends SplitOut {
if (chat === null) return null
this._controller._pages = 0

// console.log('getFullChatById', chatId)
const messageIds = this._dc.getChatMessages(chat.id, C.DC_GCM_ADDDAYMARKER, 0)
const messages = loadMessages ? this._controller.messageList._messagesToRender(messageIds) : []

const isGroup = isGroupChat(chat)
const contactIds = this._dc.getChatContacts(chatId)

Expand All @@ -143,8 +139,7 @@ module.exports = class DCChatList extends SplitOut {
isSelfTalk: chat.isSelfTalk,

contacts: contacts,
totalMessages: messageIds.length,
messages: messages,
contactIds,
color: integerToHexColor(chat.color),
summary: undefined,
freshMessageCounter: this._dc.getFreshMessageCount(chatId),
Expand Down
15 changes: 7 additions & 8 deletions src/main/deltachat/contacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,17 @@ module.exports = class DCContacts extends SplitOut {
log.debug(`Blocked contact ${name} (id = ${contactId})`)
}

acceptContactRequest (deadDrop) {
log.info(`chat with dead drop ${deadDrop}`)
const contact = this._dc.getContact(deadDrop.contact.id)
acceptContactRequest ({ messageId, contactId }) {
log.info(`chat with dead drop ${contactId}:${messageId}`)
const contact = this._dc.getContact(contactId)
const address = contact.getAddress()
const name = contact.getName() || address.split('@')[0]
this._dc.createContact(name, address)
log.info(`Added contact ${name} (${address})`)
const chatId = this._dc.createChatByMessageId(deadDrop.id)
if (chatId) {
this._controller.chatList.updateChatList()
this._controller.chatList.selectChat(chatId)
}
const chatId = this._dc.createChatByMessageId(messageId)

if (chatId) this._controller.chatList.updateChatList()
return chatId
}

createContact (name, email) {
Expand Down
23 changes: 2 additions & 21 deletions src/main/deltachat/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class DeltaChatController extends EventEmitter {
* @param {object} payload
*/
sendToRenderer (eventType, payload) {
log.debug('sendToRenderer: ' + eventType)
log.debug('sendToRenderer: ' + eventType, payload)
windows.main.send('ALL', eventType, payload)
if (!eventType) {
log.error('Tried to send an undefined event to the renderer.\n' +
Expand All @@ -199,23 +199,21 @@ class DeltaChatController extends EventEmitter {
}
this.logCoreEvent(event, ...args)
if (!event || event === 'DC_EVENT_INFO') return
this.sendToRenderer(event, ...args)
this.sendToRenderer(event, args)
})

dc.on('DD_EVENT_CHATLIST_UPDATED', this.onChatListChanged.bind(this))

dc.on('DC_EVENT_MSGS_CHANGED', (chatId, msgId) => {
this.onChatListChanged()
this.onChatListItemChanged(chatId)
this.onMessageUpdate(chatId, msgId, 'DC_EVENT_MSGS_CHANGED')
this.chatList.onChatModified(chatId)
})

dc.on('DC_EVENT_INCOMING_MSG', (chatId, msgId) => {
maybeMarkSeen(chatId, msgId)
this.onChatListChanged()
this.onChatListItemChanged(chatId)
this.onMessageUpdate(chatId, msgId, 'DC_EVENT_INCOMING_MSG')
this.chatList.onChatModified(chatId)
})

Expand All @@ -231,12 +229,10 @@ class DeltaChatController extends EventEmitter {

dc.on('DC_EVENT_MSG_DELIVERED', (chatId, msgId) => {
this.onChatListItemChanged(chatId)
this.onMessageUpdate(chatId, msgId, 'DC_EVENT_MSG_DELIVERED')
})

dc.on('DC_EVENT_MSG_READ', (chatId, msgId) => {
this.onChatListItemChanged(chatId)
this.onMessageUpdate(chatId, msgId, 'DC_EVENT_MSG_READ')
})

dc.on('DC_EVENT_WARNING', (warning) => {
Expand Down Expand Up @@ -284,17 +280,6 @@ class DeltaChatController extends EventEmitter {
this.sendToRenderer('DD_EVENT_CHATLIST_ITEM_CHANGED', { chatId })
}

/**
*
* @param {int} chatId
* @param {int} msgId
* @param {string} eventType
*/
onMessageUpdate (chatId, msgId, eventType) {
if (chatId === 0 || msgId === 0) return
this.sendToRenderer('DD_EVENT_MSG_UPDATE', { chatId, messageObj: this.messageList.messageIdToJson(msgId), eventType })
}

updateBlockedContacts () {
const blockedContacts = this._blockedContacts()
this.sendToRenderer('DD_EVENT_BLOCKED_CONTACTS_UPDATED', { blockedContacts })
Expand Down Expand Up @@ -333,10 +318,6 @@ class DeltaChatController extends EventEmitter {
this.sendToRenderer('DD_EVENT_CONTACTS_UPDATED', { contacts })
}

contactRequests () {
this.chatList.selectChat(C.DC_CHAT_ID_DEADDROP)
}

setProfilePicture (newImage) {
this._dc.setConfig('selfavatar', newImage)
}
Expand Down
142 changes: 88 additions & 54 deletions src/main/deltachat/messagelist.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const C = require('deltachat-node/constants')
const log = require('../../logger').getLogger('main/deltachat/messagelist')
const { integerToHexColor } = require('./util')
const CHATVIEW_PAGE_SIZE = 20
const filesizeConverter = require('filesize')
const mime = require('mime-types')

const SplitOut = require('./splitout')
module.exports = class DCMessageList extends SplitOut {
Expand All @@ -11,7 +12,8 @@ module.exports = class DCMessageList extends SplitOut {
if (filename) msg.setFile(filename)
if (text) msg.setText(text)
if (location) msg.setLocation(location.lat, location.lng)
this._dc.sendMessage(chatId, msg)
const messageId = this._dc.sendMessage(chatId, msg)
return [messageId, this.getMessage(messageId)]
}

sendSticker (chatId, stickerPath) {
Expand Down Expand Up @@ -41,47 +43,16 @@ module.exports = class DCMessageList extends SplitOut {
this._dc.setDraft(chatId, msg)
}

_messagesToRender (messageIds) {
// we need one more message than we render, to get the timestamp
// from preceeding message for DAYMARKER
const currentIndex = (this._controller._pages * CHATVIEW_PAGE_SIZE)
messageIds.reverse() // newest IDs first
const messageIdsToRender = messageIds.splice(
currentIndex,
CHATVIEW_PAGE_SIZE + 1
)
if (messageIdsToRender.length === 0) return []
messageIdsToRender.reverse() // newest IDs last
const messages = []
for (let i = 0; i < messageIdsToRender.length; i++) {
const id = messageIdsToRender[i]
if (id > C.DC_MSG_ID_LAST_SPECIAL) {
messages.push(this.messageIdToJson(id))
} else if (id === C.DC_MSG_ID_DAYMARKER && messages.length > 0) {
const timestamp = messages[messages.length - 1].msg.timestamp
const json = {
id,
msg: {
text: '',
timestamp
},
daymarker: {
timestamp,
id: 'd' + i
}
}
messages.push(json)
}
}
return messages
}

messageIdToJson (id) {
const msg = this._dc.getMessage(id)
if (!msg) {
log.warn('No message found for ID ' + id)
return { msg: null }
}
return this.messageToJson(msg)
}

messageToJson (msg) {
const filemime = msg.getFilemime()
const filename = msg.getFilename()
const filesize = msg.getFilebytes()
Expand All @@ -93,8 +64,8 @@ module.exports = class DCMessageList extends SplitOut {
if (contact.color) {
contact.color = integerToHexColor(contact.color)
}
return {
id,
return convert({
id: msg.id,
msg: msg.toJson(),
filemime,
filename,
Expand All @@ -105,25 +76,88 @@ module.exports = class DCMessageList extends SplitOut {
contact,
isInfo: msg.isInfo(),
setupCodeBegin
}
}

fetchMessages (chatId) {
var messageIds = this._dc.getChatMessages(chatId, C.DC_GCM_ADDDAYMARKER, 0)
if (messageIds.length <= this._controller._pages * CHATVIEW_PAGE_SIZE) {
return
}
this._controller._pages++
var payload = {
chatId: chatId,
totalMessages: messageIds.length,
messages: this._messagesToRender(messageIds)
}
this._controller.sendToRenderer('DD_MESSAGES_LOADED', payload)
})
}

forwardMessage (msgId, chatId) {
this._dc.forwardMessages(msgId, chatId)
this._controller.chatList.selectChat(chatId)
}

getMessageIds (chatId) {
const messageIds = this._dc.getChatMessages(chatId, C.DC_GCM_ADDDAYMARKER, 0)
return messageIds
}

getMessages (messageIds) {
const messages = {}
messageIds.forEach(messageId => {
if (messageId <= C.DC_MSG_ID_LAST_SPECIAL) return
messages[messageId] = this.messageIdToJson(messageId)
})
return messages
}
}

function convert (message) {
const msg = message.msg

Object.assign(msg, {
sentAt: msg.timestamp * 1000,
receivedAt: msg.receivedTimestamp * 1000,
direction: message.isMe ? 'outgoing' : 'incoming',
status: convertMessageStatus(msg.state)
})

if (msg.file) {
msg.attachment = {
url: msg.file,
contentType: convertContentType(message),
fileName: message.filename || msg.text,
fileSize: filesizeConverter(message.filesize)
}
}

return message
}

function convertMessageStatus (s) {
switch (s) {
case C.DC_STATE_IN_FRESH:
return 'sent'
case C.DC_STATE_OUT_FAILED:
return 'error'
case C.DC_STATE_IN_SEEN:
return 'read'
case C.DC_STATE_IN_NOTICED:
return 'read'
case C.DC_STATE_OUT_DELIVERED:
return 'delivered'
case C.DC_STATE_OUT_MDN_RCVD:
return 'read'
case C.DC_STATE_OUT_PENDING:
return 'sending'
case C.DC_STATE_UNDEFINED:
return 'error'
}
}

function convertContentType (message) {
const filemime = message.filemime

if (!filemime) return 'application/octet-stream'
if (filemime !== 'application/octet-stream') return filemime

switch (message.msg.viewType) {
case C.DC_MSG_IMAGE:
return 'image/jpg'
case C.DC_MSG_VOICE:
return 'audio/ogg'
case C.DC_MSG_FILE:
const type = mime.lookup(message.msg.file)
if (type) return type
else return 'application/octet-stream'
default:
return 'application/octet-stream'
}
}
Loading