How do i have my comments stop indenting after a certain amount of comments?

OK so im extremely new to programming and im making my own blog website to teach myself as I go. I havent been usuing any tutorials and have basically hack and slashed my way to a working website somehow.

Now my problem is that I want my comment section to work in the same way it works on reddit where the comments continue to indent until about the 4th or 5th comment and then they basically stay at the same level. The main issue is that my code infininetly indents with each comment replying to another comment. At first i wanted this, but for readablity i cant have the page going to the right forever.

However with all my attempts i have either broken the code or have made worse versions of what I already have and I’m extremely stumped and dont know what to do since i am self taught. Be aware that my code is really messy and probably not ideal.

I will offer below two code snippets that are relevant to the problem from the css and the EJS file:

<h2>Comments</h2>
  <% function displayComments(comments, depth) { %>
    <ul class="<%= depth >= 5 ? 'comment-level-max' : 'comment-level-' + depth %>">
      <% comments.forEach(comment => { %>
        <li>
          <div>
            <p><%- comment.content %></p>     
            <p>By <%= comment.author ? comment.author.username : 'Anonymous' %></p>
            <% if (user && comment.author && user._id.toString() === comment.author._id.toString()) { %>
              <form action="/post/<%= post._id %>/comment/<%= comment._id %>/edit" method="GET" style="display: inline;">
                <button type="submit" class="edit-button">Edit</button>
              </form>
              <form action="/post/<%= post._id %>/comment/<%= comment._id %>/delete" method="POST" style="display: inline;">
                <button type="submit">Delete</button>
              </form>
            <% } %>
            <% if (user) { %>
              <form onsubmit="return false;" style="display: inline;">
                <button type="button" onclick="toggleReplyForm('<%= comment._id %>')">Reply</button>
              </form>
            <% } %>
          </div>
          <% if (comment.replies && comment.replies.length > 0) { %>
            <%= displayComments(comment.replies, depth + 1) %>
          <% } %>
          <div class="reply-form" id="reply-form-<%= comment._id %>" style="display: none;">
            <h3>Reply to this comment</h3>
            <form action="/post/<%= post._id %>/comment/<%= comment._id %>/add-reply" method="POST">
              <textarea id="reply-content" name="content" required></textarea>
              <br>
              <button type="submit">Add Reply</button>
            </form>
          </div>
        </li>
      <% }); %>
    </ul>
  <% } %>
  <% if (post.comments.length > 0) { %>
    <%= displayComments(post.comments, 0) %>
  <% } else { %>
    <p>No comments yet.</p>
  <% } %>
  <% if (user) { %>
    <h2>Add Comment</h2>
    <form action="/post/<%= post._id %>/add-comment" method="POST">
      <br>
      <textarea id="comment-content" name="content" required></textarea>
      <br>
      <button type="submit">Add Comment</button>
    </form>
  <% } else { %>
    <p>Please <a href="/login">log in</a> to add a comment.</p>
  <% } %>

and here is the css file:

  /* Comment Indentation Styles */
.comment-level-0 { margin-left: 0; }
.comment-level-1 { margin-left: 20px; }
.comment-level-2 { margin-left: 40px; }
.comment-level-3 { margin-left: 60px; }
.comment-level-4 { margin-left: 80px; }
.comment-level-max { margin-left: 80px; }

Ive tried diffrent things in my ejs file that either made it worse or better, the above is my best attempt, however, i have tried something else in my CSS file where i made the comment-level-max 0:

  /* Comment Indentation Styles */
.comment-level-0 { margin-left: 0; }
.comment-level-1 { margin-left: 20px; }
.comment-level-2 { margin-left: 40px; }
.comment-level-3 { margin-left: 60px; }
.comment-level-4 { margin-left: 80px; }
.comment-level-max { margin-left: 0; }

Here are the outputs on the actual website:
without the javascript changes
with the final changes (making comment-level-max 0)

How do I import values with HTML? [closed]

I want to set up a config file with a list of links, and I want to use HTML and JavaScript to get a link for an image from that config file.

But when i use fetch i get a CORS error, is there a way to import values with only HTML and JavaScript, without using a local server.

I just want to get values from a local file .

formsubmit não funciona? [closed]

Estou usando o formsubmit.co para disparo de formulários, porem os email não estão chegando, nem mesmo de validação, ano passado estava funcionando, esse ano parou!

refiz o formulario, mas o email continua não chegando nem mesmo o de validação

