Skip to content

Update blame view upon save #31

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

Merged
merged 4 commits into from
Sep 6, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 1 addition & 3 deletions lib/controllers/blameViewController.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ function toggleBlame(projectBlamer) {
editorView.blameView = React.renderComponent(new BlameListView({
projectBlamer: projectBlamer,
remoteRevision: remoteRevision,
filePath: filePath,
lineCount: editor.getLineCount(),
scrollbar: editorView.find('.vertical-scrollbar')
editorView: editorView
}), mountPoint[0]);
} else {
editorView.blameView.toggle();
Expand Down
11 changes: 7 additions & 4 deletions lib/views/blame-line-view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ moment = require 'moment'

HASH_LENGTH = 7 # github uses this length
BLANK_HASH = '-'.repeat(HASH_LENGTH)
DEFAULT_DATE = formatDate moment("2000-01-01T13:17:00 Z")

_defaultDate = null
getDefaultDate = ->
_defaultDate ?= formatDate moment("2014-01-01T13:37:00 Z")


renderLoading = ->
div className: 'blame-line loading',
span className: 'hash', BLANK_HASH
span className: 'date', DEFAULT_DATE
span className: 'date', getDefaultDate()
span className: 'committer', 'Loading'


Expand Down Expand Up @@ -50,7 +53,7 @@ BlameLineComponent = React.createClass
componentWillUnmount: ->
$(@getDOMNode()).tooltip "destroy"

shouldComponentUpdate: ->
false
shouldComponentUpdate: ({hash}) ->
hash isnt @props.hash

module.exports = {BlameLineComponent, renderLoading}
67 changes: 44 additions & 23 deletions lib/views/blame-list-view.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{React, Reactionary, $} = require 'atom'
{div, span, a} = Reactionary
{div} = Reactionary
RP = React.PropTypes
_ = require 'underscore'
{BlameLineComponent, renderLoading} = require './blame-line-view'
Expand All @@ -9,12 +9,12 @@ BlameListLinesComponent = React.createClass
propTypes:
annotations: RP.arrayOf(RP.object)
loading: RP.bool.isRequired
filePath: RP.string.isRequired
lineCount: RP.number.isRequired
dirty: RP.bool.isRequired
initialLineCount: RP.number.isRequired
remoteRevision: RP.object.isRequired

renderLoading: ->
lines = [0...@props.lineCount].map renderLoading
lines = [0...@props.initialLineCount].map renderLoading
div null, lines

# makes background color alternate by commit
Expand Down Expand Up @@ -49,28 +49,34 @@ BlameListLinesComponent = React.createClass
else
@renderLoaded()

shouldComponentUpdate: ({loading}) ->
loading isnt @props.loading

shouldComponentUpdate: ({loading, dirty}) ->
finishedInitialLoad = @props.loading and not loading and not @props.dirty
finishedEdit = @props.dirty and not dirty
finishedInitialLoad or finishedEdit

BlameListView = React.createClass
propTypes:
projectBlamer: RP.object.isRequired
remoteRevision: RP.object.isRequired
filePath: RP.string.isRequired
lineCount: RP.number.isRequired
scrollbar: RP.object.isRequired
editorView: RP.object.isRequired

getInitialState: ->
{
# TODO: get this from the parent component somehow?
scrollTop: @props.scrollbar.scrollTop()
scrollTop: @scrollbar().scrollTop()
# TODO: be intelligent about persisting this so it doesn't reset
width: 210
loading: true
visible: true
dirty: false
}

scrollbar: ->
@_scrollbar ?= @props.editorView.find('.vertical-scrollbar')

editor: ->
@_editor ?= @props.editorView.getModel()

render: ->
display = if @state.visible then 'inline-block' else 'none'

Expand All @@ -85,10 +91,9 @@ BlameListView = React.createClass
BlameListLinesComponent
annotations: @state.annotations
loading: @state.loading
filePath: @props.filePath
lineCount: @props.lineCount
dirty: @state.dirty
initialLineCount: @editor().getLineCount()
remoteRevision: @props.remoteRevision

div
className: 'git-blame'
style: width: @state.width, display: display
Expand All @@ -107,38 +112,54 @@ BlameListView = React.createClass

componentWillMount: ->
# kick off async request for blame data
@loadBlame true

loadBlame: (force) ->
return if @state.loading and not force
@loadBlame()
@editor().on 'contents-modified', @contentsModified
@editor().buffer.on 'saved', @saved

loadBlame: ->
@setState loading: true
@props.projectBlamer.blame @props.filePath, (err, data) =>
@props.projectBlamer.blame @editor().getPath(), (err, data) =>
if err
@setState
loading: false
error: true
dirty: false
else
@setState
loading: false
error: false
dirty: false
annotations: data

contentsModified: ->
return unless @isMounted()
@setState dirty: true unless @state.dirty

saved: ->
return unless @isMounted()
@loadBlame() if @state.visible and @state.dirty

toggle: ->
@setState visible: !@state.visible
if @state.visible
@setState visible: false
else
@loadBlame() if @state.dirty
@setState visible: true

componentDidMount: ->
# Bind to scroll event on vertical-scrollbar to sync up scroll position of
# blame gutter.
@props.scrollbar.on 'scroll', @matchScrollPosition
@scrollbar().on 'scroll', @matchScrollPosition

componentWillUnmount: ->
@props.scrollbar.off 'scroll', @matchScrollPosition
@scrollbar().off 'scroll', @matchScrollPosition
@editor().off 'contents-modified', @contentsModified
@editor().buffer.off 'saved', @saved

# Makes the view arguments scroll position match the target elements scroll
# position
matchScrollPosition: ->
@setState scrollTop: @props.scrollbar.scrollTop()
@setState scrollTop: @scrollbar().scrollTop()

resizeStarted: ({pageX}) ->
@setState dragging: true, initialPageX: pageX, initialWidth: @state.width
Expand Down