Suggestion and Update Thread

Is there an official rule on bumping old threads on KF? I often research topics I'm interested in first so I don't make a thread on something that's already been discussed. When I find an existing discussion, I'll prefer to bump it with relevant information or questions. I just had a post deleted due to "necroposting" a thread, though I question the utility in that rule unless there's no information added. My post had two reactions and both were "Informative" so I feel like the post wasn't valueless.

Not bitching or anything, just curious. The mods have been excellent with my few requests here so not complaining. On mobile so forgive me if I'm overlooking rules out in the open.
Cross-posting from Articles & Happenings meta thread.

Here's an example of me bumping an older thread on an old incident for more information. My initial post had negative and late reactions and a poster bitched at me, but then apologized after I explained the rationale above. There were about 40 posts after with helpful information and useful discussion. Overall, I consider this optimal from the perspective of consolidating useful discussion on specific issues/incidents. It's beneficial for the forum and future searching, in my opinion. The rule is kind of illogical to me, tbh.

Anyway, as someone who only wants to make threads if they're useful and tries researching shit on here, I was curious if I'd missed some official ruling on "necroposting," I swear I searched prior to the bump above and it seemed okay to do if the posts were relevant, but maybe I'm overlooking shit. If it's subjective to the mods, I'm hoping for some sort of ruling to clarify so my future bumps don't get deleted. I often put a lot of effort into them.
 
Last edited:
Screenshot_20251103_104913.jpg
>link your twitter account to kiwifarms
On a hunch, I checked the account registration page before I hit post, and it seems to be an alternative to using an invitation (are we still under invite-only?). I guess that answers the question I'd already typed up, but it's still so bizarre to see as an option now. It's like the "share to LinkedIn" button, except not a joke. What kind of user would be dumb enough to use it, especially on an account that had already registered without it?
 