How to get a text change color when it overlaps an image? [duplicate]

How can I achieve this effect through CSS. I have seen too many things but nothing works. Through clip-path, through mix-blend-mode, through background-blend-mode. I am using Next.JS.

I have tried everything. Mix-blend-mode just does not work in the project. Also, I saw some SVG trick to do this, but I am looking for an easy and straight forward way. Do you guys have any solution for this. I do not know how this guy did this and I also know this effect is popular in many portfolios. Thanks in Advance!!!

React Native schedulePushNotification

I have this code to schedule a notification using expo notification

export async function schedulePushNotification( rotina, horas, minutos, dias ) {
const notifId = await Notifications.scheduleNotificationAsync({
  content: {
    title: "Rotina agendada",
    subtitle: "Mensagem de Rotinagem",
    body: `Não se esqueça, você definiu ${rotina} as ${horas}:${minutos}`,
    vibrate: true | 1000,
    priority: AndroidNotificationPriority.HIGH,
    // sound: 'default',
  },
  trigger: {
    hour: horas,
    minute: minutos,
    repeats: true,
  },
});
return notifId;

}

Now i have a list with de days, dias = [1, 2, 4, 7]

I want to set a notification in this especific days, the weekday parameter is a number in range from 1 to 7, 1 is sunday, 2 is monday…

I want if possible just one idNotification to this days, but if impossible i want a list of idNotification.

I tried but I couldn’t

I’ve tried to pass a list in the weekDay parameter, but do not accept, and i’ve tried a list of idNotification, but i receive a dictionary with random letters

Why is linking my website to the Stripe dashboard not working? [closed]

I am getting html button error as shown in image & also in cart.js


What can i do for that

const payBtn = document.querySelector('.btn-buy');

payBtn.addEventListener("click", () => {
    fetch("/stripe-checkout", {
        method: "post",
        headers: new Headers({ "Content-Type": "application/json" }),
        body: JSON.stringify({
            items: JSON.parse(localStorage.getItem("cartItems")),
        }),
    })
    .then((res) => res.json())
    .then((url) => {
        location.href = url;
    })
    .catch((err) => console.log(err));
});

is there any error in this, should i have to create somepage for stripe-checkout

Unable to fix the logic in the slider

I’ve create a slider which works with dynamic data. What I’m trying to achieve is when I click on the slides it should select that slide and the rest should rotate in order in the container. So I was able to achieve this only with the button but I’m having problem having the onclick functionality on the slides.

const slideContainer = document.querySelector('.slide');
const nextBtn = document.querySelector('.next');
const prevBtn = document.querySelector('.prev');
fetch('https://restcountries.com/v3.1/all')
  .then(response => response.json())
  .then(data => {
    // Create HTML elements based on the fetched data

    data.forEach(country => {
      const item = document.createElement('div');
      item.classList.add('item');

      // Customize the content based on your data structure
      item.innerHTML = `
          <div class="item-wrapper">
              <img src="${country.flags.svg}" alt="${country.name.common}">
              <div class="content">
                  <div class="sub-name">${country.name.common}</div>
                  <div class="name">${country.region}</div>
                  <button>See More</button>
                  <div class="des">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ab, eum!</div>
                  <div class="icon-wrapper">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="svg-icons">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z" />
                      </svg>
                      <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="svg-icons">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z" />
                      </svg>
                      <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="svg-icons">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M7.217 10.907a2.25 2.25 0 1 0 0 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186 9.566-5.314m-9.566 7.5 9.566 5.314m0 0a2.25 2.25 0 1 0 3.935 2.186 2.25 2.25 0 0 0-3.935-2.186Zm0-12.814a2.25 2.25 0 1 0 3.933-2.185 2.25 2.25 0 0 0-3.933 2.185Z" />
                      </svg>

                </div>
                <button class="view-btn">
                    <span>ver pedra</span>
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" >
                        <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 19.5 15-15m0 0H8.25m11.25 0v11.25" />
                      </svg>
                      </button>
              </div>
              <p class="unfocus-names">${country.region}</p>
          </div>
                    `;

      // Append the item to the slide container
      slideContainer.appendChild(item);
    });
  })
  .catch(error => console.error('Error fetching data:', error));



nextBtn.addEventListener('click', function() {
  let items = document.querySelectorAll('.item');
  slideContainer.appendChild(items[0]);
});

