How would you go about coding a TV guide? [closed]

How would you go about coding a TV guide?
Preferably with HTML, CSS and Javascript…

But all suggestions are welcome!

I expect the code to have a timestamp, items in boxes for what is currently playing, and a cursor that passes with the current time

If you had something different, its okay to contribute too!

Finding the optimal division of an array

I’m trying to write a function in appsscript to take a large array of values that I’d like to split as evenly as possible into subarrays of values (a array of arrays). Each subarray would optimally be 15 values long. The maximum number of values in each array would be 20 and the minimum number of values would be 10.

If the value of the array were 21, you’d have a a array of 10 and a array of 11. 22 would be two arrays of 11. And so on until you got to 36 (18, 18). At 37 you’d break out into (13, 13, 14). 38 would be (13, 14, 14)

My initial thought was to take the starting number and find the closest multiple of 15. So if the number is 47, then 45 is the closest multiple. If the closest multiple is less than the starting number, use the factor of that multiple, then calculate the difference between the starting number and the multiple. Distribute that number one per array until the difference sum is reached. So 45 is a factor of 3. That means 3 arrays of 15 and then the difference between 47 and 45 is 2. So add one to the first array and one to the second to get 16, 16, 15.

If the closer multiple is higher than the starting number, use the factor of the higher multiple, then calculate the difference between the starting number and the higher multiple, subtract one from each subarray until that difference is exhausted. So for 43, the higher multiple is a 45 (15, 15, 15) The difference between the higher number is 2, so subtract 1 from the first two arrays and get (14, 14, 15).

So far I have this, which will tell me how many values each array should have. But it fails on numbers 21 and 22. I need something that will take the number of values in each array, X or Y, and populate X or Y values into that array. The final output being an array of arrays that, when read left to right, would maintain the same order as the original array, albeit subdivided into arrays.

function splitList(values) {
    const total = values.length;
    const optimalSize = 15;
    const minSize = 10;
    const maxSize = 20;

    if (total <= maxSize) {
        return [values];
    }

    let numSublists = Math.round(total / optimalSize);
    let sublistSize = Math.floor(total / numSublists);
    let remainder = total % numSublists;

    let result = [];
    let startIndex = 0;

    for (let i = 0; i < numSublists; i++) {
        let currentSize = sublistSize + (remainder > 0 ? 1 : 0);
        result.push(values.slice(startIndex, startIndex + currentSize));
        startIndex += currentSize;
        remainder--;
    }

    return result;
}

// Example usage:
const values = Array.from({ length: 43 }, (_, i) => i + 1);
const sublists = splitList(values);
console.log(sublists);

Route path changing but component not rendering as expected

I’ve setup basic app navigation using a Material UI drawer and appbar and all listitems in the drawer properly change routes and display the corresponding component(s) as expected using React Router.

enter image description here

App.js

function App() {
  const location = useLocation();

  function showComponentByPath(){
    let path = location.pathname;
  
    if (path === "/") {
      return <ProjectDashboard />
    }
  }

  return (
    <>
      <NavMenu />
      {showComponentByPath()}
      <Outlet />
    </>  
)}

export default App

Main.js

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<App />} errorElement={<ErrorPage />}>
      <Route path="projects/:id" element={<ProjectDetails />} />
      <Route path="tasks" element={<MyTasksView />} />
      <Route path="reviewtasks" element={<ReviewTasks />} />
      <Route path="myapplications" element={<MyApplications />} />
      <Route path="peerreviews" element={<PeerReviews />} />
      <Route path="reviewapplications" element={<ReviewApplication />} />
    </Route>
  ),
)

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <RouterProvider router={router} />
    </LocalizationProvider>
  </StrictMode>,
)

ProjectDetails.jsx

function ProjectDetails() {
  console.log("I'm the ProjectDetails component");

  <div>
    <h1>
      Project Details
    </h1>
  </div>
}

export default ProjectDetails

The issue comes in when I try using the tablecell as a link to a nested route (i.e. projects/1). When I do this, the tablecell link and route both work as expected but the contents of the component are not being displayed — despite the component being rendered as evident by a console.log being printed when the component is mounted.

