vaadin / collaboration-engine

The simplest way to build real-time collaboration into web apps
https://vaadin.com/collaboration
Other
3 stars 1 forks source link

Enable rendering AvatarGroup with a custom visual representation. #37

Closed Peppe closed 3 years ago

Peppe commented 3 years ago

Use case

As a developer, I want to have access to the avatargroup information programmatically so that I can make a custom UI for showing avatars according to the project designs.

Example

I want to implement the UI that has avatars as a vertical list, with the avatar to the left and the name of the person to the right. Look at the right edge of the image. image.png

Legioth commented 3 years ago

This case is directly supported by the code example that I suggested in https://github.com/vaadin/collaboration-engine/issues/36. Implementation of createUserCard is left as an exercise to the reader. I just added one line to filter out your own user info since it doesn't look like it's included in the screenshot.

VerticalLayout users = new VerticalLayout();
PresenceCollaborationDao dao = new PresenceCollaborationDao(users, topicId, ownUserInfo);
dao.setPresence(ownUserInfo, true);
dao.setNewUserHandler(newUserInfo -> {
  if (newUserInfo.equals(ownUserInfo)) return null;
  Component card = createUserCard(newUserInfo);
  users.add(card);
  return () -> avatarGroup.remove(card);
});
Legioth commented 3 years ago

Alternative API design that doesn't force you to return a registration while still allowing the same convenience of not having to manually track the mappings.

VerticalLayout users = new VerticalLayout();
PresenceCollaborationDao dao = new PresenceCollaborationDao(users, topicId, ownUserInfo);
dao.setPresence(ownUserInfo, true);
dao.setNewUserHandler((newUserInfo, context) -> {
  if (newUserInfo.equals(ownUserInfo)) return;
  Component card = createUserCard(newUserInfo);
  users.add(card);
  context.onUserRemove(() -> avatarGroup.remove(card));
});
Peppe commented 3 years ago

Implementation of createUserCard is left as an exercise to the reader.

Here's my mockup code, if it happens to be useful.

private VerticalLayout getMemberList() {
    VerticalLayout memberList = new VerticalLayout();
    Label onlineNowLabel = new Label("Online now");
    onlineNowLabel.addClassNames("text-s", "text-secondary", "font-medium",
            "p-s", "leading-xs");
    memberList.add(onlineNowLabel);
    memberList.add(dummyAvatarComponent("Danny Stego",
            "https://i.pravatar.cc/150?img=61"));
    memberList.add(dummyAvatarComponent("Albi Mccray",
            "https://i.pravatar.cc/150?img=45"));
    memberList.add(dummyAvatarComponent("Casey Kim",
            "https://i.pravatar.cc/150?img=36"));
    memberList.add(dummyAvatarComponent("Drew Archer",
            "https://i.pravatar.cc/150?img=66"));
    memberList.add(dummyAvatarComponent("Kitty Mcfarland",
            "https://i.pravatar.cc/150?img=32"));
    memberList.setWidth("300px");
    memberList.addClassNames("bg-contrast-5", "border-l",
            "border-contrast-10", "pt-s");
    return memberList;
}

private Component dummyAvatarComponent(String name, String avatarUrl) {
    Avatar avatar = new Avatar(name, avatarUrl);
    Label label = new Label(name);
    label.addClassNames("font-medium");
    HorizontalLayout layout = new HorizontalLayout(avatar, label);
    layout.setAlignItems(Alignment.CENTER);
    return layout;
}

I just added one line to filter out your own user info since it doesn't look like it's included in the screenshot.

That's an oversight on my part. It is meant to have you as well on the list, but I forgot to take the user's own avatar into account when building the mock. But it is good to have the options.