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

