Implement starred changes for user accounts, including async toggling

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2008-11-27 22:29:11 -08:00
parent 88f26588b1
commit b0828d47f6
8 changed files with 351 additions and 12 deletions

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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,13 +155,24 @@ public class ChangeTable extends Composite implements HasFocus {
signedInListener = new SignedInListener() {
public void onSignIn() {
final int max = table.getRowCount();
for (int row = 0; row < max; row++) {
final ChangeInfo c = getChangeInfo(row);
if (c != null) {
setStar(row, c);
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() {
@@ -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);
}
}

View File

@@ -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);
}
});
}
}

View File

@@ -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;
}
}