diff --git a/client/issues/issue.css b/client/issues/issue.css
index 2b44398..8b69bb4 100644
--- a/client/issues/issue.css
+++ b/client/issues/issue.css
@@ -24,6 +24,25 @@
vertical-align: middle;
}
+.claimed-text {
+ padding-right: 50px;
+ color: white;
+ border-size: 5px;
+ border-radius: 5px;
+}
+.claim-button, .unclaim-button {
+ background-color: green;
+ border-radius: 2px;
+ border-size: 2px;
+ border-color: transparent;
+ float: right;
+ cursor: pointer;
+}
+
+.unclaim-button {
+ background-color: red;
+}
+
.needs-response {
background-color: white;
border-radius: 2px;
diff --git a/client/issues/issue.html b/client/issues/issue.html
index 9e3f7c8..d8f2591 100644
--- a/client/issues/issue.html
+++ b/client/issues/issue.html
@@ -6,6 +6,18 @@
#{{issueDocument.number}}
({{status}})
+ {{#unless claimed}}
+
+ {{else}}
+
+
+ Issue has been claimed by {{claimedBy}}
+
+ {{/unless}}
{{#if displayNeedsResponseButton}}
needs response
diff --git a/client/issues/issue.js b/client/issues/issue.js
index 2560ff1..0dd42ec 100644
--- a/client/issues/issue.js
+++ b/client/issues/issue.js
@@ -56,5 +56,21 @@ Template.issue.events({
number: this.issueDocument.number
});
Session.set(displayId(this), false);
+ },
+ 'click .claim-button': function() {
+ Meteor.call('claim', {
+ repoOwner: this.repoOwner,
+ repoName: this.repoName,
+ number: this.issueDocument.number
+ });
+ Session.set(displayId(this), false);
+ },
+ 'click .unclaim-button': function() {
+ Meteor.call('unclaim', {
+ repoOwner: this.repoOwner,
+ repoName: this.repoName,
+ number: this.issueDocument.number
+ });
+ Session.set(displayId(this), false);
}
});
diff --git a/packages/hubble:issue-sync/classify.js b/packages/hubble:issue-sync/classify.js
index ae41857..14afe91 100644
--- a/packages/hubble:issue-sync/classify.js
+++ b/packages/hubble:issue-sync/classify.js
@@ -12,6 +12,49 @@ P.asyncMethod('needsResponse', function (options, cb) {
recordAction('needsResponses', options, cb);
});
+Meteor.methods(
+{
+ claim : function(options, cb) {
+ check(options, {
+ repoOwner: String,
+ repoName: String,
+ number: Match.Integer
+ });
+ var mongoId = P.issueMongoId(options.repoOwner, options.repoName, options.number);
+ if (! Issues.findOne(mongoId)) {
+ cb(new Meteor.Error(404, "No such issue"));
+ return;
+ }
+ var user = new Meteor.user();
+ Issues.update(mongoId, {
+ $set: {
+ claimed: true,
+ claimedBy: user.services.github.username
+ }
+ });
+ },
+
+ unclaim: function(options, cb) {
+ check(options, {
+ repoOwner: String,
+ repoName: String,
+ number: Match.Integer
+ });
+ var mongoId = P.issueMongoId(options.repoOwner, options.repoName, options.number);
+ if (! Issues.findOne(mongoId)) {
+ cb(new Meteor.Error(404, "No such issue"));
+ return;
+ }
+ var user = new Meteor.user();
+ Issues.update(mongoId, {
+ $set: {
+ claimed: false,
+ claimedBy: null
+ }
+ });
+ }
+});
+
var recordAction = function (actionField, options, cb) {
var mongoId;
diff --git a/publish.js b/publish.js
index 790e240..582263e 100644
--- a/publish.js
+++ b/publish.js
@@ -15,7 +15,9 @@ if (Meteor.isServer) {
lastUpdateOrComment: 1,
highlyActive: 1,
status: 1,
- canBeSnoozed: 1
+ canBeSnoozed: 1,
+ claimed: 1,
+ claimedBy: 1
};
Meteor.publish('issues-by-status', function (status) {