Implement starred changes for user accounts, including async toggling
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -15,10 +15,30 @@
|
||||
package com.google.gerrit.client.changes;
|
||||
|
||||
import com.google.gerrit.client.data.AccountDashboardInfo;
|
||||
import com.google.gerrit.client.data.ChangeInfo;
|
||||
import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.Change;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.client.RemoteJsonService;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface ChangeListService extends RemoteJsonService {
|
||||
/** Get the data to show {@link AccountDashboardScreen} for an account. */
|
||||
void forAccount(Account.Id id, AsyncCallback<AccountDashboardInfo> callback);
|
||||
|
||||
/** Get the changes starred by the caller. */
|
||||
void myStarredChanges(AsyncCallback<List<ChangeInfo>> callback);
|
||||
|
||||
/** Get the ids of all changes starred by the caller. */
|
||||
void myStarredChangeIds(AsyncCallback<Set<Change.Id>> callback);
|
||||
|
||||
/**
|
||||
* Add and/or remove changes from the set of starred changes of the caller.
|
||||
*
|
||||
* @param req the add and remove cluster.
|
||||
*/
|
||||
void toggleStars(ToggleStarRequest req, AsyncCallback<VoidResult> callback);
|
||||
}
|
||||
|
||||
@@ -9,14 +9,20 @@ import com.google.gerrit.client.reviewdb.Account;
|
||||
import com.google.gerrit.client.reviewdb.Change;
|
||||
import com.google.gerrit.client.reviewdb.ChangeAccess;
|
||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.client.reviewdb.StarredChange;
|
||||
import com.google.gerrit.client.reviewdb.Change.Id;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.client.CookieAccess;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.ResultSet;
|
||||
import com.google.gwtorm.client.SchemaFactory;
|
||||
import com.google.gwtorm.client.Transaction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ChangeListServiceImpl implements ChangeListService {
|
||||
private final SchemaFactory<ReviewDb> schema;
|
||||
@@ -27,8 +33,9 @@ public class ChangeListServiceImpl implements ChangeListService {
|
||||
|
||||
public void forAccount(Account.Id id,
|
||||
AsyncCallback<AccountDashboardInfo> callback) {
|
||||
final Account.Id me = idFromCookie();
|
||||
if (id == null) {
|
||||
id = idFromCookie();
|
||||
id = me;
|
||||
}
|
||||
if (id == null) {
|
||||
callback.onFailure(new IllegalArgumentException("No Account.Id"));
|
||||
@@ -45,12 +52,19 @@ public class ChangeListServiceImpl implements ChangeListService {
|
||||
return;
|
||||
}
|
||||
|
||||
final Set<Change.Id> starred = new HashSet<Change.Id>();
|
||||
if (me != null) {
|
||||
for (final StarredChange sc : db.starredChanges().byAccount(me)) {
|
||||
starred.add(sc.getChangeId());
|
||||
}
|
||||
}
|
||||
|
||||
final ChangeAccess changes = db.changes();
|
||||
final AccountDashboardInfo d;
|
||||
|
||||
d = new AccountDashboardInfo(new AccountInfo(user));
|
||||
d.setByOwner(toInfoList(changes.byOwnerOpen(user.getId()), accts));
|
||||
d.setClosed(toInfoList(changes.byOwnerMerged(user.getId()), accts));
|
||||
d.setByOwner(list(changes.byOwnerOpen(user.getId()), starred, accts));
|
||||
d.setClosed(list(changes.byOwnerMerged(user.getId()), starred, accts));
|
||||
callback.onSuccess(d);
|
||||
} finally {
|
||||
db.close();
|
||||
@@ -60,11 +74,108 @@ public class ChangeListServiceImpl implements ChangeListService {
|
||||
}
|
||||
}
|
||||
|
||||
private List<ChangeInfo> toInfoList(final ResultSet<Change> rs,
|
||||
final AccountCache accts) throws OrmException {
|
||||
public void myStarredChanges(final AsyncCallback<List<ChangeInfo>> callback) {
|
||||
final Account.Id me = idFromCookie();
|
||||
if (me == null) {
|
||||
callback.onFailure(new IllegalArgumentException("Not signed in"));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final ReviewDb db = schema.open();
|
||||
try {
|
||||
final AccountCache accts = new AccountCache(db);
|
||||
final Set<Change.Id> starred = new HashSet<Change.Id>();
|
||||
for (final StarredChange sc : db.starredChanges().byAccount(me)) {
|
||||
starred.add(sc.getChangeId());
|
||||
}
|
||||
callback.onSuccess(list(db.changes().get(starred), starred, accts));
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleStars(final ToggleStarRequest req,
|
||||
final AsyncCallback<VoidResult> callback) {
|
||||
final Account.Id me = idFromCookie();
|
||||
if (me == null) {
|
||||
callback.onFailure(new IllegalArgumentException("Not signed in"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final ReviewDb db = schema.open();
|
||||
try {
|
||||
final Set<Change.Id> existing = new HashSet<Change.Id>();
|
||||
for (final StarredChange sc : db.starredChanges().byAccount(me)) {
|
||||
existing.add(sc.getChangeId());
|
||||
}
|
||||
|
||||
final ArrayList<StarredChange> add = new ArrayList<StarredChange>();
|
||||
final ArrayList<StarredChange> remove = new ArrayList<StarredChange>();
|
||||
if (req.getAddSet() != null) {
|
||||
for (final Change.Id id : req.getAddSet()) {
|
||||
if (!existing.contains(id)) {
|
||||
add.add(new StarredChange(new StarredChange.Key(me, id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (req.getRemoveSet() != null) {
|
||||
for (final Change.Id id : req.getRemoveSet()) {
|
||||
if (existing.contains(id)) {
|
||||
remove.add(new StarredChange(new StarredChange.Key(me, id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!add.isEmpty() || !remove.isEmpty()) {
|
||||
final Transaction txn = db.beginTransaction();
|
||||
db.starredChanges().insert(add);
|
||||
db.starredChanges().delete(remove);
|
||||
txn.commit();
|
||||
}
|
||||
callback.onSuccess(VoidResult.INSTANCE);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void myStarredChangeIds(final AsyncCallback<Set<Id>> callback) {
|
||||
final Account.Id me = idFromCookie();
|
||||
if (me == null) {
|
||||
callback.onFailure(new IllegalArgumentException("Not signed in"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final ReviewDb db = schema.open();
|
||||
try {
|
||||
final Set<Change.Id> existing = new HashSet<Change.Id>();
|
||||
for (final StarredChange sc : db.starredChanges().byAccount(me)) {
|
||||
existing.add(sc.getChangeId());
|
||||
}
|
||||
callback.onSuccess(existing);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ChangeInfo> list(final ResultSet<Change> rs,
|
||||
final Set<Change.Id> starred, final AccountCache accts)
|
||||
throws OrmException {
|
||||
final ArrayList<ChangeInfo> r = new ArrayList<ChangeInfo>();
|
||||
for (final Change c : rs) {
|
||||
r.add(new ChangeInfo(c, accts));
|
||||
final ChangeInfo ci = new ChangeInfo(c, accts);
|
||||
ci.setStarred(starred.contains(ci.getId()));
|
||||
r.add(ci);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -20,12 +20,14 @@ import com.google.gerrit.client.SignedInListener;
|
||||
import com.google.gerrit.client.data.ChangeInfo;
|
||||
import com.google.gerrit.client.reviewdb.Change;
|
||||
import com.google.gerrit.client.reviewdb.Change.Id;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.user.client.Command;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.DeferredCommand;
|
||||
import com.google.gwt.user.client.Element;
|
||||
import com.google.gwt.user.client.Event;
|
||||
import com.google.gwt.user.client.History;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.AbstractImagePrototype;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.FlexTable;
|
||||
@@ -40,10 +42,12 @@ import com.google.gwt.user.client.ui.SourcesTableEvents;
|
||||
import com.google.gwt.user.client.ui.TableListener;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
|
||||
import com.google.gwtjsonrpc.client.VoidCallback;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class ChangeTable extends Composite implements HasFocus {
|
||||
@@ -151,14 +155,25 @@ public class ChangeTable extends Composite implements HasFocus {
|
||||
|
||||
signedInListener = new SignedInListener() {
|
||||
public void onSignIn() {
|
||||
Util.LIST_SVC.myStarredChangeIds(new AsyncCallback<Set<Change.Id>>() {
|
||||
public void onFailure(final Throwable caught) {
|
||||
GWT.log("ChangeTable.onSignIn myStarredChangeIds failed", caught);
|
||||
}
|
||||
|
||||
public void onSuccess(final Set<Change.Id> result) {
|
||||
if (result != null) {
|
||||
final int max = table.getRowCount();
|
||||
for (int row = 0; row < max; row++) {
|
||||
final ChangeInfo c = getChangeInfo(row);
|
||||
if (c != null) {
|
||||
c.setStarred(result.contains(c.getId()));
|
||||
setStar(row, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onSignOut() {
|
||||
final int max = table.getRowCount();
|
||||
@@ -184,6 +199,10 @@ public class ChangeTable extends Composite implements HasFocus {
|
||||
if (c != null && Gerrit.isSignedIn()) {
|
||||
c.setStarred(!c.isStarred());
|
||||
setStar(row, c);
|
||||
|
||||
final ToggleStarRequest req = new ToggleStarRequest();
|
||||
req.toggle(c.getId(), c.isStarred());
|
||||
Util.LIST_SVC.toggleStars(req, VoidCallback.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,13 @@
|
||||
|
||||
package com.google.gerrit.client.changes;
|
||||
|
||||
import com.google.gerrit.client.data.ChangeInfo;
|
||||
import com.google.gerrit.client.ui.AccountScreen;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.user.client.History;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class MineStarredScreen extends AccountScreen {
|
||||
@@ -30,4 +36,20 @@ public class MineStarredScreen extends AccountScreen {
|
||||
table.addSection(starred);
|
||||
add(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
table.setSavePointerId(History.getToken());
|
||||
Util.LIST_SVC.myStarredChanges(new AsyncCallback<List<ChangeInfo>>() {
|
||||
public void onSuccess(final List<ChangeInfo> result) {
|
||||
starred.display(result);
|
||||
table.finishDisplay();
|
||||
}
|
||||
|
||||
public void onFailure(final Throwable caught) {
|
||||
GWT.log("Fail", caught);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.client.changes;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Change;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/** Request parameters to update the changes the user has toggled. */
|
||||
public class ToggleStarRequest {
|
||||
protected Set<Change.Id> add;
|
||||
protected Set<Change.Id> remove;
|
||||
|
||||
/**
|
||||
* Request an update to the change's star status.
|
||||
*
|
||||
* @param id unique id of the change, must not be null.
|
||||
* @param on true if the change should now be starred; false if it should now
|
||||
* be not starred.
|
||||
*/
|
||||
public void toggle(final Change.Id id, final boolean on) {
|
||||
if (on) {
|
||||
if (add == null) {
|
||||
add = new HashSet<Change.Id>();
|
||||
}
|
||||
add.add(id);
|
||||
if (remove != null) {
|
||||
remove.remove(id);
|
||||
}
|
||||
} else {
|
||||
if (remove == null) {
|
||||
remove = new HashSet<Change.Id>();
|
||||
}
|
||||
remove.add(id);
|
||||
if (add != null) {
|
||||
add.remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the set of changes which should have stars added; may be null. */
|
||||
public Set<Change.Id> getAddSet() {
|
||||
return add;
|
||||
}
|
||||
|
||||
/** Get the set of changes which should have stars removed; may be null. */
|
||||
public Set<Change.Id> getRemoveSet() {
|
||||
return remove;
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,9 @@ public interface ReviewDb extends Schema {
|
||||
@Relation
|
||||
AccountGroupMemberAccess accountGroupMembers();
|
||||
|
||||
@Relation
|
||||
StarredChangeAccess starredChanges();
|
||||
|
||||
@Relation
|
||||
ProjectAccess projects();
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.client.reviewdb;
|
||||
|
||||
import com.google.gwtorm.client.Column;
|
||||
|
||||
/** A {@link Change} starred by an {@link Account}. */
|
||||
public class StarredChange {
|
||||
public static class Key implements com.google.gwtorm.client.Key<Account.Id> {
|
||||
@Column
|
||||
protected Account.Id accountId;
|
||||
|
||||
@Column
|
||||
protected Change.Id changeId;
|
||||
|
||||
protected Key() {
|
||||
accountId = new Account.Id();
|
||||
changeId = new Change.Id();
|
||||
}
|
||||
|
||||
public Key(final Account.Id a, final Change.Id g) {
|
||||
accountId = a;
|
||||
changeId = g;
|
||||
}
|
||||
|
||||
public Account.Id getParentKey() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return accountId.hashCode() * 31 + changeId.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
return o instanceof Key && ((Key) o).accountId.equals(accountId)
|
||||
&& ((Key) o).changeId.equals(changeId);
|
||||
}
|
||||
}
|
||||
|
||||
@Column(name = Column.NONE)
|
||||
protected Key key;
|
||||
|
||||
protected StarredChange() {
|
||||
}
|
||||
|
||||
public StarredChange(final StarredChange.Key k) {
|
||||
key = k;
|
||||
}
|
||||
|
||||
public Account.Id getAccountId() {
|
||||
return key.accountId;
|
||||
}
|
||||
|
||||
public Change.Id getChangeId() {
|
||||
return key.changeId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.client.reviewdb;
|
||||
|
||||
import com.google.gwtorm.client.Access;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.PrimaryKey;
|
||||
import com.google.gwtorm.client.Query;
|
||||
import com.google.gwtorm.client.ResultSet;
|
||||
|
||||
public interface StarredChangeAccess extends
|
||||
Access<StarredChange, StarredChange.Key> {
|
||||
@PrimaryKey("key")
|
||||
StarredChange get(StarredChange.Key key) throws OrmException;
|
||||
|
||||
@Query("WHERE key.accountId = ?")
|
||||
ResultSet<StarredChange> byAccount(Account.Id id) throws OrmException;
|
||||
}
|
||||
Reference in New Issue
Block a user