prevBtn.addEventListener('click', function() {
  let items = document.querySelectorAll('.item');
  slideContainer.prepend(items[items.length - 1]);
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

@media screen and (max-width: 1300px) {
  body {
    font-size: 14px;
    box-sizing: border-box;
    width: 100vw;
    height: 100vh;
  }
  .slide,
  .prev,
  .next {
    display: none;
  }
  .swiper {
    position: relative;
    width: 100vw;
    height: 100vh;
    padding: 50px;
  }
  .swiper-slide {
    height: 100% !important;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    transition: box-shadow 0.3s ease-in-out;
    border-radius: 20px;
    padding: 30px;
    display: flex;
    flex-direction: column;
  }
  .icon-wrapper {
    margin-top: 20px;
    display: flex;
    gap: 18px;
  }
  .svg-icons {
    width: 24px;
  }
  .img-div {
    width: 100%;
    height: 250px;
  }
  .swiper-slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
  }
  .content {
    font-family: system-ui;
  }
  .navigation {
    position: absolute;
    z-index: 20;
    bottom: 60px;
    width: 100%;
    display: flex;
    justify-content: center;
    gap: 20px;
    padding-bottom: 3px;
  }
  .navigation>* {
    width: 20px;
    height: 20px;
    border: 1px solid black;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 100%;
  }
  .navigation svg {
    width: 13px;
  }
  .content .sub-name {
    text-transform: uppercase;
    font-weight: 600;
    color: #838282;
    margin-top: 10px;
  }
  .content .name {
    margin-top: 10px;
    font-weight: 700;
    font-size: 20px;
  }
  .content button {
    margin-top: 10px;
    padding: 5px 10px;
    border-radius: 20px;
    background-color: transparent;
    border: 1px solid #b1b0b0;
    color: #7d7d7d;
  }
  .content .des {
    margin-top: 10px;
    margin-bottom: 10px;
    font-size: 16px;
  }
  .view-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    text-transform: uppercase;
    width: 150px;
    height: 30px;
    border-radius: 0px !important;
  }
  .view-btn svg {
    width: 14px;
  }
}

