Skip to content

nodebb-user-level customisation : popover element

Solved Customisation
15 3 3.5k 1
  • arf I can’t edit first post

    image.png

    image.png

    @DownPW You mean something like this ?

    65144ee9-4220-40f9-91e8-59efc7b31828-image.png

  • exactly my friend 🙂

    same things for second screenshot

  • exactly my friend 🙂

    same things for second screenshot

    @DownPW This will work - obviously, modify to suit your needs

    .popover {
        border-radius: 0.375rem;
    }
    .popover-body {
        background: var(--bs-body-navbar) !important;
        color: var(--bs-body-color) !important;
        border: 1px solid var(--bs-border-color);
        border-radius: 0 0 0.375rem 0.375rem;
    }
    .popover-header {
        background-color: var(--bs-alert-info-bg);
        color: var(--bs-alert-info-color);
    }
    .bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after, .bs-popover-top>.popover-arrow::after {
        border-top-color: var(--bs-border-color);
    }
    
  • exactly my friend 🙂

    same things for second screenshot

    @DownPW Try this

    .bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after, .bs-popover-end>.popover-arrow::after {
        border-right-color: var(--bs-border-color);
    }
    

    It’s important to remember that JS will determine the popup position and then add the arrow to suit. In this case, you’d need the below CSS to capture all of them

    .bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after, .bs-popover-top>.popover-arrow::after,{
        border-top-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after, .bs-popover-bottom>.popover-arrow::after,{
        border-bottom-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after, .bs-popover-end>.popover-arrow::after {
        border-left-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after, .bs-popover-end>.popover-arrow::after {
        border-right-color: var(--bs-border-color);
    }
    
    
  • phenomlabundefined phenomlab has marked this topic as solved on
  • better result than me but did you see this ?

    • The border radius is much larger than the original
    • On light theme, seems border was blurry

    image.png

    image.png

    • And in addition of blur, on dark/mid theme, we have 2 border with haven’t radius. Don’t know why

    image.png

    image.png

    –> I have the same behavior with my code when I have tested

  • better result than me but did you see this ?

    • The border radius is much larger than the original
    • On light theme, seems border was blurry

    image.png

    image.png

    • And in addition of blur, on dark/mid theme, we have 2 border with haven’t radius. Don’t know why

    image.png

    image.png

    –> I have the same behavior with my code when I have tested

    @DownPW Ooops…

    Sorry - I forgot a class - original answer modified

    .popover {
        border-radius: 0.375rem;
    }
    
  • hmmm nope it doesn’t change anything

    see it’s worse ^^

    204f26de-7ac7-4b29-bdb3-edcb9b65a73d-image.png
    205f5e14-f3f5-4cd0-b68b-e35b2d9052b4-image.png

    –> I have the same behavior with my code last night 😞

    EDIT:

    I f you play with border-radius you better seen the bug
    There missing something

  • hmmm nope it doesn’t change anything

    see it’s worse ^^

    204f26de-7ac7-4b29-bdb3-edcb9b65a73d-image.png
    205f5e14-f3f5-4cd0-b68b-e35b2d9052b4-image.png

    –> I have the same behavior with my code last night 😞

    EDIT:

    I f you play with border-radius you better seen the bug
    There missing something

    @DownPW This isn’t as simple as it looks, because bootstrap is using inset border radius

    Here’s a workaround

    .popover-body {
        background: var(--bs-body-bg) !important;
        color: var(--bs-body-color) !important;
        border: 1px solid var(--bs-border-color);
        border-radius: 0 0 0.375rem 0.375rem;
        margin: 0px;
    }
    .popover-header {
        background-color: var(--bs-alert-info-bg);
        color: var(--bs-alert-info-color);
        border-top-left-radius: 0.375rem;
        border-top-right-radius: 0.375rem;
        margin: 0px;
    }
    .bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after, .bs-popover-top>.popover-arrow::after,{
        border-top-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after, .bs-popover-bottom>.popover-arrow::after,{
        border-bottom-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after, .bs-popover-end>.popover-arrow::after {
        border-left-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after, .bs-popover-end>.popover-arrow::after {
        border-right-color: var(--bs-border-color);
    }
    

    Then, in the widgets section - /admin/extend/widgets select the account/profile.tpl widget, and add the below HTML

    <style>
    .popover-body {
        border-radius: 0.375rem;
    }
    </style>
    

    32d9fac7-67b1-4ea2-9aa5-37eba0ab776e-image.png

    Save the widget.

    This is the closest you can get unfortunately. It’s something of a hack, but a necessary evil.

  • phenomlabundefined phenomlab has marked this topic as solved on
  • @DownPW This isn’t as simple as it looks, because bootstrap is using inset border radius

    Here’s a workaround

    .popover-body {
        background: var(--bs-body-bg) !important;
        color: var(--bs-body-color) !important;
        border: 1px solid var(--bs-border-color);
        border-radius: 0 0 0.375rem 0.375rem;
        margin: 0px;
    }
    .popover-header {
        background-color: var(--bs-alert-info-bg);
        color: var(--bs-alert-info-color);
        border-top-left-radius: 0.375rem;
        border-top-right-radius: 0.375rem;
        margin: 0px;
    }
    .bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after, .bs-popover-top>.popover-arrow::after,{
        border-top-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after, .bs-popover-bottom>.popover-arrow::after,{
        border-bottom-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after, .bs-popover-end>.popover-arrow::after {
        border-left-color: var(--bs-border-color);
    }
    .bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after, .bs-popover-end>.popover-arrow::after {
        border-right-color: var(--bs-border-color);
    }
    

    Then, in the widgets section - /admin/extend/widgets select the account/profile.tpl widget, and add the below HTML

    <style>
    .popover-body {
        border-radius: 0.375rem;
    }
    </style>
    

    32d9fac7-67b1-4ea2-9aa5-37eba0ab776e-image.png

    Save the widget.

    This is the closest you can get unfortunately. It’s something of a hack, but a necessary evil.

    @phenomlab said in nodebb-user-level customisation : popover element:

    @DownPW This isn’t as simple as it looks, because bootstrap is using inset border radius

    yes, that’s what I noticed !! 😊
    Thank you baris ^^

    Hence the need to open this topic

    This hack seems to work, thanks again. If there is anything I will come back 🙂

  • @phenomlab said in nodebb-user-level customisation : popover element:

    @DownPW This isn’t as simple as it looks, because bootstrap is using inset border radius

    yes, that’s what I noticed !! 😊
    Thank you baris ^^

    Hence the need to open this topic

    This hack seems to work, thanks again. If there is anything I will come back 🙂

    @DownPW said in nodebb-user-level customisation : popover element:

    Thank you baris ^^

    Not his fault really - it’s the BS library behaviour by default.

  • No no, I said that in the sense that he told me it was simple ^^
    I was able to see that this was not the case by targeting the elements he had advised me.

  • phenomlabundefined phenomlab referenced this topic on

Did this solution help you?
Did you find the suggested solution useful? Support 💗 Sudonix with a coffee
If your organisation needs deeper expertise around infrastructure, security, or technology leadership, learn more about Phenomlab Ltd. Many of the deeper technical guides behind Sudonix are published there.

Related Topics
  • Forum customisation

    Customisation nodebb forum customised
    11
    2
    6 Votes
    11 Posts
    2k Views
    Thank you Mark, the changes look fantastic!!
  • Sudonix Blog

    General blog new topic plugin
    8
    3 Votes
    8 Posts
    2k Views
    Yes that is very awesome and I really like that idea! Great job with thinking that up!!
  • navigation menu panel on mobile

    Solved Customisation nodebb css
    8
    1
    7 Votes
    8 Posts
    2k Views
    @crazycells hmm. That’s odd. I haven’t made any changes from recollection but I could be wrong. I’ll need to check. EDIT - very strange. I honestly don’t recall adding the below CSS block to alter the bottom bar, but you’re right… .bottombar-nav { padding: 0px !important; } I’ve removed this so it reflects stock Harmony.
  • Adding a banner to chat messages

    Tips banner custom
    38
    1
    18 Votes
    38 Posts
    10k Views
    @phenomlab said: @DownPW Possible, yes, but not using the existing code. It would need to be changed to test for multiple entries based on two distinct widget areas. This should work (it’s already applied on your DEV server) function chatBanner() { var roomName = $("h5[component='chat/header/title']").text().trim(); var roomNameWidget = $('[id*="chat-modal"] .btn-ghost.btn-sm.dropdown-toggle').text().trim(); var bannerContent; if (roomName === "General" || roomNameWidget === "General") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 1. </div>'; } else if (roomName === "Support" || roomNameWidget === "Support") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 2.</div>'; } else if (roomName === "Info" || roomNameWidget === "Info") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 3</div>'; } else if (roomName === "xxxxxx" || roomNameWidget === "xxxxxx") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 4</div>'; } else if (roomName === "xxxxxx" || roomNameWidget === "xxxxxx") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 5</div>'; } else if (roomName === "xxxxxx" || roomNameWidget === "xxxxxx") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 6</div>'; } else { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Ce canal est une discussion privée. </div>'; } var chatMessagesContainer = $('[component="chat/system-message"]:last-of-type'); //var existingMessages = $('[component="chat/message"]'); var existingMessages = $('[component="chat/composer"]'); if (existingMessages.length === 0) { // If there are no messages, append the banner to the messages container chatMessagesContainer.first().after(bannerContent); } else { // If there are messages, add the banner after the last message //existingMessages.last().after(bannerContent); existingMessages.before(bannerContent); } } Here, we are using || which is essentially an OR operator. Because we cannot know the chat room ID in advance, it is necessary to use a wildcard to track it [id*="chat-modal"] .btn-ghost.btn-sm.dropdown-toggle I see bugs with this code and chat box widget I use on my categories page What was happening NodeBB allows multiple chat windows to be open simultaneously , the widget and the full/modal-page DM view. Both exist in the DOM at the same time. The original code used global jQuery selectors like $(‘[component=“chat/composer”]’) which scanned the entire page and found elements from both chat windows at once. When you opened “XY” caht while “XXY” was still open in the widget, the selectors would pick up the wrong room name or inject the banner into the wrong window. The key discovery was that the action:chat.loaded event passes the modal DOM element directly as data. By wrapping it in $(data) and using $modal.find(…) for every selector, all queries are scoped exclusively to the correct modal, making it impossible for two open chat windows to interfere with each other. FIX code (to adapt to your rooms) : function chatBanner(modalElement) { var $modal = $(modalElement); $modal.find('#chatbanner').remove(); var roomName = $modal.find('[component="chat/room/name"]').text().trim(); if (!roomName) { var placeholder = $modal.find('[component="chat/input"]').attr('placeholder') || ''; roomName = placeholder.replace(/^Message #?/, '').trim(); } var bannerContent; if (roomName === "General") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Chat message banner</div>'; } else if (roomName === "xxxxxxxxxx") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Chat message banner</div>'; } else if (roomName === "xxxxxxxxxx") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Chat message banner</div>'; } else if (roomName === "xxxxxxxxxx") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Chat message banner</div>'; } else if (roomName === "xxxxxxxxxx") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Chat message banner</div>'; } else if (roomName === "Les geeks de l'espace") { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Chat message banner</div>'; } else { bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Chat message banner</div>'; } $modal.find('[component="chat/composer"]').first().before(bannerContent); } $(window).on('action:chat.loaded', function(ev, data) { chatBanner(data); });
  • hover link effect

    Solved Customisation css link hover
    18
    1
    6 Votes
    18 Posts
    4k Views
    @DownPW Looking at the underlying code, class start is being added on hover by jQuery in this function document.querySelectorAll(".button-gradient, .button-transparent").forEach((button) => { const style = getComputedStyle(button); const lines = document.createElement("div"); lines.classList.add("lines"); const groupTop = document.createElement("div"); const groupBottom = document.createElement("div"); const svg = createSVG( button.offsetWidth, button.offsetHeight, parseInt(style.borderRadius, 10) ); groupTop.appendChild(svg); groupTop.appendChild(svg.cloneNode(true)); groupTop.appendChild(svg.cloneNode(true)); groupTop.appendChild(svg.cloneNode(true)); groupBottom.appendChild(svg.cloneNode(true)); groupBottom.appendChild(svg.cloneNode(true)); groupBottom.appendChild(svg.cloneNode(true)); groupBottom.appendChild(svg.cloneNode(true)); lines.appendChild(groupTop); lines.appendChild(groupBottom); button.appendChild(lines); button.addEventListener("pointerenter", () => { button.classList.add("start"); }); svg.addEventListener("animationend", () => { button.classList.remove("start"); }); }); }) The CSS for start is below .button-gradient.start .lines svg, .button-transparent.start .lines svg { animation: stroke 0.3s linear; } And this is the corresponding keyframe @keyframes stroke { 30%, 55% { opacity: 1; } 100% { stroke-dashoffset: 5; opacity: 0; } } It’s using both CSS and SVG, so might not be a simple affair to replicate without the SVG files.
  • 5 Votes
    9 Posts
    2k Views
    is there any way to see whose reputation is changed by this plugin?
  • NodeBB Footer

    Solved Customisation footer nodebb
    10
    1 Votes
    10 Posts
    3k Views
    @phenomlab said in NodeBB Footer: @jac and you. Hope all is well and you recover quickly Thanks pal
  • NodeBB customisation

    Locked Customisation
    332
    27 Votes
    332 Posts
    170k Views
    @jac Given your departure away from your previous project, I’m going to close this thread…