JavaScript:
    /**
        * Rearranges all forum alerts. It groups reaction alerts by post and integrates
        * all other alert types (quotes, etc.) into a single, chronologically sorted list
        * * without adding any extra borders or outlines.
    */

    function reorganizeAllAlertsClean() {
        // 1. Find the main list container.
        const listContainer = document.querySelector('ol.listPlain[data-xf-init="alerts-list"]');
        if (!listContainer) {
            console.error('Could not find the alerts list container element.');
            return;
        }
        const alerts = listContainer.querySelectorAll('li.alert');

        // 2. Create data structures to segregate and process alerts.
        const postsMap = new Map(); // For grouping reactions.
        const otherAlerts = []; // For storing non-reaction alerts.

        // 3. Loop through each alert and categorize it.
        alerts.forEach(alert => {
            const timeElement = alert.querySelector('time.u-dt');
            if (!timeElement) return; // Skip if it has no timestamp.

            const timestamp = parseInt(timeElement.dataset.timestamp, 10);

            // Check if it's a reaction alert.
            if (alert.querySelector('.alert-action--reaction')) {
                const postLinkElement = alert.querySelector('a.fauxBlockLink-blockLink');
                const userLinkElement = alert.querySelector('a.username');
                const reactionElement = alert.querySelector('span.reaction');
                const avatarElement = alert.querySelector('.contentRow-figure a.avatar');

                if (!postLinkElement || !userLinkElement || !reactionElement || !avatarElement) {
                    return; // Skip malformed reaction alerts.
                }

                const postHref = postLinkElement.getAttribute('href');

                // Get the thread title HTML.
                let threadNodes = [];
                let currentNode = postLinkElement.nextSibling;
                while (currentNode && currentNode !== reactionElement) {
                    threadNodes.push(currentNode);
                    currentNode = currentNode.nextSibling;
                }
                const threadHtml = threadNodes.map(node => node.nodeType === Node.TEXT_NODE ? node.textContent : node.outerHTML).join('');
                const cleanedThreadHtml = threadHtml.replace(/^\s*in the thread\s*/i, '').replace(/\s*with\s*$/, '');

                const reactionData = {
                    userHtml: userLinkElement.outerHTML,
                    avatarHtml: avatarElement.outerHTML,
                    reactionHtml: reactionElement.outerHTML,
                    timeHtml: timeElement.outerHTML,
                    timestamp: timestamp
                };

                // Add the reaction to its group in the map.
                if (postsMap.has(postHref)) {
                    const postGroup = postsMap.get(postHref);
                    postGroup.reactions.push(reactionData);
                    if (timestamp > postGroup.latestTimestamp) {
                        postGroup.latestTimestamp = timestamp;
                    }
                } else {
                    postsMap.set(postHref, {
                        postLink: postLinkElement.outerHTML,
                        threadHtml: cleanedThreadHtml,
                        reactions: [reactionData],
                        latestTimestamp: timestamp
                    });
                }
            } else {
                // It's a non-reaction alert (quote, profile post, etc.).
                otherAlerts.push({
                    type: 'single',
                    html: alert.outerHTML,
                    timestamp: timestamp
                });
            }
        });

        // 4. Prepare the grouped reactions for merging and sorting.
        const groupedReactions = Array.from(postsMap.values()).map(group => ({
            type: 'group',
            data: group,
            timestamp: group.latestTimestamp
        }));

        // 5. Combine grouped reactions with other alerts and sort the final list.
        const finalList = [...groupedReactions, ...otherAlerts]
            .sort((a, b) => b.timestamp - a.timestamp);

        // 6. Clear the original list and prepare it for new content.
        listContainer.innerHTML = '';
        listContainer.style.display = 'flex';
        listContainer.style.flexDirection = 'column';
        // Let the default CSS handle the spacing.

        // 7. Render the final sorted and grouped list.
        finalList.forEach(item => {
            if (item.type === 'group') {
                const postData = item.data;
                const groupContainer = document.createElement('li');

                // **CHANGE**: Use only the original classes for a native look. No inline styles.
                groupContainer.className = 'alert js-alert block-row block-row--separated grouped-alert';

                // Header for the group
                const headerHtml = `
                    <div class="contentRow" style="margin-bottom: 10px;">
                        <div class="contentRow-main contentRow-main--close" style="font-size: 1.1em;">
                            Reactions to ${postData.postLink} in the thread: ${postData.threadHtml}
                        </div>
                    </div>`;

                // Nested list for individual reactions
                const reactionsHtml = postData.reactions
                    .sort((a, b) => b.timestamp - a.timestamp) // Sort reactions within the group
                    .map(reaction => `
                        <li>
                            <div class="contentRow alert-row">
                                <div class="contentRow-figure">${reaction.avatarHtml}</div>
                                <div class="contentRow-main contentRow-main--close">
                                    ${reaction.userHtml} reacted with ${reaction.reactionHtml}
                                    <div class="contentRow-minor contentRow-minor--smaller">${reaction.timeHtml}</div>
                                </div>
                            </div>
                        </li>
                    `).join('');

                groupContainer.innerHTML = headerHtml + `<ol class="listPlain" style="padding-left: 50px; display: flex; flex-direction: column; gap: 8px;">${reactionsHtml}</ol>`;
                listContainer.appendChild(groupContainer);

            } else if (item.type === 'single') {
                // This is a non-reaction alert. Just append its original HTML.
                listContainer.insertAdjacentHTML('beforeend', item.html);
            }
        });
    }

    // Run the function to transform the page.
    reorganizeAllAlertsClean();

Run this code on your alerts page and it'll organize the page with the comment itself as the top-level hierarchy, such as:
1762939546446.png
 
It probably isn't a good idea due to potential ping spam but it would be nice if there was a system where if one enters "@" it shows a list of selectable members in the room similar to Telegram rather than having to look then copy and paste the username.
 
i do not like the stretched version, is there a way to change it into the slim version back pls?

1763195034391.png

edit: the solution is on the bottom left corner, which says "change width", maybe i just missclicked and didnt realize it.

1763234651820.png
 
Last edited:
Back
Top Bottom