mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-04 19:54:32 +08:00
Threads now sorted by receivedrecetndate
Summary: Threads are now sorted using the thread's receivedrecentdate instead of recentdate Test Plan: Tested Manually Reviewers: bengotow Reviewed By: bengotow Subscribers: mg Differential Revision: https://phab.nylas.com/D1812
This commit is contained in:
parent
79dfd0866a
commit
c622e2dbeb
10 changed files with 33 additions and 33 deletions
|
@ -57,7 +57,7 @@ SearchSuggestionStore = Reflux.createStore
|
|||
|
||||
@_threadQueryInFlight = true
|
||||
DatabaseStore.findAll(Thread, [Thread.attributes.subject.like(val)])
|
||||
.order(Thread.attributes.lastMessageTimestamp.descending())
|
||||
.order(Thread.attributes.lastMessageReceivedTimestamp.descending())
|
||||
.limit(4)
|
||||
.then (results) =>
|
||||
@_threadQueryInFlight = false
|
||||
|
|
|
@ -42,7 +42,7 @@ class ThreadListScrollTooltip extends React.Component
|
|||
|
||||
render: ->
|
||||
if @state.item
|
||||
content = timestamp(@state.item.lastMessageTimestamp)
|
||||
content = timestamp(@state.item.lastMessageReceivedTimestamp)
|
||||
else
|
||||
content = "Loading..."
|
||||
<div className="scroll-tooltip">
|
||||
|
@ -111,7 +111,7 @@ class ThreadList extends React.Component
|
|||
c4 = new ListTabular.Column
|
||||
name: "Date"
|
||||
resolver: (thread) =>
|
||||
<span className="timestamp">{timestamp(thread.lastMessageTimestamp)}</span>
|
||||
<span className="timestamp">{timestamp(thread.lastMessageReceivedTimestamp)}</span>
|
||||
|
||||
c5 = new ListTabular.Column
|
||||
name: "HoverActions"
|
||||
|
@ -141,7 +141,7 @@ class ThreadList extends React.Component
|
|||
{pencil}
|
||||
<span style={flex:1}></span>
|
||||
{attachment}
|
||||
<span className="timestamp">{timestamp(thread.lastMessageTimestamp)}</span>
|
||||
<span className="timestamp">{timestamp(thread.lastMessageReceivedTimestamp)}</span>
|
||||
</div>
|
||||
<div className="subject">{subject(thread.subject)}</div>
|
||||
<div className="snippet">{thread.snippet}</div>
|
||||
|
|
|
@ -96,7 +96,7 @@ test_threads = -> [
|
|||
"email": "user2@nylas.com"
|
||||
}
|
||||
],
|
||||
"last_message_timestamp": 1415742036
|
||||
"last_message_received_timestamp": 1415742036
|
||||
}),
|
||||
(new Thread).fromJSON({
|
||||
"id": "222",
|
||||
|
@ -146,7 +146,7 @@ test_threads = -> [
|
|||
"email": "user3@nylas.com"
|
||||
}
|
||||
],
|
||||
"last_message_timestamp": 1415741913
|
||||
"last_message_received_timestamp": 1415741913
|
||||
}),
|
||||
(new Thread).fromJSON({
|
||||
"id": "333",
|
||||
|
@ -190,7 +190,7 @@ test_threads = -> [
|
|||
"email": "user4@nylas.com"
|
||||
}
|
||||
],
|
||||
"last_message_timestamp": 1415741837
|
||||
"last_message_received_timestamp": 1415741837
|
||||
})
|
||||
]
|
||||
|
||||
|
|
|
@ -133,12 +133,12 @@ describe "DatabaseView", ->
|
|||
beforeEach ->
|
||||
@inbox = new Label(id: 'l-1', name: 'inbox', displayName: 'Inbox')
|
||||
@archive = new Label(id: 'l-2', name: 'archive', displayName: 'archive')
|
||||
@a = new Thread(id: 'a', subject: 'a', labels:[@inbox], lastMessageTimestamp: new Date(1428526885604))
|
||||
@b = new Thread(id: 'b', subject: 'b', labels:[@inbox], lastMessageTimestamp: new Date(1428526885604))
|
||||
@c = new Thread(id: 'c', subject: 'c', labels:[@inbox], lastMessageTimestamp: new Date(1428526885604))
|
||||
@d = new Thread(id: 'd', subject: 'd', labels:[@inbox], lastMessageTimestamp: new Date(1428526885604))
|
||||
@e = new Thread(id: 'e', subject: 'e', labels:[@inbox], lastMessageTimestamp: new Date(1428526885604))
|
||||
@f = new Thread(id: 'f', subject: 'f', labels:[@inbox], lastMessageTimestamp: new Date(1428526885604))
|
||||
@a = new Thread(id: 'a', subject: 'a', labels:[@inbox], lastMessageReceivedTimestamp: new Date(1428526885604))
|
||||
@b = new Thread(id: 'b', subject: 'b', labels:[@inbox], lastMessageReceivedTimestamp: new Date(1428526885604))
|
||||
@c = new Thread(id: 'c', subject: 'c', labels:[@inbox], lastMessageReceivedTimestamp: new Date(1428526885604))
|
||||
@d = new Thread(id: 'd', subject: 'd', labels:[@inbox], lastMessageReceivedTimestamp: new Date(1428526885604))
|
||||
@e = new Thread(id: 'e', subject: 'e', labels:[@inbox], lastMessageReceivedTimestamp: new Date(1428526885604))
|
||||
@f = new Thread(id: 'f', subject: 'f', labels:[@inbox], lastMessageReceivedTimestamp: new Date(1428526885604))
|
||||
|
||||
@view = new DatabaseView Thread,
|
||||
matchers: [Thread.attributes.labels.contains('l-1')]
|
||||
|
@ -164,13 +164,13 @@ describe "DatabaseView", ->
|
|||
expect(@view.invalidateRetainedRange).toHaveBeenCalled()
|
||||
|
||||
it "should invalidate the entire range if a provided item is not in the set but matches the set", ->
|
||||
incoming = new Thread(id: 'a', subject: 'a', labels:[@inbox], lastMessageTimestamp: new Date())
|
||||
incoming = new Thread(id: 'a', subject: 'a', labels:[@inbox], lastMessageReceivedTimestamp: new Date())
|
||||
@view.invalidateAfterDatabaseChange({objects:[incoming], type:'persist'})
|
||||
expect(@view.invalidateRetainedRange).toHaveBeenCalled()
|
||||
|
||||
it "should invalidate the entire range if a provided item matches the set and the value of it's sorting attribute has changed", ->
|
||||
a = new Thread(@a)
|
||||
a.lastMessageTimestamp = new Date(1428526909533)
|
||||
a.lastMessageReceivedTimestamp = new Date(1428526909533)
|
||||
@view.invalidateAfterDatabaseChange({objects:[a], type:'persist'})
|
||||
expect(@view.invalidateRetainedRange).toHaveBeenCalled()
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ TestModel.configureWithAdditionalSQLiteConfig = ->
|
|||
modelKey: 'body'
|
||||
TestModel.additionalSQLiteConfig =
|
||||
setup: ->
|
||||
['CREATE INDEX IF NOT EXISTS ThreadListIndex ON Thread(last_message_timestamp DESC, namespace_id, id)']
|
||||
['CREATE INDEX IF NOT EXISTS ThreadListIndex ON Thread(last_message_received_timestamp DESC, namespace_id, id)']
|
||||
writeModel: jasmine.createSpy('additionalWriteModel')
|
||||
deleteModel: jasmine.createSpy('additionalDeleteModel')
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ describe "ModelQuery", ->
|
|||
expect(@q._matchers[1]).toBe(@m2)
|
||||
|
||||
it "should accept a shorthand format", ->
|
||||
@q.where({id: 4, lastMessageTimestamp: 1234})
|
||||
@q.where({id: 4, lastMessageReceivedTimestamp: 1234})
|
||||
expect(@q._matchers.length).toBe(2)
|
||||
expect(@q._matchers[0].attr.modelKey).toBe('id')
|
||||
expect(@q._matchers[0].comparator).toBe('=')
|
||||
|
@ -51,7 +51,7 @@ describe "ModelQuery", ->
|
|||
describe "order", ->
|
||||
beforeEach ->
|
||||
@q = new ModelQuery(Thread, @db)
|
||||
@o1 = Thread.attributes.lastMessageTimestamp.descending()
|
||||
@o1 = Thread.attributes.lastMessageReceivedTimestamp.descending()
|
||||
@o2 = Thread.attributes.subject.descending()
|
||||
|
||||
it "should accept an array of SortOrders", ->
|
||||
|
@ -126,7 +126,7 @@ describe "ModelQuery", ->
|
|||
builder: (q) -> q.where({namespaceId: 'abcd'}).one()
|
||||
sql: "SELECT `Thread`.`data` FROM `Thread` \
|
||||
WHERE `Thread`.`namespace_id` = 'abcd' \
|
||||
ORDER BY `Thread`.`last_message_timestamp` DESC LIMIT 1"
|
||||
ORDER BY `Thread`.`last_message_received_timestamp` DESC LIMIT 1"
|
||||
|
||||
it "should correctly generate `contains` queries using JOINS", ->
|
||||
@runScenario Thread,
|
||||
|
@ -134,7 +134,7 @@ describe "ModelQuery", ->
|
|||
sql: "SELECT `Thread`.`data` FROM `Thread` \
|
||||
INNER JOIN `Thread-Label` AS `M1` ON `M1`.`id` = `Thread`.`id` \
|
||||
WHERE `M1`.`value` = 'label-id' AND `Thread`.`id` = '1234' \
|
||||
ORDER BY `Thread`.`last_message_timestamp` DESC"
|
||||
ORDER BY `Thread`.`last_message_received_timestamp` DESC"
|
||||
|
||||
@runScenario Thread,
|
||||
builder: (q) -> q.where([Thread.attributes.labels.contains('l-1'), Thread.attributes.labels.contains('l-2')])
|
||||
|
@ -142,20 +142,20 @@ describe "ModelQuery", ->
|
|||
INNER JOIN `Thread-Label` AS `M1` ON `M1`.`id` = `Thread`.`id` \
|
||||
INNER JOIN `Thread-Label` AS `M2` ON `M2`.`id` = `Thread`.`id` \
|
||||
WHERE `M1`.`value` = 'l-1' AND `M2`.`value` = 'l-2' \
|
||||
ORDER BY `Thread`.`last_message_timestamp` DESC"
|
||||
ORDER BY `Thread`.`last_message_received_timestamp` DESC"
|
||||
|
||||
it "should correctly generate queries with the class's naturalSortOrder when one is available and no other orders are provided", ->
|
||||
@runScenario Thread,
|
||||
builder: (q) -> q.where({namespaceId: 'abcd'})
|
||||
sql: "SELECT `Thread`.`data` FROM `Thread` \
|
||||
WHERE `Thread`.`namespace_id` = 'abcd' \
|
||||
ORDER BY `Thread`.`last_message_timestamp` DESC"
|
||||
ORDER BY `Thread`.`last_message_received_timestamp` DESC"
|
||||
|
||||
@runScenario Thread,
|
||||
builder: (q) -> q.where({namespaceId: 'abcd'}).order(Thread.attributes.lastMessageTimestamp.ascending())
|
||||
builder: (q) -> q.where({namespaceId: 'abcd'}).order(Thread.attributes.lastMessageReceivedTimestamp.ascending())
|
||||
sql: "SELECT `Thread`.`data` FROM `Thread` \
|
||||
WHERE `Thread`.`namespace_id` = 'abcd' \
|
||||
ORDER BY `Thread`.`last_message_timestamp` ASC"
|
||||
ORDER BY `Thread`.`last_message_received_timestamp` ASC"
|
||||
|
||||
@runScenario Namespace,
|
||||
builder: (q) -> q.where({id: 'abcd'})
|
||||
|
|
|
@ -55,7 +55,7 @@ describe "DatabaseConnection", ->
|
|||
spyOn(TestModel.additionalSQLiteConfig, 'setup').andCallThrough()
|
||||
queries = @connection._setupQueriesForTable(TestModel)
|
||||
expect(TestModel.additionalSQLiteConfig.setup).toHaveBeenCalledWith()
|
||||
expect(queries.pop()).toBe('CREATE INDEX IF NOT EXISTS ThreadListIndex ON Thread(last_message_timestamp DESC, namespace_id, id)')
|
||||
expect(queries.pop()).toBe('CREATE INDEX IF NOT EXISTS ThreadListIndex ON Thread(last_message_received_timestamp DESC, namespace_id, id)')
|
||||
|
||||
it "should not fail if additional config is present, but setup is undefined", ->
|
||||
delete TestModel.additionalSQLiteConfig['setup']
|
||||
|
|
|
@ -25,7 +25,7 @@ This is equivalent to writing the following SQL:
|
|||
SELECT `Thread`.`data` FROM `Thread`
|
||||
INNER JOIN `Thread-Label` AS `M1` ON `M1`.`id` = `Thread`.`id`
|
||||
WHERE `M1`.`value` = 'inbox'
|
||||
ORDER BY `Thread`.`last_message_timestamp` DESC
|
||||
ORDER BY `Thread`.`last_message_received_timestamp` DESC
|
||||
```
|
||||
|
||||
The value of this attribute is always an array of ff other model objects. To use
|
||||
|
|
|
@ -24,7 +24,7 @@ query.then (thread) ->
|
|||
```coffee
|
||||
query = DatabaseStore.findAll(Thread)
|
||||
query.where([Thread.attributes.labels.contains('label-id')])
|
||||
.order([Thread.attributes.lastMessageTimestamp.descending()])
|
||||
.order([Thread.attributes.lastMessageReceivedTimestamp.descending()])
|
||||
.limit(100).offset(50)
|
||||
.then (threads) ->
|
||||
# array of threads
|
||||
|
|
|
@ -32,7 +32,7 @@ For more information about Threads on the Nylas Platform, read the
|
|||
representing the participants in the thread.
|
||||
Note: Contacts on Threads do not have IDs.
|
||||
|
||||
`lastMessageTimestamp`: {AttributeDateTime} The timestamp of the
|
||||
`lastMessageReceivedTimestamp`: {AttributeDateTime} The timestamp of the
|
||||
last message on the thread.
|
||||
|
||||
This class also inherits attributes from {Model}
|
||||
|
@ -74,17 +74,17 @@ class Thread extends Model
|
|||
modelKey: 'participants'
|
||||
itemClass: Contact
|
||||
|
||||
'lastMessageTimestamp': Attributes.DateTime
|
||||
'lastMessageReceivedTimestamp': Attributes.DateTime
|
||||
queryable: true
|
||||
modelKey: 'lastMessageTimestamp'
|
||||
jsonKey: 'last_message_timestamp'
|
||||
modelKey: 'lastMessageReceivedTimestamp'
|
||||
jsonKey: 'last_message_received_timestamp'
|
||||
|
||||
@naturalSortOrder: ->
|
||||
Thread.attributes.lastMessageTimestamp.descending()
|
||||
Thread.attributes.lastMessageReceivedTimestamp.descending()
|
||||
|
||||
@additionalSQLiteConfig:
|
||||
setup: ->
|
||||
['CREATE INDEX IF NOT EXISTS ThreadListIndex ON Thread(last_message_timestamp DESC, namespace_id, id)']
|
||||
['CREATE INDEX IF NOT EXISTS ThreadListIndex ON Thread(last_message_received_timestamp DESC, namespace_id, id)']
|
||||
|
||||
# Public: Returns true if the thread has a {Category} with the given ID.
|
||||
#
|
||||
|
|
Loading…
Add table
Reference in a new issue