enter image description here

TableCell Link Attempts

Below are the two ways that I’ve tried linking the tablecell to the desired path (i.e. “projects/:id). These both update the route as expected but the component’s contents are not displayed so I wanted to include these to provide more context.

I’m also not using these both at the same time but just wanted to show the approaches I’ve taken.

<TableCell component={Link} to={"projects/1"}>{row.project_name}</TableCell>
<TableCell><Link to="projects/1">{row.project_name}</Link></TableCell>

Questions that might be helpful for myself or others looking at this example:

  • Have I setup or configured something wrong with React Router?
  • Could there be a state/rendering issue with how I’m trying to display my component(s)?

I’ll provide as many screenshots as possible to help anyone else setting up React Router V6 here as well.

Dynamic Templates – Reporting

So, i am building a custom ERP-like application and it’s time to build the reports that the company needs.

In a technical aspect I work on Node.Js, Angular, MySQL stack.

The need is very straight forward, a user must select some search filters for each report and do the query. Then, he/she must be able to view the report and can export it (excel, pdf etc).

Currently, i have some HTML templates and with little JavaScript, I replace the placeholders with my actual content but i don’t like this solution.

What are your suggestions?

Creating boundaries for moving an image inside a squared view

I am building a crop component in React Native. I’ve already assembled some code (https://snack.expo.dev/@leurs247/cropper).

Explanation:
It’s goal is to crop the given image into a square, but the user can choose which part of the image to crop (and it’s also possible to scale the image). At the start, the scale is 1, so the image has it’s original size. The background of the square is pink, en when moving the images, the image should be bounded inside the square so no pink background is visible. This works. But when scaling > 1 (up to scale=3), the boundaries are not calculated correctly. When moving the image, it’s possible to move outside of the boundaries so the pink background becomes visible.

This is the complete code for the cropper component:

import React, {useMemo} from 'react';
import {View, useWindowDimensions} from 'react-native';
import {GestureDetector, Gesture} from 'react-native-gesture-handler';
import Animated, {useSharedValue, clamp} from 'react-native-reanimated';
import Slider from '@react-native-community/slider';

const Cropper = props => {
  const {width} = useWindowDimensions();

  const {ratio, scaledWidth, scaledHeight} = useMemo(() => {
    let ratio;
    let scaledWidth;
    let scaledHeight;

    if (props.width < props.height) {
      ratio = width / props.width;
      scaledWidth = width;
      scaledHeight = props.height * ratio;
    } else if (props.height < props.width) {
      ratio = width / props.height;
      scaledWidth = props.width * ratio;
      scaledHeight = width;
    } else {
      ratio = width / props.width;
      scaledWidth = width;
      scaledHeight = width;
    }

    return {ratio, scaledWidth, scaledHeight};
  }, [props.width, props.height, width]);

  const posX = useSharedValue(0);
  const posY = useSharedValue(0);
  const transX = useSharedValue(0);
  const transY = useSharedValue(0);
  const scaleT = useSharedValue(1);
  const maxLeft = useSharedValue(0);
  const maxRight = useSharedValue(0);
  const maxTop = useSharedValue(0);
  const maxBottom = useSharedValue(0);
  const x = useSharedValue(0);
  const y = useSharedValue(0);

  const pan = Gesture.Pan()
    .onStart(e => {})
    .onUpdate(e => {
      const totalWidth = scaledWidth * scaleT.value;
      const totalHeight = Math.round(scaledHeight * scaleT.value);

      maxLeft.value = -(totalWidth - width) * scaleT.value;
      maxRight.value = (totalWidth - width) * (scaleT.value - 1);
      maxTop.value = -((totalHeight - width) * scaleT.value);
      maxBottom.value = (totalHeight - width) * (scaleT.value - 1);

      posX.value = clamp(
        transX.value + e.translationX,
        maxLeft.value,
        maxRight.value,
      );

      posY.value = clamp(
        transY.value + e.translationY,
        maxTop.value,
        maxBottom.value,
      );
    })
    .onEnd(e => {
      transX.value = posX.value;
      transY.value = posY.value;
    });

  const composed = Gesture.Race(pan);

  return (
    <View style={{flex: 1}}>
      <View style={{width, height: width, overflow: 'hidden'}}>
        <GestureDetector gesture={composed}>
          <Animated.Image
            source={{uri: props.uri}}
            style={{
              transform: [
                {
                  translateX: posX,
                },
                {
                  translateY: posY,
                },
                {
                  scale: scaleT,
                },
              ],
              width: scaledWidth,
              height: scaledHeight,
            }}
          />
        </GestureDetector>
      </View>
      <Slider
        minimumValue={1}
        maximumValue={3}
        value={1}
        onValueChange={value => {
          scaleT.value = value;
        }}
      />
    </View>
  );
};

export default Cropper;

I think the main part for this to work correctly is with the maxLeft, maxRight, maxTop and maxBottom animated values.

Can anyone guide me in the right direction?

Angular 18+ Elements bundled as Web components

I have the following question about taking direction to build a web application separated into a micro-front-end app. For this purpose, I’m using Angular Elements. I’m reading the official documentation at https://angular.dev/guide/elements, and my question is:
How can I bundle (run) ng build and embed a script in my page that automatically bootstraps the app when the custom element is added to the DOM?
<popup-element message="alabala"></popup-element> – when I have this on my page, I want my micro app to start.
Note: I’m using the latest release, 18.2.x, and the experimental zone-less feature. The Zone.js is messing my router in the outer app, which is Aurelia 🙂
By running the example from the angular docs, I can not see it as a stand-alone working web component.

Avoid XLSX Sheetname Change when pasting data from Sheets with Google Apps Script

I have this Google Apps Script function to paste data into an XLSX file from my base sheet in Google Sheets. It works fine, but I have a problem. When the file.setContent() line is executed, the Excel file’s sheet is automatically renamed to match the XLSX file name, including the .xlsx extension (the sheet gets renamed to interop.xlsx).

I need the sheet name not to change, or at least be able to control that name, because I am using MSExcelParser, and this parser does not return data when the sheet name contains dots.

I need to achieve this to fully automate the workflow I’m working on. What can I do?

function overwriteXLSX(sheet, fileId) {

  var docSheet = sheet || SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Interoperabilidad');

  // Get Data Range
  var lastRow = docSheet.getLastRow();
  var lastColumn = docSheet.getLastColumn();
  
  var valuesRange = docSheet.getRange(1, 2, lastRow - 2, lastColumn - 1);
  var dataValues = valuesRange.getValues();
  
  // Clean Empty Rows
  valoresDatos = dataValues.filter(row => row.some(cell => cell !== ""));

  // Convert to TSV format (Tab-Separated Values)
  var tsvContent = dataValues.map(row => row.join("t")).join("n");

  // Generate Blob with TSV
  var blob = Utilities.newBlob(tsvContent, 'text/tab-separated-values', 'datos.tsv');
  
  // Get Google Drive XLSX File
  var file = DriveApp.getFileById(fileId);
  
  // Paste TSV in XLSX File
  file.setContent(blob.getDataAsString());
}

dgs

Broken Protomaps (pmtiles) rivers rendering, both leaflet and maplibregl

I’m trying to set up OpenStreetMap with a self-hosted Protomaps file served by Apache.

The same error occurs with Leaflet and MaplibreGL. maplibreGL is what I want to use in the app.

I tried removing all stylesheets from the page (except some sizing for the map container) to make sure our styles is not causing the problem, but the result is the same.

versions from package.json:

"maplibre-gl": "^4.7.1",
    "pmtiles": "^3.2.0",

The map shows, is navigable, but rivers and water bodies are rendered incorrectly, as if some parts of the SVG path was closed by a straight line.

I have the same bug with firefox and chrome. The way the rivers are broken changes with zoom level, but it is never correct.

enter image description here

enter image description here

The file /osm/my_area.pmtiles was downloaded using the pmtiles tool. The sample code is composed of various examples. It is 1.4GB so I can’t upload it here. pmtiles verify shows no errors.

DATE='20240922'
AREA=11.958618,48.520243,18.918457,51.120765
pmtiles extract https://build.protomaps.com/$DATE.pmtiles my_area.pmtiles --bbox=$AREA

How I render the map:

import { Protocol } from "pmtiles";
import maplibregl from "maplibre-gl";

function initMaps() {

        let protocol = new Protocol();
        maplibregl.addProtocol("pmtiles", protocol.tile);

        const mapOpts = {
            style: {
                version: 8,
                sources: {
                    selfhosted: {
                        type: "vector",
                        // url: "pmtiles://https://example.com/example.pmtiles",
                        url: "pmtiles:///osm/my_area.pmtiles", // http://fb.local
                    }
                },

                layers: [
                    {
                        id: "water",
                        source: "selfhosted",
                        "source-layer": "water",
                        type: "fill",
                        paint: {
                            "fill-color": "#80b1d3",
                        },
                    },
                    {
                        id: "buildings",
                        source: "selfhosted",
                        "source-layer": "buildings",
                        type: "fill",
                        paint: {
                            "fill-color": "#d9d9d9",
                        },
                    },
                    {
                        id: "roads",
                        source: "selfhosted",
                        "source-layer": "roads",
                        type: "line",
                        paint: {
                            "line-color": "#fc8d62",
                        },
                    },
                    {
                        id: "pois",
                        source: "selfhosted",
                        "source-layer": "pois",
                        type: "circle",
                        paint: {
                            "circle-color": "#ffffb3",
                        },
                    },
                ],
            },
            container: document.getElementsByClassName('Map')[0],
            center: [this.data.lng, this.data.lat], // starting position [lng, lat]
            zoom: this.data.zoom, // starting zoom
        };

        console.log(mapOpts);

        let map = new maplibregl.Map(mapOpts);

        map.showTileBoundaries = true;
}

window.open from a https to http, and from https to http

first of all, this is really important for my website, i need to open a specific http page

i want to know if its a good practice to use window.open to open a page with different protocol (like http -> https | https -> http)

it works in my computer, but i’m not sure if it works with other browsers and OS’s

ChatGPT told me that this is not allowed but i can’t see someone in the internet saying that this is not allowed

Shopify Polaris IndexTable

I have tabs in the index table, and there are icons beside them. I want to remove those. is it possiable ?

Trying using Javascript DOM but I’m not able to get elment.

Inspect the DOM: Use your browser’s developer tools (usually accessible by right-clicking on the element and selecting “Inspect”) to find out the HTML structure of the tabs and the icons. Look for classes or IDs that uniquely identify the icons.

Select the Icons: Use JavaScript to select the icons next to the tabs. This can be done using document.querySelectorAll().

Remove the Icons: Loop through the selected elements and remove them from the DOM using the remove() method.

React pagination queries

I am building pagination for React project. The pagination itself does work when I click on prev or next page buttons, but I’ve got 2 problems, which I can’t figure out.

  1. Browser button acts weird. I am at home page (page1) and click next page until I reach last page(page3). Now I open specific product page while at page 3 and when I click browser back button first time it correctly puts me back into page 3, but when I click again I expect to go back to page 2, but instead I am moved out of the website entirely and see some other website which I was browsing before.

I also get this warning in chrome dev tools:
Use of history.pushState in a trivial session history context, which maintains only one session history entry. It seems like this warning indicated the problem, but how to save multiple history records?

  1. If I manually change search query in browser from http://localhost:5173/?p=1 let’s say to http://localhost:5173/?p=3 nothing happens. I see that the page refreshes and I believe my new ?p=3 query is not persisted somehow so useEffect code does not run?

Code:

  let [currentPage, setCurrentPage] = useState(getCurrentPage());
  let [pagesCount, setPagesCount] = useState(0);
  let [itemsCount, setItemsCount] = useState(0);
  let [productData, UpdateProductData] = useState([]);
  const [searchParams, setSearchParams] = useSearchParams();

  //On init
  useEffect(() => {
    getCurrentPage();
    setSearchParams({ p: `${currentPage}` });
    calcPagesCount();
    getData();
  }, []);

  //Updates screen if query is changed by browser back button or manually changing query in url bar
  useEffect(() => {
    let CurrentPageFromQuery: number;
    CurrentPageFromQuery = Number(location.search.replace(/D/g, ""));
    setCurrentPage(CurrentPageFromQuery);
    saveCurrentPage();
    getData();
  }, [searchParams]);

  //Updates query if next/prev page buttons are clicked
  useEffect(() => {
    saveCurrentPage();
    getData();
    setSearchParams({ p: `${currentPage}` });
  }, [currentPage]);

  function prevPage() {
    if (currentPage !== 1) {
      getCurrentPage();
      setCurrentPage(currentPage - 1);
      saveCurrentPage();
    }
  }

  function nextPage() {
    if (currentPage !== pagesCount) {
      getCurrentPage();
      setCurrentPage(currentPage + 1);
      saveCurrentPage();
    }
  }

  function saveCurrentPage() {
    sessionStorage.setItem("current page", String(currentPage));
  }

  function getCurrentPage(): number {
    return Number(sessionStorage.getItem("current page") || 1);
  }

  async function calcPagesCount() {
    const api_url = `https://******&per_page=99`;
    const req = await fetch(api_url);
    const products = await req.json();
    setItemsCount(products.length);
    setPagesCount(Math.floor(products.length / 9));
  }

  async function getData() {
    const api_url = `https://******&per_page=9&page=${currentPage}`;
    const req = await fetch(api_url);
    const products = await req.json();
    UpdateProductData(products);
  }

React TreeView unselect parent if any child is unselected

Hello I am implementing a TreeView with React.

One of the requirements is to un-select the parent if any of the childs is un-selected. I am starting with React and I am not sure how to do this.

Please see my whole implementation here: https://playcode.io/2019412

In TreeContext.jsx the following function:

const toggleNode = (nodes, id, parent, expanded, checked) => {
  return nodes.map((node) => {
    // if parent is clicked
    if (node.id === id && node.children?.length > 0) {
      // Check or Un-checked all children
      const children = node.children;
      const newChildren = children.map((child) => {
        return { ...child, isChecked: checked };
      });
      return {
        ...node,
        isExpanded: expanded,
        isChecked: checked,
        children: newChildren,
      };
    }
    // if child is clicked
    if (node.id === id && node.children === null) {
      // Check individual node
      return { ...node, isExpanded: expanded, isChecked: checked };
    }
    if (node.id === parent.toString()) {
      const allChildrenChecked = node.children.every(
        (child) => child.isChecked
      );
    }
    if (node.children?.length > 0) {
      return {
        ...node,
        children: toggleNode(node.children, id, parent, expanded, checked),
      };
    }
    return node;
  });
};

Gets the job done.

However, how can I implement:

  1. Un-select parent checkbox if any of the children are Un-selected?
  2. Is there are an easier way to represent the object in data.js?

javascript can’t access private field or method error on event

I get the following error when I click:

Uncaught TypeError: can't access private field or method: object is not the right class
    #clickEventHandler index.js:67
    enable index.js:45

I don’t get any errors in my IDE and I don’t understand what might be wrong.

Relevant code:

InteractionsManager

class InteractionsManager {
    #putHandler
    #eventListener

    constructor(putCallback) {
        this.#putHandler = new PutHandler(putCallback)
        this.#eventListener = null
    }

    /**
     * starts listening to "click" event
     */
    enable() {
line 45:        this.#eventListener = document.body.addEventListener("click", this.#clickEventHandler)
    }

    /**
     * 
     * @param {MouseEvent} e 
     */
    #clickEventHandler(e) {
        const mousePos = getMousePos(e);

line 67:        this.#putHandler.putTHandler(mousePos)
    }
}

PutHandler

class PutHandler {
    putTHandler(mousePos) {
        
    }
}

Any idea what might be wrong?