@media screen and (min-width: 1300px) {
  body {
    background: #eaeaea;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: auto;
  }
  .container {
    transform: translate(-85%, -5%);
    width: 500px;
    height: 500px;
    background: #f5f5f5;
    margin-top: 20px;
    padding: 120px;
  }
  .container .slide .item {
    width: 100px;
    height: 100px;
    position: absolute;
    top: 50%;
    left: 80%;
    transform: translate(290%, -50%);
    border-radius: 20px;
    background-position: 50% 50%;
    border-radius: 0;
    background-size: cover;
    display: inline-block;
    transition: 0.5s;
    transform-style: preserve-3d;
  }
  .container .slide .item .item-wrapper {
    width: 100%;
    height: 100%;
    display: relative;
  }
  .container .slide .item img {
    width: 100%;
    height: 100%;
    position: relative;
    z-index: 2;
    object-fit: cover;
    object-position: center;
  }
  .slide .item:nth-child(1),
  .slide .item:nth-child(2) {
    top: 0;
    left: 0;
    transform: translate(0, 0);
    border-radius: 0;
    width: 100%;
    height: 100%;
  }
  .slide .item:nth-child(1) .item-wrapper p,
  .slide .item:nth-child(2) .item-wrapper p {
    display: none;
  }
  .slide .item .item-wrapper p {
    text-align: center;
  }
  .slide .item:nth-child(3) {
    left: 150%;
  }
  .slide .item:nth-child(4) {
    left: calc(150% + 120px);
  }
  .slide .item:nth-child(5) {
    left: calc(150% + 240px);
  }
  /* here n = 0, 1, 2, 3,... */
  .slide .item:nth-child(n + 6) {
    left: calc(150% + 360px);
    opacity: 0;
  }
  .item .content {
    transform: translateZ(-10px);
    position: absolute;
    top: 20%;
    right: 300px;
    width: 300px;
    text-align: left;
    color: black;
    transform: translate(0, -50%);
    font-family: system-ui;
    display: none;
    animation: animate 1s ease-in-out 1 forwards;
  }
  .slide .item:nth-child(2) .content {
    display: block;
  }
  .content .sub-name {
    font-size: 16px;
    font-weight: semibold;
    text-transform: uppercase;
  }
  .content .name {
    font-size: 40px;
    font-weight: bold;
  }
  .content .des {
    margin-top: 10px;
    margin-bottom: 20px;
    font-size: 22px;
  }
  .content button {
    padding: 5px 20px;
    border: none;
    cursor: pointer;
    border-radius: 50px;
    border: 1px solid rgb(216, 216, 216);
    color: #ababab;
    font-size: 12px;
    font-style: normal;
  }
  @keyframes animate {
    0% {
      opacity: 0;
      transform: translate(0, 0);
    }
    30% {
      opacity: 0;
      transform: translate(0, 0);
    }
    100% {
      opacity: 100;
      transform: translate(650px);
    }
  }
  .icon-wrapper {
    margin: 30px auto;
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .svg-icons {
    width: 28px;
  }
  .button {
    width: 100%;
    text-align: center;
    position: absolute;
    bottom: 20px;
  }
  .button button {
    width: 40px;
    height: 35px;
    border-radius: 8px;
    border: none;
    cursor: pointer;
    margin: 0 5px;
    border: 1px solid #000;
    transition: 0.3s;
  }
  .button button:hover {
    background: #ababab;
    color: #fff;
  }
  .view-btn {
    margin-top: 70px;
    border-color: black !important;
    color: black !important;
    width: 150px;
    height: 35px;
    border-radius: 0 !important;
    font-size: 14px !important;
    text-transform: uppercase;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .view-btn svg {
    width: 12px;
  }
  .swiper {
    display: none;
  }
  .prev-btn,
  .next-btn {
    display: none;
  }
}
<div class="container">

  <div class="slide">

  </div>

  <div class="button">
    <button class="prev"><i class="fa-solid fa-arrow-left"></i></button>
    <button class="next"><i class="fa-solid fa-arrow-right"></i></button>
  </div>

</div>

This is what I’m trying to achieve
Video

This is what I’ve achieved
Video

ES6 module and compatible with non-module js

I’m wondering if there are some ways of making non-module JS like:

// my-api.js
function MyAPI() {
   this.classVar = null
}

MyAPI.prototype.myFunction = function() {
  this.classVar = {something: 3}
}

Compatible with ES6 modules. I tried to put this code into my-api.js:

if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
  module.exports = MyAPI
}

But I get The requested module '/static/my-api.js' does not provide an export named 'MyAPI' when trying to import whether with import MyAPI from '<url-of-backend>/static/my-api.js or import { MyAPI } from <url-of-backend>/static/my-api.js

I stumbled upon https://stackoverflow.com/a/58615189/8204956 this response, but it requires another level of indirection.

I’m trying to make non-module JS compatible with es6 module in order to move to module smoothly in a large codebase.

Can I store a PromiseResult in a variable? (Vue3)

I’m trying to set a dynamic background image, which I get from unsplash API.
The image URL is inside my DynamicBG function, but I can’t use it as a template literal.

const DynamicBG = async (ConditionCode: number) => {
  try {
    const unsplashQuery = mapConditionToUnsplashKeyword(ConditionCode);
    const imageUrl = await fetchUnsplashImage(unsplashQuery);
    console.log('fetched url', imageUrl);
    return imageUrl;
  } catch (error) {
    console.error('Error fetching image:', error);
    return '';
  }
};

let fetchedUrl = imageUrl

<template>
    <div v-if="weatherData">
      <div :style="{ backgroundImage: `url(${fetchedUrl})` }"
        >
      </div>
    </div>
  </template>
  

When I console.log the imageUrl inside the function, it returns a image URL.
I want to use that URL as a dynamic background.

How using ‘as’ works under the hood in angular?

<div>
  @if (user.name as userName) {
    {{ userName }}
  }
</div>



<div>
 @if (user.name) {
   {{ user.name }}
 }
</div>

I am wondering what is the difference between this two approaches? just a syntax? or something else? For example when using as does it creates variable? What is happening under the hood?

Wrapping a custom API around a Promise [closed]

I am currently implementing feature flags in a PHP/JS project.
I already have a solution that pre-loads the list of defined flags. It makes use of fetch to access the PHP backend and load the list into a JS object (FeatureFlags.#cachedFlags). The class FeatureFlags has a function onCacheReady through which callbacks can be defined which are then executed after fetch is done with caching of the flags.

Here’s my problem: I don’t like this API. What I would prefer is probably something like FeatureFlags.ifFlagIsEnabled(flagname).then(...).else(...). So, essentially, ifFlagIsEnabled should return something like a Promise with two functions then and else that take a callback. Except for the first call (or possibly after cache invalidation), this should perform a (sync) lookup on the cache, but with a unified API for async (remote) and sync (local) lookups.

Addressing JSON data in supabase JS client

I have a column guests which contains json data of the schema first_name, last_name. Each row can contain multiple guests.

[{"last_name":"One","first_name":"Guest"},
 {"last_name":"Two","first_name":"Guest"}]

I’m trying to address the data inside this object. In the supabase/postgres console the following statement gives me results as intended:

Select guests
from bookings
where ((guests -> 0 ->> 'first_name') = 'Guest')

When querying the same in supabase JS it doesn’t return any output:

let query = supabase.from("get_booking")
                    .select()
                    .eq('guests -> 0 ->> first_name', 'Guest');

What am I missing here?

Also the statement to check if the json exists and is not empty doesn’t work:

.not('guests -> 0 ->> first_name','is',null)

I tried different approaches but it seems I am addressing the json object in a wrong way.

Python web scraping #document inside iframe (dynamically)

I need to extract the src-link of an iframe with python. But I have 2 problems:

  1. The iframe only appears after clicking on a button/link.
  2. The iframe has no src, but inside the iframe tags is a #document. Inside is another iframe with the src link

Problem 1:

This is the relevant HTML code snipped before clicking the button:

<div class="video-content" id="video">
 <div class="autosize-container">
    <a href="#stream" id="stream" title="xyz"><img src="/img/tem/image.png"></a>
  </div>
</div>

The button/link:

<a href="#video" data-mirror="1" data-host="1" title="xyz">xyz</a>

has these two events (on click):

function() {
  $.ajax("", {
    type: "POST",
    async: !1,
    data: {
      req: "1",
      pid: "57315",
      mirror: $(this).data("mirror"),
      host: $(this).data("host"),
      rel: $("#rel option:selected").attr("data")
    },
    success: function(e) {
      $(".autosize-container").html(e)
    }
  })
}

and

function(b) {
  return "undefined" != typeof n && n.event.triggered !== b.type ? n.event.dispatch.apply(a, arguments) : void 0
}

This is the same HTML code snipped after clicking the button:

<div class="video-content" id="video">
<div class="autosize-container">

    <form id="moodleform" target="iframe" method="post" action="">
      <input type="hidden" name="req" value="2">
      <input type="hidden" name="pid" value="57315">
      <input type="hidden" name="mirror" value="1">
      <input type="hidden" name="host" value="1">
      <input type="hidden" name="rel" value="71580,0">
    </form>
    <iframe name="iframe" scrolling="no" frameborder="0" width="100%" height="480px" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" style="background-color:#eee"></iframe>
    <script>
      document.getElementById('moodleform').submit();
    </script>


  </div>
</div>

(The ajax_data values can be found in the html code before clicking any button. So I used them to emit the ajax:)

With my current python code, I might have worked around the first problem:

import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
ajax_url = "https://website.com"

ajax_data = {
    "req": "1",
    "pid": "57316",
    "mirror": "1",
    "host": "1",
    "rel": "71584,0"
}
response = requests.post(ajax_url, data=ajax_data, headers=headers)

print(response.text)

Output:

<form id="moodleform" target="iframe" method="post" action="">
      <input type="hidden" name="req" value="2" />
      <input type="hidden" name="pid" value="57316" />
      <input type="hidden" name="mirror" value="1" />
      <input type="hidden" name="host" value="1" />
      <input type="hidden" name="rel" value="71584,0" />
    </form>
    <iframe name="iframe" scrolling="no" frameborder="0" width="100%" height="480px" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" style="background-color:#eee"></iframe>
    <script>
      document.getElementById('moodleform').submit();
    </script>

Now I get the HTML code snipped that I would get after clicking the button on the website if I’m in the edit mode (see problem 2).

Problem 2:

But now the problem is that in the browser dev tools, inside the iframe is #document (<iframe […]>#document). After expanding it, there is more code and also an iframe with the src link.
However, if I click on “edit html” in the browser dev tools, this #document disappears. But if I expand it in the dev-tools, I can look inside and copy the link.
In my python code #document cannot be found either.

Now my question: How can I get the scr-link from the iframe within #document with python?

Inside the #document is more html and also the src-link i am searching for:

<iframe src="https://example.com" scrolling="no" frameborder="0" width="100%" height="480px" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true"></iframe>

#document inside iframe. Contains an iframe with the wanted src link:
Screenshot: #document inside iframe

document disappeared in edit mode (right click -> edit html):
Screenshot: #document disappeared in edit mode