diff --git a/AUDRICTOCLEAN.txt b/AUDRICTOCLEAN.txt index 97cdd874c..b8b1465a9 100644 --- a/AUDRICTOCLEAN.txt +++ b/AUDRICTOCLEAN.txt @@ -25,8 +25,3 @@ ReadSyncs SyncMessage sendSyncMessage needs to be rewritten sendSyncMessageOnly to fix - - - - -LONG_ATTAHCMENNT diff --git a/libtextsecure/account_manager.js b/libtextsecure/account_manager.js index c6d699f4e..4c2f5da7e 100644 --- a/libtextsecure/account_manager.js +++ b/libtextsecure/account_manager.js @@ -169,16 +169,6 @@ this.dispatchEvent(new Event('registration')); }, - validatePubKeyHex(pubKey) { - const c = new window.models.Conversation({ - id: pubKey, - type: 'private', - }); - const validationError = c.validateNumber(); - if (validationError) { - throw new Error(validationError); - } - }, }); textsecure.AccountManager = AccountManager; })(); diff --git a/package.json b/package.json index 19a9a0477..8a597300e 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "@types/react-mic": "^12.4.1", "@types/styled-components": "^5.1.4", "abort-controller": "3.0.0", + "auto-bind": "^4.0.0", "backbone": "1.3.3", "blob-util": "1.3.0", "blueimp-canvas-to-blob": "3.14.0", diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts index 46bb00d23..2fa60363b 100644 --- a/ts/models/conversation.ts +++ b/ts/models/conversation.ts @@ -21,6 +21,7 @@ import { SignalService } from '../protobuf'; import { MessageCollection, MessageModel } from './message'; import * as Data from '../../js/modules/data'; import { MessageAttributesOptionals } from './messageType'; +import autoBind from 'auto-bind'; export interface OurLokiProfile { displayName: string; @@ -152,6 +153,7 @@ export class ConversationModel extends Backbone.Model { this.messageCollection = new MessageCollection([], { conversation: this, }); + autoBind(this); this.throttledBumpTyping = _.throttle(this.bumpTyping, 300); this.updateLastMessage = _.throttle( @@ -177,8 +179,6 @@ export class ConversationModel extends Backbone.Model { if (this.isPublic()) { this.set('profileSharing', true); } - this.unset('hasFetchedProfile'); - this.unset('tokens'); this.typingRefreshTimer = null; this.typingPauseTimer = null; @@ -549,49 +549,6 @@ export class ConversationModel extends Backbone.Model { return window.Signal.Data.getUnreadCountByConversation(this.id); } - public validate(attributes: any) { - const required = ['id', 'type']; - const missing = _.filter(required, attr => !attributes[attr]); - if (missing.length) { - return `Conversation must have ${missing}`; - } - - if (attributes.type !== 'private' && attributes.type !== 'group') { - return `Invalid conversation type: ${attributes.type}`; - } - - const error = this.validateNumber(); - if (error) { - return error; - } - - return null; - } - - public validateNumber() { - if (!this.id) { - return 'Invalid ID'; - } - if (!this.isPrivate()) { - return null; - } - - // Check if it's hex - const isHex = this.id.replace(/[\s]*/g, '').match(/^[0-9a-fA-F]+$/); - if (!isHex) { - return 'Invalid Hex ID'; - } - - // Check if the pubkey length is 33 and leading with 05 or of length 32 - const len = this.id.length; - if ((len !== 33 * 2 || !/^05/.test(this.id)) && len !== 32 * 2) { - return 'Invalid Pubkey Format'; - } - - this.set({ id: this.id }); - return null; - } - public queueJob(callback: any) { // tslint:disable-next-line: no-promise-as-boolean const previous = this.pending || Promise.resolve(); diff --git a/ts/models/message.ts b/ts/models/message.ts index 8a1bb1e27..6db4f4427 100644 --- a/ts/models/message.ts +++ b/ts/models/message.ts @@ -20,6 +20,7 @@ import { MessageAttributesOptionals, } from './messageType'; +import autoBind from 'auto-bind'; export class MessageModel extends Backbone.Model { public propsForTimerNotification: any; public propsForGroupNotification: any; @@ -45,6 +46,8 @@ export class MessageModel extends Backbone.Model { this.on('change:expireTimer', this.setToExpire); // this.on('expired', this.onExpired); void this.setToExpire(); + autoBind(this); + this.markRead = this.markRead.bind(this); // Keep props ready const generateProps = (triggerEvent = true) => { if (this.isExpirationTimerUpdate()) { @@ -95,7 +98,7 @@ export class MessageModel extends Backbone.Model { return !!this.get('unread'); } - // Important to allow for this.unset('unread'), save to db, then fetch() + // Important to allow for this.set({ unread}), save to db, then fetch() // to propagate. We don't want the unset key in the db so our unread index // stays small. public merge(model: any) { @@ -103,7 +106,7 @@ export class MessageModel extends Backbone.Model { const { unread } = attributes; if (unread === undefined) { - this.unset('unread'); + this.set({ unread: false }); } this.set(attributes); @@ -1323,7 +1326,7 @@ export class MessageModel extends Backbone.Model { } public async markRead(readAt: number) { - this.unset('unread'); + this.set({ unread: false }); if (this.get('expireTimer') && !this.get('expirationStartTimestamp')) { const expirationStartTimestamp = Math.min( diff --git a/ts/receiver/queuedJob.ts b/ts/receiver/queuedJob.ts index 2e3e166d9..92ab4d9d6 100644 --- a/ts/receiver/queuedJob.ts +++ b/ts/receiver/queuedJob.ts @@ -294,7 +294,8 @@ function updateReadStatus( } } if (readSync || message.isExpirationTimerUpdate()) { - message.unset('unread'); + message.set({ unread: false }); + // This is primarily to allow the conversation to mark all older // messages as read, as is done when we receive a read sync for // a message we already know about. diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts index 20f5d85da..aa0e5200a 100644 --- a/ts/state/selectors/conversations.ts +++ b/ts/state/selectors/conversations.ts @@ -1,6 +1,5 @@ import { createSelector } from 'reselect'; -import { LocalizerType } from '../../types/Util'; import { StateType } from '../reducer'; import { ConversationLookupType, @@ -11,6 +10,7 @@ import { import { getIntl, getOurNumber } from './user'; import { BlockedNumberController } from '../../util'; +import { LocalizerType } from '../../types/Util'; export const getConversations = (state: StateType): ConversationsStateType => state.conversations; @@ -49,13 +49,15 @@ export const getMessagesOfSelectedConversation = createSelector( (state: ConversationsStateType): Array => state.messages ); -function getConversationTitle(conversation: ConversationType): string { +function getConversationTitle( + conversation: ConversationType, + i18n: LocalizerType +): string { if (conversation.name) { return conversation.name; } if (conversation.type === 'group') { - const { i18n } = window; return i18n('unknown'); } return conversation.id; @@ -65,19 +67,25 @@ const collator = new Intl.Collator(); export const _getConversationComparator = (i18n: LocalizerType) => { return (left: ConversationType, right: ConversationType): number => { - const leftTimestamp = left.timestamp; - const rightTimestamp = right.timestamp; - if (leftTimestamp && !rightTimestamp) { + const leftActiveAt = left.activeAt; + const rightActiveAt = right.activeAt; + if (leftActiveAt && !rightActiveAt) { return -1; } - if (rightTimestamp && !leftTimestamp) { + if (rightActiveAt && !leftActiveAt) { return 1; } - if (leftTimestamp && rightTimestamp && leftTimestamp !== rightTimestamp) { - return rightTimestamp - leftTimestamp; + if (leftActiveAt && rightActiveAt && leftActiveAt !== rightActiveAt) { + return rightActiveAt - leftActiveAt; } - const leftTitle = getConversationTitle(left).toLowerCase(); - const rightTitle = getConversationTitle(right).toLowerCase(); + const leftTitle = getConversationTitle( + left, + i18n || window?.i18n + ).toLowerCase(); + const rightTitle = getConversationTitle( + right, + i18n || window?.i18n + ).toLowerCase(); return collator.compare(leftTitle, rightTitle); }; diff --git a/yarn.lock b/yarn.lock index f759664d2..4e3cb28b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1308,6 +1308,11 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +auto-bind@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-4.0.0.tgz#e3589fc6c2da8f7ca43ba9f84fa52a744fc997fb" + integrity sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ== + autoprefixer@^6.3.1: version "6.7.7" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014"