Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Dicebear with static generated images #131

Open
agjohnson opened this issue Mar 2, 2023 · 3 comments · May be fixed by #181
Open

Replace Dicebear with static generated images #131

agjohnson opened this issue Mar 2, 2023 · 3 comments · May be fixed by #181
Assignees
Labels
Improvement Minor improvement to code

Comments

@agjohnson
Copy link
Contributor

agjohnson commented Mar 2, 2023

I really like the project list display with image icons in the view. However, not all projects will have this. We are using the GitHub supplied avatar_url for projects with a connected remote_repo, but for others, we need something generative or a default image.

For now, I'm using Dicebear hosted images, which ultimately are SVGs currently.

In the future, we probably want these on our domain, and it wouldn't be hard to generate these and serve the statically. We probably want to:

  • Generate 50-10 images and store them in our repo
  • Reference these files by some sort of hashing. {project.pk % 50}.svg even
  • Tune the look and feel of the icons, I didn't do much here yet. We could use initials too.

We might also want to do this for default user, team, and organization images. Right now we rely on gravatar for organizations (weird), lots of users have the empty face icon, and we have no visual identifier for teams besides a name.

Update

The PR attached here implements a nice replacement for projects without remote repo avatar URLs, but it did overlook some caching attacks. With an API v3 change, it would be possible to do this all from the front end side instead. I'll wait on this to continue, if someone wants to jump in on that change (it should be small, but I haven't looked yet)

@agjohnson agjohnson added the Improvement Minor improvement to code label Mar 2, 2023
@agjohnson
Copy link
Contributor Author

So, I thought about this one a bit more today and I lean towards a dynamic implementation using a view, not generating a static number of images.

The reason for this is that for project avatars, we want to always show the GitHub avatar_url first if it exists. This means that this image will always have conditional logic, and I can't always reference that logic from front end code.

However, if this is instead a dynamic view, we can make the decision to redirect the image to the remote repo avatar URL, and if that image isn't defined, show our own generated avatar instead. In this case, I do not need to make a decision inside templates or front end JS whether to show the GitHub avatar or our avatar, I can instead just point to a URL:

<img src="/projects/test-builds/images/avatar/" />

This was already on my radar, as the Dicebear images were a bit of a placeholder, but I got excited about writing some Python for once and landed on something usable:

image

The images are reproducible SVGs, based on a random seed for the project. I used the Dicebear "initials" avatar SVG source to generate our template. We'd want to cache for some amount of time of course.

The idea would be a project avatar, but also eventually user, team, and organization default avatars.

There is some stuff to talk through in my implementation, so I'll put it up as a draft and we can talk more there.

@agjohnson agjohnson self-assigned this Jun 24, 2023
@agjohnson agjohnson linked a pull request Jun 24, 2023 that will close this issue
@humitos
Copy link
Member

humitos commented Jul 24, 2023

With an API v3 change, it would be possible to do this all from the front end side instead

This is now possible (see readthedocs/readthedocs.org#10513)

@agjohnson
Copy link
Contributor Author

agjohnson commented Apr 18, 2024

Generating an SVG here is still an option, but I just realized that generating a single sprite image is also an option and one that would be avoid multiple requests and able to be cached too.

The current Dicebear variant is stacked shapes, but other options like zoomed in pixel art could be used here too. The sprite image could be used with or without overlap, giving a fair number of unique combinations for a small image.

Pixel art especially, as we can zoom in instead of using an image with the final aspect ratio. For example, the project avatar images could be 4x4 pixels zoomed to 40x40px. With 50% overlap, a 160x100px sprite image can have ~3800 combinations and would <20Kb uncompressed.

.avatar {
  background-image: url("foo.gif");
  background-size: 1600px 1000px;
  width: 40px;
  height: 40px;
  image-rendering: pixelated;
}

.avatar.1a {
  background-position-x: -800px;
}

.avatar.2b {
  background-position-y: -500px;
}

/* <div class="avatar 1a 2b">Project with initials AB</div> */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Improvement Minor improvement to code
Projects
Status: Planned
Development

Successfully merging a pull request may close this issue.

2 participants