kballard / gitnub forked from Caged/gitnub
- Source
- Commits
- Network (35)
- Issues (0)
- Downloads (5)
- Wiki (1)
- Graphs
-
Tree:
5ff35a9
gitnub / CommitsController.rb
| a6ad7f3e » | Caged | 2008-03-03 | 1 | # | |
| 2 | # CommitsController.rb | ||||
| 3 | # GitNub | ||||
| 4 | # | ||||
| 5 | # Created by Justin Palmer on 3/2/08. | ||||
| 6 | # Copyright (c) 2008 Active Reload, LLC. All rights reserved. | ||||
| 7 | # | ||||
| 8 | |||||
| 9 | require 'osx/cocoa' | ||||
| 87d207d0 » | Caged | 2008-03-03 | 10 | require 'md5' | |
| d4b7e48b » | Caged | 2008-03-04 | 11 | require 'cgi' | |
| a6ad7f3e » | Caged | 2008-03-03 | 12 | ||
| 5ff35a94 » | kballard | 2008-03-21 | 13 | def gravatar_url(email, size=36) | |
| 14 | hash = MD5.hexdigest(email.downcase) | ||||
| 15 | NSURL.URLWithString("http://www.gravatar.com/avatar.php?gravatar_id=#{hash}&size=#{size}") | ||||
| 16 | end | ||||
| 17 | |||||
| a6ad7f3e » | Caged | 2008-03-03 | 18 | class CommitsController < OSX::NSObject | |
| 19 | ib_outlet :commits_table | ||||
| cc55a449 » | Caged | 2008-03-03 | 20 | ib_outlet :branch_select | |
| 3ba71262 » | Caged | 2008-03-04 | 21 | ib_outlet :paging_segment | |
| d4b7e48b » | Caged | 2008-03-04 | 22 | ib_outlet :commit_details | |
| 083bfdf7 » | Caged | 2008-03-09 | 23 | ib_outlet :application_controller | |
| a6ad7f3e » | Caged | 2008-03-03 | 24 | ||
| 25 | def awakeFromNib | ||||
| 3ba71262 » | Caged | 2008-03-04 | 26 | @current_commit_offset = 0 | |
| 27 | @offset = 50 | ||||
| d4b7e48b » | Caged | 2008-03-04 | 28 | @active_commit = nil | |
| 5ff35a94 » | kballard | 2008-03-21 | 29 | @branch = :master | |
| 30 | @icon_queue = NSOperationQueue.alloc.init | ||||
| 31 | @icon_url_map = {} | ||||
| 210a3f37 » | benstiglitz | 2008-03-12 | 32 | @icons = Hash.new do |hash, email| | |
| 5ff35a94 » | kballard | 2008-03-21 | 33 | url = gravatar_url(email) | |
| 34 | @icon_url_map[url] = email | ||||
| 35 | @icon_queue.addOperation(ImageLoadOperation.alloc.initWithURL_delegate(url, self)) | ||||
| 36 | hash[email] = NSImage.imageNamed(NSImageNameUser) | ||||
| 210a3f37 » | benstiglitz | 2008-03-12 | 37 | end | |
| 3ba71262 » | Caged | 2008-03-04 | 38 | ||
| 39 | if(fetch_git_repository) | ||||
| 78657c76 » | Caged | 2008-03-06 | 40 | setup_commit_detail_view | |
| a1d6f9d1 » | Caged | 2008-03-21 | 41 | fetch_commits_for @branch, @offset | |
| 3ba71262 » | Caged | 2008-03-04 | 42 | setup_branches_menu | |
| 43 | setup_paging_control | ||||
| 44 | @commits_table.reloadData | ||||
| 78d3665c » | Caged | 2008-03-03 | 45 | end | |
| 3ba71262 » | Caged | 2008-03-04 | 46 | end | |
| 47 | |||||
| 083bfdf7 » | Caged | 2008-03-09 | 48 | ib_action :perform_utility_action | |
| 49 | def perform_utility_action(segment) | ||||
| 50 | tag = segment.cell.tagForSegment(segment.selectedSegment) | ||||
| 51 | case tag | ||||
| 52 | when 0 then refresh_commits(segment) | ||||
| 53 | when 1 then @application_controller.show_info_panel(segment) | ||||
| 54 | end | ||||
| 55 | end | ||||
| 56 | |||||
| 57 | ib_action :refresh_commits | ||||
| 58 | def refresh_commits(sender) | ||||
| 59 | refresh | ||||
| 60 | end | ||||
| 61 | |||||
| 3ba71262 » | Caged | 2008-03-04 | 62 | ib_action :page_commits | |
| 63 | def page_commits(segment) | ||||
| 64 | tag = segment.cell.tagForSegment(segment.selectedSegment) | ||||
| 65 | case tag | ||||
| 66 | when 0 then @current_commit_offset -= @offset | ||||
| 67 | when 1 then @current_commit_offset = 0 | ||||
| 68 | when 2 then @current_commit_offset += @offset | ||||
| 69 | end | ||||
| 70 | |||||
| 71 | @current_commit_offset = 0 if @current_commit_offset == -(@offset) | ||||
| a1d6f9d1 » | Caged | 2008-03-21 | 72 | fetch_commits_for(@branch, @offset, @current_commit_offset) | |
| a6ad7f3e » | Caged | 2008-03-03 | 73 | @commits_table.reloadData | |
| cc55a449 » | Caged | 2008-03-03 | 74 | ||
| 4bfd4e9a » | Caged | 2008-03-09 | 75 | select_latest_commit | |
| 3ba71262 » | Caged | 2008-03-04 | 76 | ||
| 77 | if @commits.size == 0 || @current_commit_offset == 0 | ||||
| 78 | @paging_segment.setEnabled_forSegment(false, 0) | ||||
| 79 | @paging_segment.setEnabled_forSegment(true, 2) unless @commits.size == 0 | ||||
| 80 | elsif ((@current_commit_offset >= @offset) && (@commits.size % @offset == 0)) | ||||
| 81 | @paging_segment.setEnabled_forSegment(true, 0) | ||||
| 82 | @paging_segment.setEnabled_forSegment(true, 2) | ||||
| 83 | elsif @commits.size % @offset != 0 | ||||
| 84 | @paging_segment.setEnabled_forSegment(true, 0) | ||||
| 85 | @paging_segment.setEnabled_forSegment(false, 2) | ||||
| cc55a449 » | Caged | 2008-03-03 | 86 | end | |
| a6ad7f3e » | Caged | 2008-03-03 | 87 | end | |
| 88 | |||||
| 89 | def tableViewSelectionDidChange(notification) | ||||
| 0e0ed38a » | Caged | 2008-03-09 | 90 | update_main_document | |
| 4bfd4e9a » | Caged | 2008-03-09 | 91 | scrollView = @commit_details.mainFrame.frameView.documentView.enclosingScrollView | |
| 92 | scrollView.documentView.scrollPoint([0,0]) | ||||
| a6ad7f3e » | Caged | 2008-03-03 | 93 | end | |
| 94 | |||||
| 78d3665c » | Caged | 2008-03-03 | 95 | # DataSource Methods | |
| a6ad7f3e » | Caged | 2008-03-03 | 96 | def numberOfRowsInTableView(table_view) | |
| 97 | @commits ? @commits.size : 0 | ||||
| 98 | end | ||||
| 99 | |||||
| 100 | def tableView_objectValueForTableColumn_row(table_view, table_column, row) | ||||
| 66e4e62e » | Caged | 2008-03-16 | 101 | @commits[row].message.split(/\n/).first.to_s | |
| a6ad7f3e » | Caged | 2008-03-03 | 102 | end | |
| 103 | |||||
| 88e97175 » | benstiglitz | 2008-03-12 | 104 | objc_method :tableView_willDisplayCell_forTableColumn_row, 'v@:@@@i' | |
| 105 | def tableView_willDisplayCell_forTableColumn_row(table_view, cell, table_column, row) | ||||
| 106 | commit = @commits[row] | ||||
| b4da17cd » | Caged | 2008-03-14 | 107 | cell.subtitle = %(by #{commit.author.name} on #{commit.authored_date.to_system_time}) | |
| 4f75917d » | Caged | 2008-03-13 | 108 | cell.gravatarImage = @icons[commit.author.email] | |
| 3ba71262 » | Caged | 2008-03-04 | 109 | end | |
| 110 | |||||
| 4bfd4e9a » | Caged | 2008-03-09 | 111 | def webView_didFinishLoadForFrame(view, frame) | |
| 112 | select_latest_commit | ||||
| d4b7e48b » | Caged | 2008-03-04 | 113 | end | |
| d054f6d8 » | kballard | 2008-03-21 | 114 | ||
| 115 | def webView_contextMenuItemsForElement_defaultMenuItems(view, element, defaultMenuItems) | ||||
| 116 | nil | ||||
| 117 | end | ||||
| 5ff35a94 » | kballard | 2008-03-21 | 118 | ||
| 119 | def imageLoadForURL_didFinishLoading(url, image) | ||||
| 120 | email = @icon_url_map[url] | ||||
| 121 | @icons[email] = image | ||||
| 122 | # indices = NSMutableIndexSet.indexSet | ||||
| 123 | # @commits.each_with_index do |commit, idx| | ||||
| 124 | # if commit.author.email == email | ||||
| 125 | # indices.addIndex(idx) | ||||
| 126 | # end | ||||
| 127 | # end | ||||
| 128 | @commits_table.setNeedsDisplay(true) | ||||
| 129 | end | ||||
| 130 | |||||
| 131 | def imageLoadForURL_didFailWithError(url, error) | ||||
| 132 | STDERR.puts "Async image load failed for URL: #{url}\n#{error}" | ||||
| 133 | end | ||||
| 87efc5b9 » | Caged | 2008-03-12 | 134 | ||
| 4bfd4e9a » | Caged | 2008-03-09 | 135 | def select_latest_commit | |
| 136 | @commits_table.selectRowIndexes_byExtendingSelection(NSIndexSet.indexSetWithIndex(0), false) | ||||
| d4b7e48b » | Caged | 2008-03-04 | 137 | end | |
| 0e0ed38a » | Caged | 2008-03-09 | 138 | ||
| 139 | def update_main_document | ||||
| 140 | diffs = [] | ||||
| 141 | doc = @commit_details.mainFrame.DOMDocument | ||||
| 40708baa » | kballard | 2008-03-21 | 142 | title, message = active_commit.message.split("\n", 2) | |
| 143 | set_html("title", title.strip.gsub("\n", "<br />")) | ||||
| 144 | if message | ||||
| 145 | set_html("message", message.strip.gsub("\n", "<br />")) | ||||
| 146 | show_element("message") | ||||
| 147 | else | ||||
| 148 | hide_element("message") | ||||
| 149 | end | ||||
| 0e0ed38a » | Caged | 2008-03-09 | 150 | set_html("hash", active_commit.id) | |
| 151 | |||||
| 4f75917d » | Caged | 2008-03-13 | 152 | if Time.now.day == active_commit.authored_date.day | |
| b4da17cd » | Caged | 2008-03-14 | 153 | cdate = active_commit.authored_date.to_system_time(:time) | |
| 0e0ed38a » | Caged | 2008-03-09 | 154 | else | |
| b4da17cd » | Caged | 2008-03-14 | 155 | cdate = active_commit.authored_date.to_system_time | |
| 0e0ed38a » | Caged | 2008-03-09 | 156 | end | |
| 4f75917d » | Caged | 2008-03-13 | 157 | set_html("date", "#{cdate} by #{active_commit.author.name}") | |
| 0e0ed38a » | Caged | 2008-03-09 | 158 | ||
| 159 | file_list = doc.getElementById('files') | ||||
| 160 | diff_list = doc.getElementById('diffs') | ||||
| 161 | diff_list.setInnerHTML("") | ||||
| 162 | file_list.setInnerHTML("") | ||||
| 163 | |||||
| 164 | active_commit.diffs.each_with_index do |diff, i| | ||||
| 165 | li = doc.createElement('li') | ||||
| 166 | li.setAttribute__('id', "item-#{i}") | ||||
| 167 | li.setAttribute__('class', 'add') if diff.new_file | ||||
| 168 | li.setAttribute__('class', 'delete') if diff.deleted_file | ||||
| 169 | li.setInnerHTML(%(<a href="#diff-#{i}" class="">#{diff.b_path}</a>)) | ||||
| 170 | file_list.appendChild(li) | ||||
| 171 | |||||
| 98b5ff64 » | kballard | 2008-03-21 | 172 | unless diff.deleted_file or diff.diff.nil? | |
| 0e0ed38a » | Caged | 2008-03-09 | 173 | diff_div = doc.createElement('div') | |
| 174 | diff_div.setAttribute__('class', 'diff') | ||||
| 175 | diff_div.setAttribute__('id', "diff-#{i}") | ||||
| 176 | |||||
| 177 | colored_diff = [] | ||||
| 178 | html = CGI.escapeHTML(diff.diff) | ||||
| 179 | html.each_line do |line| | ||||
| 180 | if line =~ /^\+/ | ||||
| 181 | colored_diff << %(<div class="addline">#{line}</div>) | ||||
| 182 | elsif line =~ /^\-/ | ||||
| 183 | colored_diff << %(<div class="removeline">#{line}</div>) | ||||
| 184 | elsif line =~ /^@/ | ||||
| 185 | colored_diff << %(<div class="meta">#{line}</div>) | ||||
| 186 | else | ||||
| 187 | colored_diff << line | ||||
| 188 | end | ||||
| 189 | end | ||||
| 190 | |||||
| 191 | diff_div.setInnerHTML(%( | ||||
| 192 | <h3>#{File.basename(diff.b_path)}</h3> | ||||
| 193 | <pre><code class="diffcode">#{colored_diff}</pre></code> | ||||
| 194 | )) | ||||
| 195 | diff_list.appendChild(diff_div) | ||||
| 196 | end | ||||
| 197 | end | ||||
| 198 | end | ||||
| 4bfd4e9a » | Caged | 2008-03-09 | 199 | ||
| 083bfdf7 » | Caged | 2008-03-09 | 200 | def refresh | |
| 201 | current_commit = active_commit && active_commit.id | ||||
| a1d6f9d1 » | Caged | 2008-03-21 | 202 | @branch = @branch_select.titleOfSelectedItem | |
| 203 | fetch_commits_for @branch, @offset | ||||
| 083bfdf7 » | Caged | 2008-03-09 | 204 | ||
| 205 | @commits_table.reloadData | ||||
| 206 | |||||
| 207 | if current_commit | ||||
| 208 | new_commit = @commits.find { |x| x.id == current_commit } | ||||
| 209 | new_row = @commits.index(new_commit) | ||||
| 210 | @commits_table.selectRow_byExtendingSelection(new_row, false) | ||||
| 211 | end | ||||
| 212 | end | ||||
| 213 | |||||
| 4bfd4e9a » | Caged | 2008-03-09 | 214 | ||
| 215 | private | ||||
| 216 | |||||
| 217 | def active_commit | ||||
| 218 | @commits[@commits_table.selectedRow] | ||||
| 219 | end | ||||
| 220 | |||||
| 221 | def fetch_git_repository | ||||
| 222 | begin | ||||
| 223 | @repo = Grit::Repo.new(REPOSITORY_LOCATION) | ||||
| 224 | rescue Grit::InvalidGitRepositoryError | ||||
| 225 | return false | ||||
| 226 | end | ||||
| 227 | end | ||||
| 228 | |||||
| 229 | def fetch_commits_for(branch, quanity, offset = 0) | ||||
| 230 | @commits = @repo.commits(branch, quanity, offset) | ||||
| 231 | end | ||||
| 232 | |||||
| 233 | def setup_branches_menu | ||||
| 234 | @branch_select.removeAllItems | ||||
| 235 | @repo.branches.each do |branch| | ||||
| 236 | @branch_select.addItemWithTitle(branch.name) | ||||
| 237 | end | ||||
| a1d6f9d1 » | Caged | 2008-03-21 | 238 | @branch_select.selectItemWithTitle(@branch) | |
| 4bfd4e9a » | Caged | 2008-03-09 | 239 | end | |
| 240 | |||||
| 241 | def setup_paging_control | ||||
| 242 | if @commits.size < @offset | ||||
| 243 | @paging_segment.setEnabled_forSegment(false, 2) | ||||
| 244 | @paging_segment.setEnabled_forSegment(false, 1) | ||||
| 245 | end | ||||
| 246 | end | ||||
| 247 | |||||
| 248 | def setup_commit_detail_view | ||||
| 249 | commit_detail = File.join(NSBundle.mainBundle.bundlePath, "Contents", "Resources", "commit.html") | ||||
| 250 | @commit_details.mainFrame.loadRequest(NSURLRequest.requestWithURL(NSURL.fileURLWithPath(commit_detail))) | ||||
| 251 | end | ||||
| 252 | |||||
| 253 | def set_html(element, html) | ||||
| 254 | @commit_details.mainFrame.DOMDocument.getElementById(element).setInnerHTML(html) | ||||
| 255 | end | ||||
| 40708baa » | kballard | 2008-03-21 | 256 | ||
| 257 | def show_element(element) | ||||
| 258 | element = @commit_details.mainFrame.DOMDocument.getElementById(element) | ||||
| 259 | element.style.removeProperty("display") | ||||
| 260 | end | ||||
| 261 | |||||
| 262 | def hide_element(element) | ||||
| 263 | element = @commit_details.mainFrame.DOMDocument.getElementById(element) | ||||
| 264 | element.style.setProperty_value_priority("display", "none", nil) | ||||
| 265 | end | ||||
| a6ad7f3e » | Caged | 2008-03-03 | 266 | end | |
