diff --git a/package.json b/package.json index cc75a890..e8628ecc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "impro", - "version": "0.18.184", + "version": "0.18.185", "type": "module", "scripts": { "start": "rm -rf \"${BUILD_DIR:-build}\" && NODE_ENV=development eleventy --serve", diff --git a/src/css/style.css b/src/css/style.css index 870ec5f8..2febc4ff 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -874,7 +874,8 @@ input[type="color"]::-moz-color-swatch { width: var(--avatar-size-post); height: var(--avatar-size-post); border-radius: var(--avatar-border-radius); - background-color: var(--generic-border-color); + border: var(--hair) solid var(--post-border-color); + background-color: var(--skeleton-color); } header { @@ -1216,12 +1217,6 @@ tab-bar:not([full-width]) { border: var(--hair) solid var(--post-border-color); } -.sidebar-profile-avatar .avatar-placeholder { - border-radius: var(--avatar-border-radius); - background-color: var(--skeleton-color); - border: var(--hair) solid var(--post-border-color); -} - .sidebar-profile-info { margin-bottom: 12px; } @@ -1556,12 +1551,9 @@ button.sidebar-plugin-nav-item { height: var(--avatar-size-footer-nav); } -.footer-nav-item .avatar-image-placeholder { +.footer-nav-item .avatar-placeholder { width: var(--avatar-size-footer-nav); height: var(--avatar-size-footer-nav); - border-radius: var(--avatar-border-radius); - background-color: var(--skeleton-color); - border: var(--hair) solid var(--post-border-color); } .footer-nav-item[disabled] { @@ -3568,7 +3560,8 @@ image-carousel { flex-shrink: 0; } -.convo-avatar .avatar-image-frame { +.convo-avatar .avatar-image-frame, +.convo-avatar .avatar-placeholder { width: var(--avatar-size-convo); height: var(--avatar-size-convo); } @@ -3579,10 +3572,16 @@ image-carousel { height: var(--avatar-size-convo); } +.avatar-group > .avatar-placeholder { + width: 100%; + height: 100%; +} + .avatar-group-item { position: absolute; } +.avatar-group-item .avatar, .avatar-group-item .avatar-image-frame { display: block; width: 100%; @@ -4122,7 +4121,8 @@ image-carousel { align-self: flex-start; } -.message-avatar .avatar-image-frame { +.message-avatar .avatar-image-frame, +.message-avatar .avatar-placeholder { width: var(--avatar-size-message); height: var(--avatar-size-message); } @@ -5071,6 +5071,7 @@ chat-input .rich-text-input-placeholder { .reaction-row-avatar .avatar, .reaction-row-avatar .avatar-image-frame, +.reaction-row-avatar .avatar-placeholder, .reaction-row-avatar .avatar-image { width: 42px; height: 42px; @@ -8486,7 +8487,7 @@ context-menu-item-group > context-menu-item > button { } .account-switcher-item .avatar, -.account-switcher-item .avatar-image-placeholder, +.account-switcher-item .avatar-placeholder, .account-switcher-item .skeleton-avatar { width: 40px; height: 40px; diff --git a/src/js/components/account-switcher-dialog.js b/src/js/components/account-switcher-dialog.js index 5042448c..9da2ba3f 100644 --- a/src/js/components/account-switcher-dialog.js +++ b/src/js/components/account-switcher-dialog.js @@ -181,9 +181,7 @@ class AccountSwitcherDialog extends Component { author: profile, clickAction: "none", }) - : html`
`} + : html`
`} diff --git a/src/js/templates/avatarGroup.template.js b/src/js/templates/avatarGroup.template.js index d2bc2174..30eb883b 100644 --- a/src/js/templates/avatarGroup.template.js +++ b/src/js/templates/avatarGroup.template.js @@ -3,7 +3,9 @@ import { avatarTemplate } from "/js/templates/avatar.template.js"; export function avatarGroupTemplate({ authors }) { if (authors.length === 0) { - return html`
`; + return html`
+
+
`; } if (authors.length === 1) { return avatarTemplate({ author: authors[0], clickAction: "none" }); diff --git a/src/js/templates/footer.template.js b/src/js/templates/footer.template.js index 25f58aac..fff673db 100644 --- a/src/js/templates/footer.template.js +++ b/src/js/templates/footer.template.js @@ -83,7 +83,7 @@ export function footerTemplate({ template: () => html`${currentUser ? avatarTemplate({ author: currentUser, clickAction: "none" }) - : html`
`}`, + : html`
`}`, }, ]; diff --git a/src/js/views/chatDetail.view.js b/src/js/views/chatDetail.view.js index 33af1e6a..714e23a9 100644 --- a/src/js/views/chatDetail.view.js +++ b/src/js/views/chatDetail.view.js @@ -1297,7 +1297,6 @@ class ChatDetailView extends View { const reversedMessages = messages.toReversed(); const messageGroups = groupMessages(reversedMessages, currentUserDid); const days = groupMessageGroupsByDay(messageGroups); - // const message return html` { diff --git a/tests/unit/specs/templates/avatarGroup.template.test.js b/tests/unit/specs/templates/avatarGroup.template.test.js new file mode 100644 index 00000000..75cf66ed --- /dev/null +++ b/tests/unit/specs/templates/avatarGroup.template.test.js @@ -0,0 +1,43 @@ +import { describe, it } from "node:test"; +import assert from "node:assert/strict"; +import { avatarGroupTemplate } from "/js/templates/avatarGroup.template.js"; +import { render } from "/js/lib/lit-html.js"; +import { createProfile } from "../../../shared/factories.js"; + +describe("avatarGroupTemplate", () => { + function renderTemplate(authors) { + const container = document.createElement("div"); + render(avatarGroupTemplate({ authors }), container); + return container; + } + + function makeAuthors(count) { + return Array.from({ length: count }, (_unused, index) => + createProfile({ + did: `did:plc:member${index}`, + handle: `member${index}.bsky.social`, + displayName: `Member ${index}`, + }), + ); + } + + it("should render a placeholder inside the group wrapper when there are no authors", () => { + const container = renderTemplate([]); + const group = container.querySelector(".avatar-group"); + assert(group !== null); + assert(group.querySelector(".avatar-placeholder") !== null); + }); + + it("should render a single avatar without the group wrapper", () => { + const container = renderTemplate(makeAuthors(1)); + assert(container.querySelector(".avatar-group") === null); + assert(container.querySelector("[data-testid='avatar']") !== null); + }); + + it("should stack at most four avatars", () => { + const container = renderTemplate(makeAuthors(6)); + const group = container.querySelector("[data-testid='avatar-group']"); + assert(group.classList.contains("avatar-group-4")); + assert.equal(group.querySelectorAll(".avatar-group-item").length, 4); + }); +});