fix(*): Throttle so that DatabaseView won't pile on queries during scroll, better small attachment styles

Summary:
fix(attachment): Bad filenames breaking icons

fix developer bar colors

fix critical bug with files

Render small attachments inline-block, without hover effect, and with nice dotted transparency background

Test Plan: No new tests

Reviewers: evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D1661
This commit is contained in:
Ben Gotow 2015-06-19 11:31:27 -07:00
parent 0e96dd3372
commit 19d97e5393
10 changed files with 96 additions and 43 deletions

View file

@ -14,12 +14,13 @@ class ImageAttachmentComponent extends AttachmentComponent
</span>
<div className="attachment-file-actions">
{@_fileActions()}
{@_renderFileActions()}
</div>
<div className="attachment-preview" onClick={@_onClickView}>
<div className="attachment-name-bg"></div>
<div className="attachment-name">{@props.file.filename}</div>
<div className="attachment-name-container">
<div className="attachment-name">{@props.file.filename}</div>
</div>
{@_imgOrLoader()}
</div>

View file

@ -79,8 +79,11 @@
}
}
.image-file-upload, .image-attachment-file-wrap, .attachment-file-wrap,
.image-file-upload,
.image-attachment-file-wrap,
.attachment-file-wrap,
.attachment-inner-wrap {
.attachment-download-bar-wrap {
display: none;
}
@ -128,10 +131,15 @@
}
}
.image-attachment-file-wrap, .image-file-upload {
.image-attachment-file-wrap,
.image-file-upload {
position: relative;
margin: 0 0 8px 0;
text-align: center;
display:inline-block;
vertical-align: top;
margin-bottom: @spacing-standard;
margin-right: @spacing-standard;
.attachment-download-progress,
.attachment-upload-progress {
@ -147,11 +155,11 @@
}
&:hover {
.attachment-file-actions, .attachment-name-bg, .attachment-name {
.attachment-file-actions, .attachment-name-container, .attachment-name {
display: block;
}
}
.attachment-file-actions, .attachment-name-bg, .attachment-name {
.attachment-file-actions, .attachment-name-container, .attachment-name {
display: none;
}
@ -167,30 +175,35 @@
.attachment-preview {
position: relative;
z-index: 1;
overflow: hidden;
.attachment-name-bg {
.attachment-name-container {
position: absolute;
bottom: 0;
top: 0;
z-index: 2;
width: 100%;
background: linear-gradient(to top, rgba(0,0,0,0.75) 0%,rgba(0,0,0,0) 23%)
}
.attachment-name {
color: @white;
left: 15px;
bottom: 13px;
position: absolute;
z-index: 3;
height:100%;
min-height:300px;
background: linear-gradient(to top, rgba(0,0,0,0.75) 0%,rgba(0,0,0,0) 23%);
vertical-align:bottom;
.attachment-name {
color: @white;
left: @spacing-standard;
bottom: @spacing-standard;
position: absolute;
z-index: 3;
}
}
img {
position: relative;
z-index: 1;
max-width: 100%;
background: @background-secondary;
background: url(../static/images/attachments/transparency-background.png) top left repeat;
background-size:8px;
}
}
}

View file

@ -18,8 +18,9 @@ class ImageFileUpload extends FileUpload
</div>
<div className="attachment-preview" >
<div className="attachment-name-bg"></div>
<div className="attachment-name">{@props.uploadData.fileName}</div>
<div className="attachment-name-container">
<div className="attachment-name">{@props.uploadData.fileName}</div>
</div>
<DraggableImg src={@props.uploadData.filePath} />
</div>

View file

@ -9,7 +9,7 @@
order:1000;
display:flex;
flex-direction:column;
.resizable {
display: flex;
width:100%;
@ -49,12 +49,12 @@
font-size: 13px;
line-height: 15px;
height: 25px;
background-color: #999;
background: rgba(60,60,60,1);
color: white;
}
.btn:hover {
background-color: #AAA;
background: rgba(40,40,40,1);
}
.fa-caret-square-o-down,
@ -146,7 +146,7 @@
color: white;
}
}
&.long-polling {
.item {
@ -214,5 +214,3 @@
}
}

View file

@ -12,7 +12,8 @@ class ThreadListIcon extends React.Component
thread: React.PropTypes.object
_iconType: =>
myEmail = NamespaceStore.current()?.emailAddress
if !@props.thread
return 'thread-icon-star-on-hover'
if @props.thread.hasTagId('starred')
return 'thread-icon-star'
@ -23,6 +24,7 @@ class ThreadListIcon extends React.Component
msgs = @_nonDraftMessages()
last = msgs[msgs.length - 1]
myEmail = NamespaceStore.current()?.emailAddress
if msgs.length > 1 and last.from[0]?.email is myEmail
if Utils.isForwardedMessage(last)
return 'thread-icon-forwarded thread-icon-star-on-hover'

View file

@ -159,13 +159,19 @@ class ModelQuery
Query Execution
###
# Public: Starts query execution and returns a Promise.
# Public: Short-hand syntax that calls run().then(fn) with the provided function.
#
# Returns a {Promise} that resolves with the Models returned by the
# query, or rejects with an error from the Database layer.
#
then: (next) ->
@_database.run(@).then(next)
@run(@).then(next)
# Public: Returns a {Promise} that resolves with the Models returned by the
# query, or rejects with an error from the Database layer.
#
run: ->
@_database.run(@)
formatResult: (result) ->
return null unless result

View file

@ -6,6 +6,36 @@ EventEmitter = require('events').EventEmitter
verbose = true
# A small helper class that prevents the DatabaseView from making too many
# queries. It tracks the number of jobs in flight via `increment` and allows
# a callback to run "when there are fewer then N ongoing queries".
# Sort of like _.throttle, but with a work threshold rather than a time threshold.
class TaskThrottler
constructor: (@_maxConcurrent) ->
@_inflight = 0
@_whenReady = null
whenReady: (fn) ->
if @_inflight < @_maxConcurrent
fn()
else
@_whenReady = fn
increment: ->
decremented = false
@_inflight += 1
# Returns a function that can be called once and only once to
# decrement the counter.
return =>
if not decremented
@_inflight -= 1
if @_whenReady and @_inflight < @_maxConcurrent
@_whenReady()
@_whenReady = null
decremented = true
# Public: DatabaseView abstracts away the process of paginating a query
# and loading ranges of data. It's very smart about deciding when
# results need to be refreshed. There are a few core concepts that
@ -34,13 +64,15 @@ class DatabaseView extends ModelView
constructor: (@klass, config = {}, @_metadataProvider) ->
super
@_pageSize = 100
@_throttler = new TaskThrottler(2)
@_matchers = config.matchers ? []
@_includes = config.includes ? []
@_orders = config.orders ? []
@_count = -1
@invalidateCount()
@invalidateRetainedRangeImmediate()
@invalidateRetainedRange()
@
log: ->
@ -251,18 +283,16 @@ class DatabaseView extends ModelView
@_count = count
@_emitter.emit('trigger')
invalidateRetainedRange: _.debounce ->
@invalidateRetainedRangeImmediate()
,10
invalidateRetainedRangeImmediate: ->
for idx in @pagesRetained()
@retrievePage(idx)
invalidateRetainedRange: ->
@_throttler.whenReady =>
for idx in @pagesRetained()
@retrievePage(idx)
retrieveDirtyInRetainedRange: ->
for idx in @pagesRetained()
if not @_pages[idx] or @_pages[idx].lastTouchTime > @_pages[idx].lastLoadTime
@retrievePage(idx)
@_throttler.whenReady =>
for idx in @pagesRetained()
if not @_pages[idx] or @_pages[idx].lastTouchTime > @_pages[idx].lastLoadTime
@retrievePage(idx)
retrievePage: (idx) ->
page = @_pages[idx] ? {
@ -284,7 +314,8 @@ class DatabaseView extends ModelView
query.include(attr) for attr in @_includes
query.order(@_orders) if @_orders.length > 0
query.then (items) =>
decrement = @_throttler.increment()
query.run().finally(decrement).then (items) =>
# If the page is no longer in the cache at all, it may have fallen out of the
# retained range and been cleaned up.
return unless @_pages[idx]
@ -323,7 +354,8 @@ class DatabaseView extends ModelView
if idsMissingMetadata.length > 0 and @_metadataProvider
metadataPromise = @_metadataProvider(idsMissingMetadata)
metadataPromise.then (results) =>
decrement = @_throttler.increment()
metadataPromise.finally(decrement).then (results) =>
# If we've started reloading since we made our query, don't do any more work
if page.lastTouchTime >= touchTime
@log("Metadata version #{touchTime} fetched, but out of date (current is #{page.lastTouchTime})")

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB