[ home / rules / faq ] [ overboard / sfw / alt ] [ leftypol / siberia / hobby / tech / edu / games / anime / music / draw / AKM ] [ meta / roulette ] [ cytube / git ] [ GET / ref / marx / booru / zine ]

/tech/ - Technology

"Technology reveals the active relation of man to nature" - Karl Marx
Name
Options
Subject
Comment
Flag
File
Embed
Password (For file deletion.)

Join our Matrix Chat <=> IRC: #leftypol on Rizon


File: 1612129656526.gif (2.28 MB, 224x240, 1608608621350.gif)

 No.6724[Last 50 Posts]

This thread is only for feedback related to technical issues (bug reports, suggestions). Otherwise use /meta/.
Public Repo:
https://git.leftypol.org/leftypol/leftypol
If you have any grievances you can make a PR.

Mobile Support:
https://github.com/PietroCarrara/Clover/releases/latest
Thread For Mobile Feedback: >>>/tech/6316

Onion Link:
76i2c3hn55fcj5nut3tqlboqqbbh23zvphv7lefk3vftpx6wketlanyd.onion

Cytube:
https://tv.leftypol.org

Matrix rooms:
https://matrix.to/#/#leftypolPublic:matrix.org

We are currently working on improvements to the site, subject to the need of the tech team to sleep and go to their day jobs. If you need more immediate feedback please join the matrix room[s] and ask around. Feel free to leave comments, concerns, and suggestions about the tech side of the site here and we will try to get to it as soon as possible

Archived thread:
>>>/leftypol_archive/903

 No.6727

File: 1612133034865.png (153.68 KB, 681x698, 2021-01-31.png)

Plug this hole.

 No.6730

>>6727
There was an issue with the previous fix.
It had to be rolled back, unfortunately.
The issue has been fixed and a new version is in PR.

 No.6731

>>6730
Okay thanks for letting me know it's progressing. I see the PR was made Jan 30, how long do you think it will take for the given admin(s) to enable the fix?
I'm so nagging about this because the warning and Google in general gives me anxiety.

p.s. nonmakina is based af

 No.6733

>>6731
nonmakina = antonious

 No.6744

File: 1612183832574.png (8.25 KB, 461x81, Untitled2.png)

To fix the bug of div#thread_stats not staying at the bottom of the reply list when auto-reload.js adds new replies, replace
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/js/thread-stats.js#L18
.after('<div id="thread_stats"></div>');

To put the "Unique IPs" on the right with the thread stats dump the span style from the element
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/templates/post_thread.html#L103
and add a rule to style.css:

[code]
#uniqueip > span {
display: block;
float: right;
margin: 0em 1em;
}
[/code]

The result is attached. Until a backend fix the following can be added to Options -> User JS:

[code]
(() => {
$('.clear').after($('#thread_stats'))
$('#uniqueip > span').attr('style', 'display: block; float: right; margin: 0em 1em;')
})()
[/code]

Options -> User JS quick reply spoiler fix >>>/leftypol_archive/1801
Options -> User JS catalog links in div.boardlist >>>/leftypol_archive/1803

 No.6749

>>6748
lmao do itdemocratic_socialismDemocratic Socialism

 No.6752

>404
It's not multi_image.js, it's multi-image.js.

 No.6753

To fix individual post hiding in Options -> User JS:

[code]
(() => {
const pcid2tid = (board, pcid) => {
const n = document.querySelector ('[data-board="' + board + '"].thread > div#' + pcid)
return n == null ? null : n.parentNode.getAttribute ('id').replace ('thread_', '')
}
const merge = (have, posts) => {
let changed = false
for (p of posts) {
if (!have.some (e => e.post === p.post)) {
have.push (p)
changed = true
}
}
return changed
}
const fixids = () => {
let lspf = JSON.parse (localStorage.postFilter)
let changed = false
for (const [board, threads] of Object.entries (lspf.postFilter)) {
for (const [id, posts] of Object.entries (threads)) {
if (!id.startsWith ('pc')) { continue; }
const tid = pcid2tid (board, id)
if (tid == null) { continue; }
if (tid in threads) {
const have = threads [tid]
if (merge (have, posts)) { changed = true; }
} else {
threads [tid] = posts
changed = true
}
delete threads [id]
}
}
if (changed) {
lspf = JSON.stringify (lspf)
localStorage.postFilter = lspf
$(document).trigger('filter_page')
}
}
fixids ()
$(document).on('filter_page', fixids)

// post-filter.js
const removepost = function (boardId, threadId, postId) {
const list = JSON.parse (localStorage.postFilter)
const filter = list.postFilter

// thread already pruned
if (typeof filter[boardId] == 'undefined' || typeof filter[boardId][threadId] == 'undefined') return;

for (var i=0; i<filter[boardId][threadId].length; i++) {
if (filter[boardId][threadId][i].post == postId) {
filter[boardId][threadId].splice(i, 1);
break;
}
}

if ($.isEmptyObject(filter[boardId][threadId])) {
delete filter[boardId][threadId];
delete list.nextPurge[boardId][threadId];

if ($.isEmptyObject(filter[boardId])) {
delete filter[boardId];
delete list.nextPurge[boardId];
}
}

localStorage.postFilter = JSON.stringify (list)
}

Menu.onclick(function (e, $buffer) {
var ele = e.target.parentElement.parentElement;
var $ele = $(ele);
var threadId = $ele.parents('.thread').attr('id').replace('thread_', '');
var boardId = $ele.parent().data('board');
var postId = $ele.find('.post_no').not('[id]').text();

if ($ele.data('hidden')) {
$buffer.find('#filter-menu-unhide').click(function () {
removepost(boardId, threadId, postId)
$(document).trigger('filter_page')
})
}
})
})()
[/code]

The price is that the page is filtered twice, once with the wrong pcN IDs from post-filter.js, then with the correct thread IDs. The backend fix >>>/leftypol_archive/1822 doesn't have this double filtering.

Options -> User JS quick reply spoiler fix >>>/leftypol_archive/1801
Options -> User JS catalog links in div.boardlist >>>/leftypol_archive/1803
Options -> User JS thread stats and Unique IPs >>6744

 No.6755

File: 1612309139952.txt (3.73 KB, userjs.txt)

A combined Options -> User JS with the four >>6753 fixes.

 No.6756

What might it take to setup a leftypol PeerTube instance?

 No.6763

>>6748
Due to their aggressive attitude, I request the first 'message' line be replaced with the second 'message' line. This will lower the change of them recognizing we're fucking with them personally.ak-47AK-47

 No.6764

File: 1612359900997.png (49.98 KB, 877x363, 1.png)

EASILY SOLVABLE
1. please order "OPTIONS -> [THEME SELECTION]" in ABC order.

2. please create a fuggen suboption menu for it. Currently, it's picrel, which is autistic. (picrel)
At the very least add some kind of "select look" or sg like that, lmao.

3. Please fix "Gentoo" outlook the following way:
how come the fucking hovering over message box is fucking semi-transparent? I can't see shit, because of the transparency effect. PLZ figgs!

 No.6765

>>6764
$('#style-select > select').css ({float: "none"}).before ('Select theme: ')

 No.6769

>>6764
Sorted, labeled style selector:

[code]
(() => {
$('#style-select > select').before ('Select theme: ')
const selected = $('div.styles > a.selected').attr ('id').replace ('style-select-', '')
const stylesSelect = $('<select></select>').css ({float: "none"})

Array.from (document.querySelectorAll ('div.styles > a')).map (a => [a.innerText.replace (/^\[(.+)\]$/, '$1'), a.getAttribute ('id').replace ('style-select-', '')]).sort ((a, b) => {
const au = a [0].toUpperCase ()
const bu = b [0].toUpperCase ()
if (au < bu) { return -1; }
if (au > bu) { return 1; }
return 0
}).forEach (([name, id]) => {
const opt = $('<option></option>').html(name).val(id)
if (id === selected) { opt.attr('selected', true); }
stylesSelect.append(opt)
})

$('#style-select > select').detach ()
stylesSelect.change(function() {
$('#style-select-' + $(this).val()).click()
})
$('#style-select').append (stylesSelect)
})()
[/code]

 No.6770

File: 1612411260062.txt (4.67 KB, userjs.txt)

A combined Options -> User JS with the five >>6753 >>6769 fixes.

 No.6771

>>6748
Rewriting to make it unambiguous.

I literally cannot make it any easier, devs. It takes ten seconds to find the file and five seconds to copy and paste and save. It will save the janitors a ton of effort over the next few years.

Append this to instance-config.php (if you actually added the version above, remove it first!)
//———————————————

$config['filters'][] = array(
'condition' => array(
// basic filter for copypasta anorectal spam
'OP' => true,
'subject' => '/Address rampant anorectal violence/' //checks subject only
),
'action' => 'reject',
'message' => 'Due to increased spam from /pol/, you must copy and paste the opening line of The Communist Manifesto into the email field in order to post.<br><br>Email [email protected] if you are unable to post.'
);

$config['filters'][] = array(
'condition' => array(
// special filter for anorectal spam
'OP' => true,
'custom' => function($post) {
// known filename
if ($post['has_file'] && preg_match("/TAKE ACTION v/", $post['files'][0]['filename']) ||
(preg_match("/Blatantly injurious/", $post['body'])) ||
(preg_match("/ustice.*paste/", $post['body'])) ){
sleep(10); # add a delay :^)
return true; # perform the action below
}
return false;
}
),
'action' => 'reject',
'message' => 'Due to increased spam from /pol/, you must copy and paste the opening line of The Communist Manifesto into the email field in order to post.<br><br>Email [email protected] if you are unable to post.'
);

 No.6772

>>6756
Not a dev but:
>a decision to do so
>an hour or so to properly set up (unless it fucks up)
>occasional maintenance if users can upload
I think it would be cool but why do you want it? What benefit would a leftypol instance have that other socialist instances don't offer?

 No.6773

Backend version of sorted, labeled style selector. >>6769

 No.6796

In addition to image.html hardcoding the initial loop parameter to 1 >>>/leftypol_archive/1535 in the non-JS case, with JS on expand-video.js also loops by default ignoring the loop=[01] in the player.php href.
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/js/expand-video.js#L16
> var loop = true;
> loopControls[1].style.fontWeight = "bold";

In the JS case with expand-video.js the initial state can be switched to [play once] on all videos in a page with:

$('p.fileinfo > span').filter ((k, e) => e.innerText === '[play once]').each ((k, e) => e.click ())

Unfortunately the loopControls spans aren't tagged with a class.

 No.6798

File: 1612533367083.gif (772.08 KB, 228x170, ren-anxious.gif)

Is the leftypol_lainchan github maintainer okay? ~1 week has gone and they haven't updated for the fix to the Google leak.
>>6727
>>6730
https://github.com/towards-a-new-leftypol/leftypol_lainchan/pull/224

 No.6800


 No.6801

fix this already, pretty please

 No.6803

File: 1612568307155.png (76.05 KB, 444x216, Untitled.png)

>>6801
Your browser seems to be the one with the subpar handling of word-wrap:break-word, Képernyőkép dude. >>>/leftypol/69820 The break-word will not be removed, it's there for a reason. However what you can do is inspect that post, go up to div.body, locate the "div.post div.body" rules, uncheck word-wrap:break-word and post the resulting layout.

 No.6814

hiding individual posts doesn't seem to work, also, there's a lag when the hidden OPs show up in the catalog view like i can see it for half a second and then it disappears

 No.6816

Batch loop/once setting >>6796 for Options -> WebM, manual mode only for now.

Test thread: >>>/leftypol/32459

 No.6818

Batch loop/once setting >>6796 for Options -> WebM, with auto set on page load but not on new posts yet.

Test thread: >>>/leftypol/32459

 No.6819

Batch loop/once setting >>6796 >>>/leftypol_archive/1521 in Options -> WebM, with auto set on page load and on new posts. Test thread: >>>/leftypol/32459 The issue with new posts was that expand-video.js uses a MutationObserver instead of reacting to the 'new_post' event like everyone else, and the observer runs after the 'new_post' trigger.
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/js/expand-video.js#L230

Options -> User JS quick reply spoiler fix >>>/leftypol_archive/1801
Options -> User JS catalog links in div.boardlist >>>/leftypol_archive/1803
Options -> User JS thread stats and Unique IPs fix >>6744
Options -> User JS individual post hiding >>6753
Options -> User JS sorted, labeled style selector >>6769

 No.6820

File: 1612660369892.txt (6.91 KB, userjs.txt)

A combined Options -> User JS with the six >>6819 fixes.

 No.6824

>>6814
HELLLO. JANNIES. WHY CANT I HIDE INDIVIDUAL POSTS? ONLY THE OP OF THREADS WHICH IS GREAT BUT I WANT TO HIDE INDIVIDUAL POSTS IN THREADS

 No.6835

Go to top/bottom navlinks in the top bar for Options -> User JS:

[code]
(() => {
const makea = (href, title, html) => {
const a = document.createElement ("a")
a.setAttribute ('href', href)
a.setAttribute ('title', title)
a.innerHTML = html
return a
}
if (document.querySelectorAll ('div.post.op').length == 1) {
const span = document.createElement ("span")
span.setAttribute ('id', 'topbottom-boardlist-navlinks')
span.setAttribute ('style', 'float:right;')
span.appendChild (makea ('#top', 'Go to top', '&#x25B2;'))
span.appendChild (makea ('#bottom', 'Go to bottom', '&#x25BC;'))
document.querySelector ('div.boardlist').appendChild (span)
}
})()
[/code]

 No.6837

File: 1612796305571.txt (7.56 KB, userjs.txt)

A combined Options -> User JS with the seven >>6819 >>6835 fixes.

 No.6841

1. Spoiler and deleted thumbs work in the catalog after >>>/leftypol_archive/1446 #124, but generic thumbs fail with e.g. src="/tech/thumb/file".
- spoiler: https://leftypol.org/meta/catalog.html spoiler OP test
- deleted: https://leftypol.org/meta/catalog.html Posting doesn't work for me
- generic: https://leftypol.org/tech/catalog.html Kickstarter workers unionize
The reason is that generateRecentPosts doesn't have any 'file' thumb handling:
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/templates/themes/catalog/theme.php#L421
To add 'file' thumb handling, fix the fallback loop and add a missing 'else' branch:

[code]
if (isset($post['files']) && $post['files']) {
$files = json_decode($post['files']);

if (isset($files[0]) && $files[0]) {
$foundone = false;
foreach ($files as $file) {
if ($file->file != 'deleted') {
$post['file'] = $this->filepathForThumb($file->thumb, $file->file);
$foundone = true;
break;
}
}
if (!$foundone) {
$post['file'] = $this->filepathForThumb('deleted', null);
}
} else {
$post['file'] = $this->filepathForThumb('deleted', null);
}
} else {
$post['file'] = $this->filepathForThumb('deleted', null);
}
[/code]

Before or after generateRecentPosts:

[code]
private function filepathForThumb($thumb_or_special, $path_when_file) {
global $config;

if ($thumb_or_special === 'deleted') {
return $config['root'] . $config['image_deleted'];
} else if ($thumb_or_special === 'spoiler') {
return $config['root'] . $config['spoiler_image'];
} else if ($thumb_or_special === 'file') {
// see twig_extension_filter
$ext = mb_strtolower(mb_substr($path_when_file, mb_strrpos($path_when_file, '.') + 1));
$icons = $config['file_icons'];
// see templates/post/image.html
if (isset($icons[$ext])) {
return $config['root'] . sprintf($config['file_thumb'], $icons[$ext]);
} else {
return $config['root'] . sprintf($config['file_thumb'], $icons['default']);
}
} else {
return $config['uri_thumb'] . $thumb_or_special;
}
}
[/code]

2. There is what might be considered an UI bug, whereby the banner images cause a layout shift on nearly every page load. To fix it:
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/inc/config.php#L937
> // Banner dimensions are also optional. As the banner loads after the rest of the page, everything may be
> // shifted down a few pixels when it does. Making the banner a fixed size will prevent this.
> // $config['banner_width'] = 300;
> // $config['banner_height'] = 100;
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/inc/instance-config.php#L105

3. The "sticky bug in the overboard catalog view" #229 is caused by this line:
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/js/catalog.js#L11
> $('#Grid').mixItUp('sort', (value == "random" ? value : "sticky:desc " + value));
To fix it change it to:
> $('#Grid').mixItUp('sort', (((value "random") || (board_name "overboard")) ? value : "sticky:desc " + value));
and update the test if the overboard ever moves from /overboard/.

4. For future reference, should a similar issue come up again, the clone_wrapped_with_exist_check fix to #225
https://github.com/towards-a-new-leftypol/leftypol_lainchan/commit/43a6a67844e2b806945e67cd34c593009f54c460
is almost the same as the @ error suppression from
>>>/leftypol_archive/1839 + >>>/leftypol/63272
and treats the symptoms. The explanation of the cause and of a few other problems with mod_move is still available in the archive.

+ catalog post form for non-JS users >>>/leftypol_archive/1833
+ thread stats and unique IPs fix >>6744
+ sorted, labeled style selector >>6773
in issues but not resolved yet:
+ track order #63 webm error 2 >>>/leftypol_archive/1337 [in PR]
+ arabic characters #125 >>>/leftypol_archive/1517
+ original file name downloads for non-JS users #128 >>>/leftypol_archive/1499
+ txt thumbnails #129 >>>/leftypol_archive/1593 >>>/leftypol_archive/1673
+ reply limit nobump markers in index and thread view #147 >>>/leftypol_archive/1775
+ UTF-8 troubles #193 >>>/leftypol_archive/1738 >>>/leftypol_archive/1744
+ posts below the line and related #207 >>>/leftypol_archive/1759
+ quick reply spoiler #213 >>>/leftypol_archive/1801
+ individual post hiding #215 >>>/leftypol_archive/1822
+ catalog links in div.boardlist #216 >>>/leftypol_archive/1807
+ zombie threads in catalog #219 >>>/leftypol_archive/1691
+ post quote ending an orange quote #220 >>>/leftypol_archive/1722
+ ICC profile error #221 >>>/leftypol_archive/1787

 No.6842

> $('#Grid').mixItUp('sort', (((value == "random") || (board_name == "overboard")) ? value : "sticky:desc " + value));

 No.6843

Client-side fix for generic file thumbs >>6841 in catalog:

Array.from (document.getElementsByTagName ('img')).filter (e => e.hasAttribute ('src')).map (e => [e, e.getAttribute ('src').match (/^\/([^\/]+)\/thumb\/file$/)]).filter (([e, m]) => m != null).forEach (([e, m]) => e.setAttribute ('src', '/static/file.png'))

 No.6847

I cannot post images via mobile. Is there any way around this?

 No.6848

>>6847
Post a screenshot of the error message in >>4951

 No.6849

Is the matrix server down for anyone else?

 No.6851

when do we get 24 hour unique IP calculation?

 No.6859

The "sticky bug in the overboard catalog view" #229 can also be fixed >>6842 manually on the client from the console after the page has finished loading.

[code]
(() => {
const sortby = (value) => { console.log (value); $('#Grid').mixItUp('sort', value); }
if ((active_page 'catalog') && (board_name "overboard")) {
$("#sort_by").change((e) => {
const v = e.target.value
if (v != "random") { sortby (v); }
})
if (localStorage && localStorage.catalog) {
const catalog = JSON.parse(localStorage.catalog)
const sb = catalog.sort_by
if (sb && (sb != "random")) { sortby (sb); }
}
}
})()
[/code]

This version won't work from Options -> User JS because both mixitup and catalog.js run after options/user-js.js.
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/b962f6a1283b33c6dc54c78cf4545adf92e21ce9/templates/themes/catalog/theme.php#L465

 No.6860

[code]
(() => {
const sortby = (value) => { console.log (value); $('#Grid').mixItUp('sort', value); }
if ((active_page == 'catalog') && (board_name == "overboard")) {
$("#sort_by").change((e) => {
const v = e.target.value
if (v != "random") { sortby (v); }
})
if (localStorage && localStorage.catalog) {
const catalog = JSON.parse(localStorage.catalog)
const sb = catalog.sort_by
if (sb && (sb != "random")) { sortby (sb); }
}
}
})()
[/code]

 No.6864

File: 1613008585135.txt (7.84 KB, userjs.txt)

A combined Options -> User JS with the eight >>6837 >>6843 fixes.

 No.6867

>>6727
>>6730
Why can't towards-a-new-leftypol just log in and merge this?

 No.6871

Options -> User JS fix for "sticky bug in the overboard catalog view" #229 using a mixEnd callback:
https://github.com/patrickkunka/mixitup/blob/v2/docs/events.md

[code]
(() => {
if ((active_page != 'catalog') || (board_name != "overboard")) { return; }
const state = { added: false }
$("#sort_by").change((e) => {
if (state.added) { return; }
state.added = true
$('#Grid').on('mixEnd', (ev, st) => {
as = st.activeSort
if ((typeof as === 'string') && as.startsWith ('sticky:desc ')) {
$('#Grid').mixItUp('sort', as.replace ('sticky:desc ', ""))
}
})
})
})()
[/code]

As with the individual post hiding #215 User JS fix >>6753 the price is double sorting, once with the sticky:desc forced in by catalog.js and again without. The backend fix >>6842 >>6841 doesn't have this double sorting.

 No.6878

> https://github.com/towards-a-new-leftypol/leftypol_lainchan/issues/231
> https://github.com/towards-a-new-leftypol/leftypol_lainchan/issues/230
Github mangled some code portions of the pasted comment.

> https://github.com/towards-a-new-leftypol/leftypol_lainchan/issues/229

The bugfix line in >>6841 point 3 has heading markup interference which ate the two pairs of ==.
The same line with the two pairs of == present is in >>6842.

 No.6880

File: 1613133932787.txt (8.29 KB, userjs.txt)

A combined Options -> User JS with the nine fixes.

① quick reply spoiler >>>/leftypol_archive/1801
② catalog links in div.boardlist >>>/leftypol_archive/1803
③ thread stats and Unique IPs >>6744
④ individual post hiding >>6753
⑤ sorted, labeled style selector >>6769
⑥ batch loop/once WebM setting >>6819
⑦ top/bottom navlinks in the top bar >>6835
⑧ generic file thumbs in catalog >>6843
⑨ sticky bug in the overboard catalog >>6871

 No.6881

Can mods confirm that they have heard from the maintainer (towards-a-new-leftypol) within the past two weeks to that they're ok?
Or have Biden's admin taken advantage of Trumps new anti-Antifa laws?

 No.6884

File: 1613212562675.png (21.22 KB, 491x258, 2021،02،13-13:31:42.png)

Using easy privacy list blocks cloudflare scripts that is required to pass the browser verification process. If the cloudflare check loops forever for you this might be the problem.ak-47AK-47

 No.6890

>>6881
Yes, they are alive and well.
Remember that anyone with an account can start a PR on github and also review PRs.
It also helps to attach patches (as .txt) so that they're easier to apply.

 No.6892

>>6890
>It also helps to attach patches (as .txt) so that they're easier to apply.

 No.6893

>>6890
Please tell them to log in and merge this which was pull-requested half a month ago:
https://github.com/towards-a-new-leftypol/leftypol_lainchan/pull/224

 No.6914

Put a link to the catalog at the top, as well. Right next to go to bottom so it looks like:

[ Return / Go to bottom ] [ Catalog ] [ Home ]

 No.6916

>>6914
Options -> User JS

[code]
(() => {
if (active_page !== "thread") { return; }
const added = ' [ <span class="threadlink"><a href="/' + board_name + '/catalog.html">Catalog</a></span> / <span class="threadlink"><a href="/">Home</a></span> ]'
document.querySelector ('div.threadlinks-noup').innerHTML += added
})()
[/code]

 No.6917

>>6893
Why is this not progressing / getting ignored?

 No.6923

>>6917
will checkin with tech team on this

 No.6928

File: 1613819005764.txt (8.71 KB, userjs.txt)

A combined Options -> User JS with the ten >>6880 >>6916 fixes. Added tooltips to div.boardlist catalog links.

 No.6933

To fix >>>/meta/3737
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/6885c1977834ec93b594494a963df4ef6c588c71/inc/functions.php#L2199

$code = "<pre class='code lang-$code_lang'>".str_replace(array("\n","\t"), array("&#10;","&#9;"), htmlspecialchars($code, ENT_COMPAT, "UTF-8", false))."</pre>";

https://www.php.net/manual/en/function.htmlspecialchars.php

 No.6934

Frontend workaround until the backend is fixed >>6933

Array.from (document.querySelectorAll ('pre.code')).forEach (e => { e.innerHTML = e.innerHTML.replace (/&amp;(amp|lt|gt);/g, '&$1;'); })

 No.6952

what happened to youtube embed thumbnails?

 No.6953


 No.6974

File: 1614632455671.txt (8.87 KB, userjs.txt)

A combined Options -> User JS with the eleven >>6928 >>6934 fixes.

 No.6988

Suggestion: load the [watchlist] element in the site navigation bar faster or earlier, or don't incorporate it in the centered container at all. Your use of Javascript to generate it is causing it to load much later than all the other elements. Alternatively, you could could delay the generation of the entire list until your slow-ass javashit is ready. Tired of misclicking a board I want to visit because the watchlist loads too late and shifts all the entries over!

 No.6991

when are u going to fix the youtube embeds already

 No.6992

>>6991
>>6952
They got disabled because the images were being loaded from youtube and causing a call to the site which impacted tor users especially. Someone could write code to download the images directly on the server from youtube.
Hop on the matrix chat if you're interested.

 No.7012

When you merge threads, moved posts still link back to the old thread that doesn't exist anymore.
This causes a 404 to occur if you click on a post-link in a post from the old thread

 No.7013


 No.7026

Some minor nitpicks/ideas about the onion:

On the index page for the news sections etc, leftypol.org links are not replaced with the onion.

Also with the index page and site in general, it might be worthwhile having a specific filter to replace links that have known onions for when accessing leftypol from its onion. Example would be marxists.org and archive.is both have onions, respectively: http://www.marxist7mbr3mbaj.onion http://archivecaslytosk.onion

Font Awesome and other icon fonts do not display in Tor Browser when its set at the safest security levels. SVGs are disabled as well

Continuing the idea of link replacements, might be good idea for reddit, twitter, and youtube links to be replaced on the fly to respective random instances for their privacy-oriented frontend alternatives: https://codeberg.org/teddit/teddit https://github.com/zedeus/nitter/wiki/Instances https://github.com/iv-org/documentation/blob/master/Invidious-Instances.md All three have onions listed.

 No.7050

>>7026
V2 onions are about to expire.

 No.7066

My suggestion is that we make it so it previews the flag you choose, so we lesson the chance we pick the wrong flag and it tells the new anons watch each flag looks like.

 No.7071

>>6890
> It also helps to attach patches (as .txt) so that they're easier to apply.
https://github.com/towards-a-new-leftypol/leftypol_lainchan/pull/238
> Commit the patch from issue 229 #238

Here's #125 >>>/leftypol_archive/1517

 No.7096

would it be complicated to add mathjax support? I want to start more technical thread and simply attaching latex rendered image seems unwieldy.

 No.7106

> Failed to resize image! Details: gm convert: iCCP: profile 'ICC Profile': 'RGB ': RGB color space not permitted on grayscale PNG (/tmp/phparr3Fy).
When posting this: https://files.catbox.moe/0mhv8x.png

 No.7107

The https://files.catbox.moe/0mhv8x.png >>7096 image is a type 0 grayscale png with an iCCP chunk holding 'RGB '.
$ identify rgb.png
rgb.png PNG 609x282 609x282+0+0 8-bit sRGB 256c 93.8KB 0.000u 0:00.020
identify-im6.q16: iCCP: profile 'ICC Profile': 'RGB ': RGB color space not permitted on grayscale PNG `rgb.png' @ warning/png.c/MagickPNGWarningHandler/1654.

Without the iCCP the image passes >>>/meta/3992. In IM this is only a warning which doesn't prevent thumbnailing.
$ convert rgb.png -thumbnail 200x200 rgbthumb.png
convert-im6.q16: iCCP: profile 'ICC Profile': 'RGB ': RGB color space not permitted on grayscale PNG `rgb.png' @ warning/png.c/MagickPNGWarningHandler/1654.
$ identify rgbthumb.png 
rgbthumb.png PNG 200x93 200x93+0+0 8-bit sRGB 15.2KB 0.000u 0:00.000

The entire >>>/leftypol_archive/1787 #221 applies with the additional exception string "'RGB ': RGB color space not permitted on grayscale PNG".

 No.7372

test

 No.7374

I wrote a small script to filter posts by flag. just posting it here for personal convenience so I can use it between devices. if you want to add or remove flags, just alter the "blocklist" and add or remove the strings that you see when you hover over the flags in question. might expand on it in the future to make it gui-based.
blocklist = ["Sandinista","Sabo-Tabby"]

x = document.getElementsByClassName("flag")
for(var i = 0; i &lt; x.length; i++) {
  flag = x[i]
  if (blocklist.find(element =&gt; element == flag.title)) {
    flag.parentNode.parentNode.parentNode.style.display = "none";
  }
}

 No.7375

>>7374
does the great-than symbol not work in code?
blocklist = ["Sandinista","Sabo-Tabby"]

x = document.getElementsByClassName("flag")
for(var i = 0; i &amp;lt; x.length; i++) {
  flag = x[i]
  if (blocklist.find(element =&gt; element == flag.title)) {
    flag.parentNode.parentNode.parentNode.style.display = "none";
  }
}

 No.7376

x = document.getElementsByClassName("flag")
for(var i = 0; i < x.length; i++) {
flag = x[i]
if (blocklist.find(element => element == flag.title)) {
flag.parentNode.parentNode.parentNode.style.display = "none";
}
}

 No.7382

>>7375
>does the great-than symbol not work in code?
see >>6933 >>6934

 No.7390

>Could we have one spoiler checkbox per file instead of it spoilering all files in a post?
>Could the Embed field be on the quick reply box too?

Also
>>>4015

 No.7391

>>7390

>>>/meta/4015

 No.7392


 No.7435

>>7390
>Could we have one spoiler checkbox per file instead of it spoilering all files in a post?
The storage model supports this with spoilers consisting of a per-file thumb value of 'spoiler'. >>>/anime/4442 The use of $_POST['spoiler'] in post.php for every file is relatively easy to upgrade.
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/1a6b26d2be19e430add273af00a0718fd41ef016/post.php#L1057
But after that every file with posting responsibilities would also have to be upgraded to allow for individual spoilers, among them multi-image.js, file-selector.js and quick-reply.js. This is only likely to be done by someone who needs that feature and regularly uploads multiple images, since multiple image upload is only available to begin with to those who regularly browse with remote code execution enabled.

 No.7464

File: 1617038832156.png (134.01 KB, 1002x674, "no".png)

Is this really necessary?
I doubt it.

 No.7465

Don't make a /mu/ board without fixing youtube embeds first

 No.7521

>>6727
This issue has recurred. It's leaking on catalog, but not in overboard or in-thread. Pretty sure it's still to do with embeds bugging out.

 No.7525

>>6824
>HELLLO. JANNIES. WHY CANT I HIDE INDIVIDUAL POSTS? ONLY THE OP OF THREADS WHICH IS GREAT BUT I WANT TO HIDE INDIVIDUAL POSTS IN THREADS
this still isn't fixed

 No.7526

comrades, jump on the matrix and help out contributing code.

>>7525
there's a [-] button to hide the entire thread.

 No.7528


 No.7632

>>7465
>>6727
<done I think

 No.7633

File: 1617493199624.png (Spoiler Image, 8.59 KB, 493x402, rl.png)

>>7632
Hey you
Yeah, you
I love you
<3

 No.7634

Bugged link found (radio link to .ogg as JS?)
>>>/music/1174

 No.7635

>>7634
Works ok for me, you realize it's a stream right?

 No.7637

>>7635
Yes I know it's a stream, I'm saying how it was added to the site caused a bug, similar to >>6727

 No.7641

(but obv has nothing to do with youtube this time)
maybe it's an underlying thing?

 No.7651

Requesting a peertube instance with increased maximum tag count to be used as a booru. The webm thread sucks for searching.
It will also be fun to see how long it takes to get blocked by 'safe space' socialist instances

 No.7683

>>7651
Does PeerTube even allow for more than 5 tags?

 No.7820


 No.7855

>>6724
Is there a way to go to the Cytube on the .onion domain? I just tried butchering the URL together with a tv. prefix and it didn't seem to work. Not really a big deal but it would be preferable to stay on the Tor network than to shoot out an exit node.piratePirate

 No.7857

>>7855
Well the cytube has embedded content, I don't think that will work over tor anyway, I'm not sure it can be supported.

 No.8225

https://github.com/towards-a-new-leftypol/leftypol_lainchan/issues/251
>Certain Posts with images do not stretch enough to fit the text #251
see >>6801 >>6803

 No.8386

I don't see the update button at bottom of threads anymore ?

 No.8406

>>8386
I do. What are you using?
Do you have any script blockers? Is your window larger than your screen?

 No.8425

test

 No.8631


 No.8772

>>8631
amogus

 No.9096

File: 1623357174519.png (4.97 KB, 194x60, pls-do-this.png)

(reminder)
Pls do this
Thnks

 No.9214

File: 1623700986087.png (74.49 KB, 1316x358, 000.png)

Please fix cytube config to allow direct streaming of videos, change picrel to true and avprobe respectively. Join https://cytu.be/r/ipfstest for an example of how it is supposed to work.

 No.9253

>>6756
PeerTube now supports livestreaming. Even if we don't have our own instance, can cytube support PeerTube streams?

 No.9265


 No.9478

File: 1624214509975.png (175.69 KB, 1291x637, ClipboardImage.png)

Very small thing but that I think would make a better user experience:
Put the title of the thread as the title of the page. It would make having multiple tab open much better.

 No.9481

>>9478
(() =&gt; {
  const ops = document.querySelectorAll ("div.thread &gt; div.op")
  if (ops.length !== 1) return
  const sub = ops [0].querySelector ("span.subject")
  if (!sub) return
  document.title = sub.innerText
})()


>>6933 >>6934

 No.9482

Also:
>// Show thread subject in page title.
>$config['thread_subject_in_title'] = false;
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/9acdacbb352f6f515f454f851bab581baef8fe3c/inc/config.php#L929

 No.9483

Update of catalog links in div.boardlist >>>/leftypol_archive/1803 for the new overboards:
Array.from (document.querySelectorAll ("div.boardlist a")).filter (a =&gt; a.hasAttribute ("href")).forEach (a =&gt; {
  const href = a.getAttribute ("href")
  const ma   = href.match (/^(\/[^\/]+\/)(index.html)?$/)
  let   cata = null
  if (ma != null) {
    cata = ma [1] + "catalog.html"
  }
  if (cata != null) {
    const e = document.createElement ("a")
    e.setAttribute ("href", cata)
    e.innerText = "+"
    if (a.hasAttribute ("title")) {
      e.setAttribute ("title", a.getAttribute ("title") + " - Catalog")
    }
    a.insertAdjacentElement ("afterend", e)
  }
})


>>6933 >>6934

 No.9485

Update of
https://github.com/towards-a-new-leftypol/leftypol_lainchan/issues/229
https://github.com/towards-a-new-leftypol/leftypol_lainchan/commit/237ad41fc02dded98ccde72c34ed3f87fb17186d
for the new overboards:
$('#Grid').mixItUp('sort', (((value == "random") || /^(overboard|sfw|alt)$/.test (board_name)) ? value : "sticky:desc " + value));

Or you might add a new JS var to signal an overboard.

 No.9565

>>9478
>>9482
Sorry for not seeing this earlier. Incidentally, I was thinking of doing the same thing yesterday for both user experience and SEO purposes.

 No.9567

>>9565
If, like the rest of us, you find it easy to miss things, see >>7071 for #125.

 No.9568

Maybe the wrong place, but is there a way to make the Kuroba app download the full non compressed image automatically?

 No.9570

>>9568>>4951

>This Thread Has Been Re-appropriated for leftypol.org Usage.

>General thread meant for the discussion of the mobile app for browsing leftypol.org, known as clover.

 No.9591

>>6849
I can't join matrix server

 No.9596

>>9591
Which link? In OP?
Try this one:
https://matrix.to/#/#Leftypol:matrix.org
Once you're in, find the /tech/ chat if you want.

 No.9796

File: 1625394656509.txt (7.44 KB, userjs.txt)

Updated Options -> User JS >>6974 for the recent backend changes.
① quick reply spoiler >>>/leftypol_archive/1801
② catalog links in div.boardlist >>9483
③ thread stats and Unique IPs >>6744
④ individual post hiding >>6753
⑤ batch loop/once WebM setting >>6819
⑥ top/bottom navlinks in the top bar >>6835
⑦ generic file thumbs in catalog >>6843
⑧ catalog link above OP >>6916
⑨ code double escaping >>6934

 No.9797

>>9796
One of the devs here, I've got a bit of spare time to solve some of these on the main site now that more critical changes are resolved.
Thanks for compiling and sharing these with everyone.

 No.9808

>>9797
>One of the devs here, I've got a bit of spare time to solve some of these on the main site now that more critical changes are resolved.
Thanks for all your hard work.

>Thanks for compiling and sharing these with everyone.

No problem. The last list for the backend is in >>6841. The backend-relevant updates since that list:
+ code double escaping >>6933
+ issue-125-patch.txt >>7071
+ more iCCP profiles >>7107
+ embed in quick reply >>7392
+ sticky overboard catalog sort >>9485

 No.9816

please pay attention to meeeeeeee

 No.9820

Is it just me or are all the new image thumbnails broken over the last day or so?

 No.9823

>>9820
Oh, I see what happened… Whose cocksucking idea was it to start making all thumbnails in Google's gay webp format?

 No.9824

>>9823
What browser are you using that can't handle them, mobile app?

 No.9825

>>9824
An older version of Palemoon. It's not easy for me to upgrade at the moment.

 No.9828

>>9825
Now I'm curious, you must be on a five+ year old version. Is there a breaking change? Increased requirements? Excessive customization?

 No.9829

>>9828
They adopted some new library versions a few months ago that aren't supported on *buntu 16.04. The PPA maintainer seems to have given up supporting that version and it doesn't seem like this will be easy to fix without a full system upgrade (a much more complicated problem for me).

 No.9830

File: 1625436363651.png (15.78 KB, 729x90, ooboontoo.png)

>>9829
>a few
I wouldn't call over 260 months a few, v26 introduced support. 16.04 LTS is EOL, so I suspect an OS upgrade is increasingly inevitable when things start breaking. Have you tried a live USB on the newer LTS versions?

 No.9831

>>9830
lol typo with the months, meant 60

 No.9836

To fix >>>/meta/7789 stripped file sizes for the current strip_exif+use_exiftool case:
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/e0ff3ea33ba2c81acdeb6bbc1b72ecd15a734be2/post.php#L1094
if($error = shell_exec_error('exiftool -overwrite_original -ignoreMinorErrors -q -q -all= ' .
    escapeshellarg($file['tmp_name']))) {
    error(_('Could not strip EXIF metadata!'), null, $error);
} else {
    clearstatcache(true, $file['tmp_name']);
    if (($newfilesize = filesize($file['tmp_name'])) !== false)
        $file['size'] = $newfilesize;
}

More generally, operations that modify an uploaded file should reread its size.

https://www.php.net/manual/en/function.filesize.php
https://www.php.net/manual/en/function.clearstatcache.php

 No.9851

>>9830
>v26 introduced support
Oh? I'm on v28.15 and webp rendering is broken.

 No.9854

Maybe add some escaping >>>/leftypol_archive/1499 to #289 for >>>/meta/7808.

 No.9874

File: 1625529717281.png (476.67 KB, 1234x705, ClipboardImage.png)

>>9851
Huh, that's weird then, my mistake. There have been no WebP fixes since 28.15 in updates, and support was introduced in 26.
I downloaded the 29.2.1 binary for 16.04 *ubuntu and it works, but I realize that is different.
Do either of these work?
https://developers.google.com/speed/webp/gallery1
https://developers.google.com/speed/webp/gallery2
(If you don't want to touch Google, you can search for some in https://commons.wikimedia.org/w/index.php?search=webp instead)

 No.9891

>>9874
If you don't want to or can't fix the webp thumbnails, go to Options (top right) and add this script to User JS to replace the thumbnails with the source image.

ext = ["png","jpg", "jpeg"];
$('.file').each(function(file){
   children = this.childNodes;
   if (this.tagName == 'DIV'){
   link=this.childNodes[1].href;
   if (ext.includes(link.split('.').pop())){
      this.getElementsByClassName('post-image')[0].src = link;
   }}
});


(If someone wants to critique this skiddie hack, please do.)

 No.9952

saving as original filename suddenly doesn't work
tried two browsers on both desktop and mobile

 No.9960

Any chance kuroba can work with Orbot?

 No.9965

>>9952
Thanks for reporting.
We did a change last week that deferred JS loading, which broke a few features (hopefully fixed this weekend).
At the same time, I replaced the download with filename funciton with one that didn't need Javascript, but the way I did it was flawed and lead to a security issue so we quickly removed it.
So we're currently running the deferred one that appears to be broken until enough devs are online to push the new changes.

 No.10011

New update. [code­] tags double-encoding should be fixed.

<test> && "test"

 No.10013

Javascript is fucked, backlinks don't work, the autoupdate and the [Watch Thread] appear twice.

 No.10014

>>10013
The dev team is aware and a fix should be deployed soon.

 No.10015

>>10014
Also whatever the fuck is going on here

 No.10016

>>10015
Yeah, that was trippy. On the dev env I got a quad one once.
Issue should now be resolved.

 No.10018

>>9891
Here's a better version:
[code]
$('div.file a').each(function(index){
let ext = ["png","jpg", "jpeg"];
let file = $(this);
let fullSize = file.prop("href");
if (ext.includes(fullSize.split('.').pop())){
file.find('img').prop("src", fullSize);
}
});
[\code]
the indentation is fucked.

 No.10079

>>10016
Still happens if you open the thread to reply, like using this link: https://leftypol.org/tech/res/6724.html#q10016

 No.10082

>>9986
wtf it does work, nvm

 No.10101

File: 1626170899444.txt (6.83 KB, userjs.txt)

Trimmed Options -> User JS >>9796 for the recent backend changes.
① catalog links in div.boardlist >>9483
② thread stats and Unique IPs >>6744
③ individual post hiding >>6753
④ batch loop/once WebM setting >>6819
⑤ top/bottom navlinks in the top bar >>6835
⑥ generic file thumbs in catalog >>6843
⑦ catalog link above OP >>6916

 No.10104


 No.10109

const callonce_factory = target => {
  let   called = false
  const once   = (...args) => {
    if (!called) {
      called = true
      return target (...args)
    }
  }
  return once
}

const init_file_selector_once = callonce_factory (init_file_selector)

This way init_file_selector_once can be harmlessly and cheaply called any number of times, such as at $(document).ready and before show_quick_reply → clone, without losing any defer-like benefits for the most common case where there's no q fragment.

 No.10226

>>6724
is there a way to automatically decline all legitimate interests cookies from all websites using firefoxak-47AK-47

 No.10247

When the reply count drops and a recent version of the thread is available, the ids can be diffed:
>> Array.from (document.querySelectorAll ("div.post.reply")).map (e => e.getAttribute ('id').replace (/^reply_/, '')).join (' ')
"6727 ..."

$ diffids () { diff <(echo "$1" | tr ' ' '\n') <(echo "$2" | tr ' ' '\n'); }
$ diffids "6727 ..." "6727 ..."
140d139
< 9986
151a151
> 10226

In this case the logs https://leftypol.org/log.php?board=tech suggest 9986 was probably in "Deleted all posts by IP address".

 No.10389

Duplicate scripts:
>> console.log (Object.entries (Array.from (document.getElementsByTagName ("script")).filter (e => e.hasAttribute ("src")).map (e => e.getAttribute ("src")).reduce ((acc, name, idx) => {
  if (name in acc) {
    acc [name].push (idx)
  } else {
    acc [name] = [idx]
  }
  return acc
}, {})).filter (([name, indices]) => indices.length > 1).sort ((a, b) => a [1] [0] - b [1] [0]).map (([name, indices]) => name + ' ' + indices.toString ()).join ('\n'))

/js/jquery.min.js 1,3
/js/inline-expanding.js 2,5

The source of the problem is this duplication:
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/5faa622303f7a3d9568a7c89728c3095a664b5c7/inc/config.php#L1039
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/5faa622303f7a3d9568a7c89728c3095a664b5c7/inc/instance-config.php#L375

While two jquery.min only slow page loads, the two inline-expanding cause double registration of listeners and duplicate options gui spans.

 No.10393

https://github.com/towards-a-new-leftypol/leftypol_lainchan/issues/326
> Multiple features in the Options dialog appear to be broken #326
> The first three options appear to have no effect and do not store a value when activated.
> Show relative time

After the page has loaded with scripts enabled the inspector can be used to verify that '#show-relative-time>input' has no listener. The listener is added in:
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/5faa622303f7a3d9568a7c89728c3095a664b5c7/js/local-time.js#L91
> $('#show-relative-time>input').on('change', function() {

Setting a breakpoint on that line shows that $('#show-relative-time>input') is empty, so the listener is added to nothing. One way to fix this is to retrieve the input from the options tab instead of the document:
< Options.get_tab ('general').content.find ('#show-relative-time>input').on('change', function() {

I don't know whether this is the only fix needed for js/local-time.js, that needs to be retested after the listener is in place. A similar consideration applies to every script that has been moved from onready to $(document).ready and attempts to retrieve options gui elements after an Options.extend_tab or equivalent call.

https://github.com/towards-a-new-leftypol/leftypol_lainchan/commit/88f6088a429fb73d12805377b43c6b567d03a5db
> fix Relative Time and Image Throttler
> Author: marktaiwan <[email protected]>
> Date: Fri Jan 23 00:03:37 2015 +0800
> marktaiwan authored and czaks committed May 5, 2016

 No.10407

The reason $('#show-relative-time>input') is empty >>10393 is that js/options.js adds its gui to the document at $(document).ready
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/5faa622303f7a3d9568a7c89728c3095a664b5c7/js/options.js#L105
but it's placed after some scripts that add options in $config['additional_javascript']
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/5faa622303f7a3d9568a7c89728c3095a664b5c7/inc/instance-config.php#L393

The only reason js/local-time.js and its friends even find a general tab is that js/options/general.js adds it at the time of head:
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/5faa622303f7a3d9568a7c89728c3095a664b5c7/js/options/general.js#L15

 No.10414

https://github.com/towards-a-new-leftypol/leftypol_lainchan/issues/326
> Number of simultaneous image downloads (0 to disable):

Besides being run >>10389 twice, js/inline-expanding.js has the same no listener issue >>10393 because $('#inline-expand-max input') is empty.
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/5faa622303f7a3d9568a7c89728c3095a664b5c7/js/inline-expanding.js#L196

One fix is:
< Options.get_tab ('general').content.find ('#inline-expand-max input')

 No.10419


 No.10420

When testing with scripts enabled, cloudflare's injected malware can be avoided by blocking leftypol URLs that contain "/cdn-cgi/".

 No.10421

Thanks for all your help with this, I'm going to start making pull requests over the next few days.

>>10109
Would you consider this an ideal solution for us to implement, or a simple and effective bandaid for our short-sighted $(document).ready changes? Is it sane for us to be in this situation where it is called multiple times?

 No.10429

>>10421
That is certainly only a quickfix, but a very cheap one because after the first call it will immediately return on a boolean test. A more pleasing long-term solution would be for the rememberStuff chain not to trigger 'cite' that early and instead cause a delayed 'cite' to fire at the time of $(document).ready, but this way great care must be taken with the order in which things run.

Also, I see that PR #330 has been approved and its commit merged but the duplicate scripts are still being served as I'm writing this.

 No.10430

>>10429
>>10429
We're testing bb. One sec.

 No.10432

File: 1627126740264.png (9.16 KB, 454x122, ClipboardImage.png)

>>10429
>Also, I see that PR #330 has been approved and its commit merged but the duplicate scripts are still being served as I'm writing this.
Yep, merge happens before final testing, before they go live.
I can confirm it removes the duplication in the Option form.

>That is certainly only a quickfix [snip]

I'm happy with adding that, it's safe and effective. I might aim for the better solution once we've finished fixing the fallout from our speed-improvement changes and downstreaming the years of vichan changes that lainchan ignored.

 No.10441

https://github.com/towards-a-new-leftypol/leftypol_lainchan/issues/318
> Syncronize spoiler button state on quick reply and main post form #318

While looking into this the synchronization section of js/quick-reply.js turns out to be quite peculiar.
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/dcf92dfef5f5ab900dc879d7dc4c3f04fab0aed8/js/quick-reply.js#L296
Every time the quick reply form is manually closed and reopened, new listeners are installed on the forms and the window, but the old listeners are never cleared in the .close-btn click handler.
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/dcf92dfef5f5ab900dc879d7dc4c3f04fab0aed8/js/quick-reply.js#L348

The effect can be observed on elements of the top form, such as the textarea, for which the inspector shows an ever increasing number of listeners. These keep the closed quick reply forms reachable and therefore uncollectable, leaking memory. They also transfer the top form text to each closed quick reply form, and after a sufficient number typing becomes sluggish. The .close-btn click handler should deregister all listeners that only served the closed quick reply form.

Keeping in mind that the current way of doing things leaks memory with abandon, the spoiler checkboxes can be synced by extending the synchronization section:
const cbsync = (form1, form2, name) => {
  const sel = 'input[type="checkbox"][name="' + name + '"]'
  const cb1 = form1.find (sel)
  const cb2 = form2.find (sel)
  cb1.on ('change', () => {
    cb2.prop ('checked', cb1.prop ('checked'))
  })
  cb2.on ('change', () => {
    cb1.prop ('checked', cb2.prop ('checked'))
  })
}

cbsync ($origPostForm, $postForm, 'spoiler')

 No.10444

>>10441
>Every time the quick reply form is manually closed and reopened, new listeners are installed on the forms and the window, but the old listeners are never cleared in the .close-btn click handler.
It looks adding these two .off() lines fixes it correctly:
		$postForm.find('th .close-btn').click(function() {
			// Remove origPostForm listeners
			$origPostForm.find('textarea[name="body"]').off('change input propertychange focus');
			$origPostForm.find('input[type="text"],select').off('change input propertychange');

 No.10455

>>10444
That removes every listener for those events from those elements, not just those added by js/quick-reply.js. Currently there are no others, but in the future that might remove some other script's listeners. To avoid this the events can be namespaced with something like .quickreply in both on and off calls.
https://api.jquery.com/on/#event-names

> > new listeners are installed on the forms and the window >>10441

This scroll handler on the window
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/dcf92dfef5f5ab900dc879d7dc4c3f04fab0aed8/js/quick-reply.js#L363
needs to be deregistered as well on .close-btn click because it keeps the old $postForm reachable and therefore uncollectable.

This stylesheet handler on the window
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/dcf92dfef5f5ab900dc879d7dc4c3f04fab0aed8/js/quick-reply.js#L375
needs the same treatment. Alternatively it could be added exactly once >>10109, since it doesn't depend on the $postForm, but in that case it must be moved out of show_quick_reply.

This 'quick-reply' handler on the window
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/dcf92dfef5f5ab900dc879d7dc4c3f04fab0aed8/js/quick-reply.js#L414
is added anew on every floating_link call, which occurs on every .close-btn click. It needs to be added at most once. >>10109

 No.10478

Here's a cleanup_jquery_listeners utility function:
const cleanup_jquery_listeners = cleanupspec => {
  // cleanupspec is a list of triples of
  // [jquery sets, selector or null, event string]
  // example: [
  //   [[$origPostForm, $postForm], 'input[type="text"],select', '.quickreply'],
  //   [[$(window)], null, 'scroll.quickreply']
  // ]
  for (const [sets, sel, events] of cleanupspec) {
    for (let oneset of sets) {
      if (sel != null) {
        oneset = oneset.find (sel)
      }
      oneset.off (events)
    }
  }
}

Then in .close-btn click:
const spec = [
  [[$origPostForm, $postForm], 'textarea[name="body"]', '.quickreply'],
  [[$origPostForm, $postForm], 'input[type="text"],select', '.quickreply'],
  [[$(window)], null, 'scroll.quickreply'],
  [[$postForm], 'th .close-btn', 'click.quickreply'],
]

cleanup_jquery_listeners (spec)

The $postForm is cleaned up for completeness. When spoilers are synced >>10441 they can be added to the spec list in the obvious way. All on calls need .quickreply on their events. The click, focus and scroll calls become .on('click.quickreply', …) and equivalent. The exceptions are the last two listeners of >>10455 which can be dealt with using callonce_factory >>10109.

 No.10486

>>10109
Should the callonce factory be placed in main.js?

 No.10487

For the last two listeners of >>10455, inside the outermost function of js/quick-reply.js:
const stylesheet_handler_once = callonce_factory (() => {
  $(window).on('stylesheet', function() {
    do_css();
    if ($('link#stylesheet').attr('href')) {
      $('link#stylesheet')[0].onload = do_css;
    }
  });
})

const qr_handler_once = callonce_factory (() => {
  $(window).on('quick-reply', function() {
    $('.quick-reply-btn').remove();
  });
})

Then replace
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/dcf92dfef5f5ab900dc879d7dc4c3f04fab0aed8/js/quick-reply.js#L375
with
< stylesheet_handler_once ()
and replace
https://github.com/towards-a-new-leftypol/leftypol_lainchan/blob/dcf92dfef5f5ab900dc879d7dc4c3f04fab0aed8/js/quick-reply.js#L414
with
< qr_handler_once ()

>>10486
Either templates/main.js or a new js/functools.js, entirely at the techs' option.

 No.10493

Temporary fix for spoiler sync #318 in Options -> User JS until the backend is fixed >>10441.
(() => {
  const cbsync = (form1, form2, name) => {
    const sel = 'input[type="checkbox"][name="' + name + '"]'
    const cb1 = form1.find (sel)
    const cb2 = form2.find (sel)
    cb1.on ('change', () => {
      cb2.prop ('checked', cb1.prop ('checked'))
    })
    cb2.on ('change', () => {
      cb1.prop ('checked', cb2.prop ('checked'))
    })
  }
  const spoilersync = () => {
    const ftop   = $('form[name="post"]:first')
    const fquick = $('#quick-reply')
    if ((ftop.length != 1) || (fquick.length != 1)) { return; }
    if (fquick.attr ('data-userjs-spoilersync') == 'spoilersync') { return; }
    cbsync (ftop, fquick, 'spoiler')
    fquick.attr ('data-userjs-spoilersync', 'spoilersync')
  }
  spoilersync ()
  $(window).on('quick-reply', spoilersync)
})()

 No.10494

Temporary fix for >>10079 in Options -> User JS until the backend is fixed >>10104 >>10109.
$('#quick-reply input[name="file"]').remove ()

 No.10495

File: 1627344936998.txt (7.71 KB, userjs.txt)

Updated Options -> User JS >>10101 with the current fixes.
① catalog links in div.boardlist >>9483
② thread stats and Unique IPs >>6744
③ individual post hiding >>6753
④ batch loop/once WebM setting >>6819
⑤ top/bottom navlinks in the top bar >>6835
⑥ generic file thumbs in catalog >>6843
⑦ catalog link above OP >>6916
⑧ quick reply spoiler sync >>10493
⑨ quick reply before init_file_selector >>10494

 No.10656

links like https://leftychan.net/leftypol don't work anymore

 No.10664

>extremely basic pull requests in queue for weeks
>one of three devs remaining
._.

 No.10703

Threads are having the old issue where posts don't immediately show up when you update.

 No.10705

>>10703
Now that we have more active devs and most of the basic necessities are set up, I'll request to the dev team that this become a priority fix.

btw filename download should now be fixed.

 No.10716

>>10419
auto-update.js is no longer deferred or tardy. This appears to have fixed the reliability issues with that script in normal use.
Thank you, once again.

 No.10723

>> console.log ((lines => lines.join ('\n') + '\nentries: ' + lines.length) (Object.entries (Array.from (document.getElementsByTagName ("script")).filter (e => e.hasAttribute ("src")).map (e => e.getAttribute ("src")).reduce ((acc, name, idx) => {
  if (name in acc) {
    acc [name].push (idx)
  } else {
    acc [name] = [idx]
  }
  return acc
}, {})).filter (([name, indices]) => indices.length > 1).sort ((a, b) => a [1] [0] - b [1] [0]).map (([name, indices]) => name + ' ' + indices.toString ())))

entries: 0


👍 >>10389 👍

 No.10724

I see that your post transfer method replaced some deleted file entries with generic file entries, so users will get legitimate but probably unexpected 404s.

>>>/meta/979

 No.10725

>>10724
That is strange, I'm not exactly sure what caused that.
The transfer method was a very rushed effort (for another example, flags were mistakenly added to 'body' instead of 'body_nomarkup').

>>10716
Update: this appears to be false, only part of the problem has been fixed. Work on this is continuing.

 No.10727

The post transfer method seems to have assigned the virtual thumbnail's dimensions to each spoiler image, leading to stretched spoilers like >>>/anime/8489 >>>/anime/8560. To remove the dimensions from such spoilers and show them at their natural size:
Array.from (document.querySelectorAll ("div.files > div.file img.post-image")).filter (e => e.hasAttribute ("src") && /^\/static\/.*spoiler/i.test (e.getAttribute ("src")) && e.hasAttribute ("style") && /^width:[0-9]*px;height:[0-9]*px;?$/i.test (e.getAttribute ("style").replace (/\s+/g, ''))).forEach (e => { e.removeAttribute ("style"); })

 No.10728

I believe I have found the true cause of the auto-update issue after making a new post, a regression caused by an absolute hack of a commit from January.

 No.10738

>>10728
thanks devanon.

 No.10743

We're in a shortage of SEA communist flags (only Kampuchea, Vietnam). No Thai, no Pathet Lao, no Malay Communists, not even PKI is in the list currently.
Can you mods add those?

 No.10745

>>10414
>>10419
You mention $('#inline-expand-max-input') and $('#autoScroll') as being empty and I've seen this issue in a few other cases (leading to things like a broken filter tab). Do you know what could cause them not to be found despite being generated immediately earlier? It feels like there must be something we messed up that causes them all not to work any more.
Otherwise I can patch the issue per-case with that 'find' fix you suggested.

 No.10747

>>10745
>Do you know what could cause them not to be found despite being generated immediately earlier?
This is explained in >>10407. The options gui elements are only added to the global document in the $(document).ready of js/options.js. Prior to that they cannot be retrieved from the global document because they are only in the tabs, which go into options_div, which goes into options_handler, which is not yet in the global document. Js/options.js is effectively an undeclared order dependency of js/local-time.js >>10393 js/inline-expanding.js >>10414 js/auto-scroll.js >>10419 and their friends, but it's placed too late in $config['additional_javascript'] >>10407.

>Otherwise I can patch the issue per-case with that 'find' fix you suggested.

The main advantage of retrieving the options gui elements from the tabs instead of the document is to remove the undeclared order dependence on js/options.js, which if preserved may come back to bite you in the future.

 No.10749

This question is probably better asked here than /meta/, where should leftypol.org create its Git version management?
I'm sure we can all agree on 'fuck GitHub'. Personally I would prefer a site that has no external connections/trackers and allows use without enabling JavaScript.
What would be the pros and cons of various platforms?

Current suggestions:
>self-hosted - Gitea instance on leftypol.org
>0xacab.org (GitLab, explicitly leftist, has onion, requires JS)
>disroot.org (Gitea instance, explicitly leftist, no onion)
>codeberg.org (popular, no onion)

 No.10751

Scripts usually declare their optional dependencies with //.
$ head -n 14 js/local-time.js
/*
 * local-time.js
 * https://github.com/savetheinternet/Tinyboard/blob/master/js/local-time.js
 *
 * Released under the MIT license
 * Copyright (c) 2012 Michael Save <[email protected]>
 * Copyright (c) 2013-2014 Marcin Łabanowski <[email protected]>
 *
 * Usage:
 *   // $config['additional_javascript'][] = 'js/jquery.min.js';
 *   // $config['additional_javascript'][] = 'js/strftime.min.js';
 *   $config['additional_javascript'][] = 'js/local-time.js';
 *
 */

But jquery-ui.custom in quick-reply uses verbiage instead.
$ grep -F -ne "\$config['additional_javascript'][]" -r js | grep -e ';.\+'
js/quick-reply.js:11: *   $config['additional_javascript'][] = 'js/jquery-ui.custom.min.js'; // Optional; if you want the form to be draggable.
js/show-backlinks.js:11: *   // $config['additional_javascript'][] = 'js/post-hover'; (optional; must come first)

It should be switched to // for consistency and automation.

>>10749
The sources can be seen from anywhere by cloning and pulling, but if the site requires JS then I won't be able to see ancillary features like issues and PRs. Currently GitHub has the best feature set available without JS, so by this specific criterion it's the best option, regardless of our feelings about Microsoft.

 No.10752

Here's an alpha version of a tool that checks the consistency of the ordering restrictions declared by individual scripts against the order in instance-config.php's $config['additional_javascript']. Ideally individual scripts would declare complete and correct ordering restrictions, but this doesn't hold >>10747 in practice, so this tool can only provide a hint. It currently checks for:
- duplicates in $config['additional_javascript']
- unsatisfied dependencies that are not marked optional with // >>10751
- order reversals in individual scripts versus $config['additional_javascript']
- satisfiability of the full ordering restriction graph if all scripts were to be included
Here's a wrapper that sets up the grep calls:
$ cat addjs.sh
#!/bin/sh
SRC="$1"

grep -F -ne "\$config['additional_javascript'][]" -r "$SRC"/js > scripts.txt
grep -F -ne "\$config['additional_javascript'][]" "$SRC"/inc/instance-config.php > config.txt
python3 addjs.py scripts.txt config.txt

Sample invocation:
$ sh addjs.sh ~/Documents/leftypol_lainchan
js/forced-anon.js has js/[email protected] js/options/[email protected] but config has js/[email protected] js/options/[email protected]
js/toggle-images.js has js/[email protected] js/options/[email protected] but config has js/[email protected] js/options/[email protected]
js/no-animated-gif.js has js/[email protected] js/options/[email protected] but config has js/[email protected] js/options/[email protected]
js/toggle-locked-threads.js has js/[email protected] js/options/[email protected] but config has js/[email protected] js/options/[email protected]
js/options/general.js has js/[email protected] js/options/[email protected] but config has js/[email protected] js/options/[email protected]
problems: 5

Currently, on the public sources, the only problem is style-select versus options/general, which is declared five times in the opposite order from $config['additional_javascript']. But this is the only declared >>10747 ordering problem. The style selector has been moved around recently, piggybacking on its sorted fix, but its placement in $config['additional_javascript'] and its attempted transfer at the end of options/general haven't been kept consistent. This can be fixed in either direction once the long-term placement of the style selector is decided.

 No.10753

the sample invocation without clownflare interference

 No.10831

Iqdb links but only for thumbnails supported by iqdb.org, so no webps and no full images.
Array.from (document.querySelectorAll ("div.files > div.file")).map (e => [e.querySelector ("img.post-image"), e.querySelector ("span.details")]).filter (([img, details]) => img.hasAttribute ("src") && /^\/[^\/]+\/thumb\/[^\/.]+[.](jpe?g|png|gif)$/i.test (img.getAttribute ("src"))).forEach (([img, details]) => {
  const span = document.createElement ("span")
  span.setAttribute ("class", "iqdb")
  span.innerHTML = ' <a href="https://iqdb.org/?url=https://leftypol.org' + img.getAttribute ("src") + '" target="_blank">iqdb</a>'
  details.appendChild (span)
})

 No.10838

>>10831
Why not full images? They seem to support them.

 No.10845

>>10838
>Why not full images? They seem to support them.
The first thing iqdb.org and friends do is shrink the image, so transferring full images is a waste of bandwidth on both ends when thumbnails are available. Unfortunately, not creating a retrievable thumbnail at all for spoilered images is a problem that goes all the way back to Tinyboard:
https://github.com/savetheinternet/Tinyboard/blob/master/post.php#L572
Using the full images when either a thumbnail is not available or is a webp will be in a future version of >>10831.

 No.10888

Upgrade of >>10831 to use the full images when either thumbnails are not available or in an unsupported format. A failed iqdb search will provide a saucenao link using a thumbnail generated by iqdb. This hasn't been tested with image hiders, expanders and similar scripts that mutate the div.file subtree.
((getthumb, getfull, getdest, getthumb2, getfull2, realthumb, formatok, speclist, showft) => Array.from (document.querySelectorAll ("div.files > div.file")).map (e => [getthumb (e), getfull (e), getdest (e)]).map (([ethumb, efull, edest]) => [ethumb ? getthumb2 (ethumb) : null, efull ? getfull2 (efull) : null, edest]).map (([thumb, full, edest]) => [thumb, full, edest, thumb && realthumb (thumb) && formatok (thumb), full && formatok (full)]).filter (([thumb, full, edest, thumbok, fullok]) => thumbok || fullok).forEach (([thumb, full, edest, thumbok, fullok]) => {
  const url  = "https://leftypol.org" + (thumbok ? thumb : full)
  const span = document.createElement ("span")
  span.setAttribute ("class", "iqdb")
  span.innerHTML = ' ' + (showft ? ((thumbok ? 'T' : 'F') + ':') : "") + speclist.map (([label, urlfun]) => '<a href="' + urlfun (url) + '" target="_blank">' + label + '</a>').join (' ')
  edest.appendChild (span)
})) (
  e => e.querySelector ("img.post-image"),
  e => e.querySelector ('p.fileinfo a[target="_blank"][href*="/src/"]'),
  e => e.querySelector ("span.details"),
  e => e.getAttribute ("src"),
  e => e.getAttribute ("href"),
  s => /^\/[^\/]+\/thumb\//.test (s),
  s => /[.](jpe?g|png|gif)$/i.test (s),
  [
    ["iqdb", s => "https://iqdb.org/?url=" + s],
 // ["nao",  s => "https://saucenao.com/search.php?db=999&dbmaski=32768&url=" + s]
  ],
  false
)

 No.10935

Multiupload with the site's scripts disabled but JS enabled in the dev tools console:
(count => {
  const dest = document.querySelector ("tr#upload > td.upload-area")
  if (dest == null) { return; }
  const have = dest.querySelectorAll ('input[type="file"]').length
  if (have >= count) { return; }
  const make = n => '<br class="file_separator"/><input type="file" name="file' + n + '" id="upload_file' + n + '">'
  const add  = []
  for (let k = 2; k <= count; k++) {
    add.push (make (k))
  }
  dest.innerHTML += add.join ("")
}) (5)

test: >>>/meta/10945

 No.10948

Some harmless fun with the original filenames. If the filename looks like a timestamp from a board download >>6724 the UTC date is provided. If it looks like an md5 hash >>6841 an md5 search link is provided to r34. Other matchers might be added later. This is merely a demo, not anything serious.
((getfilesbody, getorig, decorate, providers) => getfilesbody ().forEach (([files, body]) => {
  const infolist = Array.from (files.querySelectorAll ("div.file")).map ((f, index) => [getorig (f), index + 1]).filter (p => p [0] != null).map (([name, index]) => providers.map (p => p (name, index)).filter (s => s != null)).flat (1)
  if (infolist.length > 0) {
    decorate (body, infolist)
  }
})) (
  () => Array.from (document.querySelectorAll ("div.thread > div.files")).map (f => [f, f.parentNode.querySelector ("div.post.op > div.body")]).concat (Array.from (document.querySelectorAll ("div.post.reply")).map (r => [r.querySelector ("div.files"), r.querySelector ("div.body")]).filter (p => p [0] != null)),
  f => {
    const a = f.querySelector ('span.details > a[download][title^="Save as original filename"]')
    return a == null ? null : a.getAttribute ("download")
  },
  (body, infolist) => {
    const p = document.createElement ("p")
    p.setAttribute ("class", "miscfilesbodyinfo")
    p.innerHTML = infolist.join ("<br/>")
    if (body.firstChild) {
       body.insertBefore (p, body.firstChild)
       const hr = document.createElement ("hr")
       hr.setAttribute ("style", "clear: none;")
       body.insertBefore (hr, p.nextSibling)
    } else {
       body.appendChild (p)
    }
  },
  [
 // (name, index) => "file " + index + " name " + name,
    (name, index) => {
      const m = name.match (/^([0-9a-fA-F]{32})[.]/)
      if (m == null) { return null; }
      const hash = m [1]
      return "file " + index + " md5 " + hash + ' search <a href="https://rule34.xxx/index.php?page=post&s=list&tags=md5%3a' + hash + '" target="_blank">r34</a>'
    },
    (name, index) => {
      const m = name.match (/^([0-9]{13})[.]/)
      if (m == null) { return null; }
      const time = parseInt (m [1], 10)
      return "file " + index + " timestamp " + time + " date " + new Date (time).toUTCString ()
    }
  ]
)

 No.10970

Let me get rid of this, I keep clicking it instead of the reply button

 No.10981

>>10970
Include enough context around it to show which one you mean.

 No.10982

File: 1630662239183.png (140.99 KB, 1086x450, ClipboardImage.png)

>>10981
Oh also I had another niche feature idea that I think would actually be used quite a bit but sounds silly. A "greentext/quote all text" button so you can copy and paste an article without having to manually add > to every line and inevitably miss a break in the middle of a paragraph due to the site it being copied from having weird formatting.

 No.10983

>>10982
If you want that button gone right now without waiting for anything fancy you can go to Options → User CSS and enter:
div.post.op > p.intro > a.watchThread { display: none; }

Adding a button to quote every line in the comment field can be done from User JS, I'll post that tomorrow. Recovering missing line breaks from another site can only be done after you specify precise and complete rules for doing so.

 No.10984

>>10983
>Recovering missing line breaks from another site can only be done after you specify precise and complete rules for doing so.
No I mean it will avoid quoting text like

>Oh also I had another niche feature idea that I think would actually

be used quite a bit but sounds silly.
>A "greentext/quote all text" button so you can copy and paste an article without
having to manually add > to every line and inevitably miss a break in the middle of a paragraph due to the site it being copied from having weird formatting.

Because line breaks aren't always visible when adding the quotes manually, it will just keep it all green
>div.post.op > p.intro > a.watchThread { display: none; }
Based, thanks

 No.11029

>>10984
Here's some Options → User JS code to add a quote link to the post forms that quotes the lines of the comment field. To change the link's text modify the value of the a.innerText assignment. Empty lines and lines that look like post links are exempt from quoting. To modify the exemptions adjust the untouched function.
(() => {
  const empty     = s => /^\s*$/.test (s)
  const untouched = s => /^\s*>>(\d+|>\/\w+\/\d*)\s*$/.test (s)
  const prefix    = "> "
  const oneline   = s => (empty (s) || untouched (s)) ? s : (prefix + s)
  const edit      = s => s.split ("\n").map (oneline).join ("\n")
  const perform   = area => {
    const vold = area.value
    const vnew = edit (vold)
    if (vold != vnew) {
      area.focus ()
      area.setRangeText (vnew, 0, vold.length, "end")
    }
  }
  const install   = form => {
    const dest = form.querySelector ("div.banner")
    const have = dest.querySelector ("a.quotecommentlines")
    const area = form.querySelector ('textarea[name="body"]')
    if (have == null) {
      const a = document.createElement ("a")
      a.setAttribute ("class", "quotecommentlines")
      a.setAttribute ("href",  "javascript:void(0)")
      a.setAttribute ("title", "quote comment lines")
      a.innerText = "> "
      a.addEventListener ('click', event => {
        perform (area)
      })
      dest.insertBefore (a, dest.firstChild)
    } else if (form.getAttribute ("id") == "quick-reply") {
      have.addEventListener ('click', event => {
        perform (area)
      })
    }
  }
  const setup     = () => {
    const form    = document.querySelector ('form[name="post"]')
    if (form == null) { return; }
    install (form)
    const doquick = () => {
      const q = document.querySelector ('form#quick-reply')
      if (q != null) { install (q); }
    }
    doquick ()
    $(window).on ('quick-reply', doquick)
  }

  setup ()
}) ()

 No.11046

There's no div.banner in the post form in index pages so >>11029 only works in thread pages. Here's the fix to the install function to make it work in both thread pages and index pages.
(() => {
  const empty     = s => /^\s*$/.test (s)
  const untouched = s => /^\s*>>(\d+|>\/\w+\/\d*)\s*$/.test (s)
  const prefix    = "> "
  const oneline   = s => (empty (s) || untouched (s)) ? s : (prefix + s)
  const edit      = s => s.split ("\n").map (oneline).join ("\n")
  const perform   = area => {
    const vold = area.value
    const vnew = edit (vold)
    if (vold != vnew) {
      area.focus ()
      area.setRangeText (vnew, 0, vold.length, "end")
    }
  }
  const install   = form => {
    const area   = form.querySelector ('textarea[name="body"]')
    const listen = e => {
      e.addEventListener ('click', event => {
        perform (area)
      })
    }
    const quick  = form.getAttribute ("id") == "quick-reply"
    const build  = () => {
      const a = document.createElement ("a")
      a.setAttribute ("class", "quotecommentlines")
      a.setAttribute ("href",  "javascript:void(0)")
      a.setAttribute ("title", "quote comment lines")
      a.innerText = "> "
      return a
    }
    const have   = form.querySelector ("a.quotecommentlines")
    const insert = e => {
      if (quick) {
        const dest = form.querySelector ("div.banner")
        if (dest == null) { return; }
        dest.insertBefore (e, dest.firstChild)
      } else {
        const dest = area.parentNode.previousSibling
        if (dest == null) { return; }
        dest.insertBefore (document.createElement ("br"), dest.firstChild)
        dest.insertBefore (e, dest.firstChild)
      }
    }

    if (have == null) {
      const e = build ()
      insert (e)
      listen (e)
    } else if (quick) {
      insert (have)
      listen (have)
    }
  }
  const setup     = () => {
    const form    = document.querySelector ('form[name="post"]')
    if (form == null) { return; }
    install (form)
    const doquick = () => {
      const q = document.querySelector ('form#quick-reply')
      if (q != null) { install (q); }
    }
    doquick ()
    $(window).on ('quick-reply', doquick)
  }

  setup ()
}) ()

 No.11066

File: 1630855709885.png (3.05 KB, 449x67, ClipboardImage.png)

m8 who tf extended the already annoying as fuck FLOOD DETECTED box to two minutes? Can we have something slightly more sophisticated like kicking in on the third post so I don't have to sit like a retard pressing New Reply to correct a mistake in the previous post?

 No.11074

Upgrade of >>10948 to unify handling of the two sites. It'll work on some other vichan-based boards as well if their URLs are added.
(regexlisttest => ((sitespec, providers) => {
  const site = sitespec.find (spec => spec ["test"] ())
  if (!site) { return; }
  const postfiles = site ["postfiles"]
  const original  = site ["original" ]
  const decorate  = site ["decorate" ]
  site ["filesbody"] ().forEach (([files, body]) => {
    const infolist = postfiles (files).map ((f, index) => [original (f), index + 1]).filter (p => p [0] != null).map (([name, index]) => providers.map (p => p (name, index)).filter (s => s != null)).flat (1)
    if (infolist.length > 0) {
      decorate (body, infolist)
    }
  })
}) (
  [
    {
      test:      regexlisttest ([
     // /^https?:\/\//,
        /^https?:\/\/leftychan\.net\//,
        /^https?:\/\/leftypol\.org\//,
      ]),
      filesbody: () => Array.from (document.querySelectorAll ("div.thread > div.files")).map (f => [f, f.parentNode.querySelector ("div.post.op > div.body")]).concat (Array.from (document.querySelectorAll ("div.post.reply")).map (r => [r.querySelector ("div.files"), r.querySelector ("div.body")]).filter (p => p [0] != null)),
      postfiles: files => Array.from (files.querySelectorAll ("div.file")),
      original:  f => {
        let e = f.querySelector ('span.postfilename')
        if (e != null) { return e.hasAttribute ("title") ? e.getAttribute ("title") : e.innerText; }
        e = f.querySelector ('span.details > a[download][title*="original filename"]')
        if (e != null) { return e.getAttribute ("download"); }
        return null
      },
      decorate:  (body, infolist) => {
        const p = document.createElement ("p")
        p.setAttribute ("class", "miscfilesbodyinfo")
        p.innerHTML = infolist.join ("<br/>")
        if (body.firstChild) {
          body.insertBefore (p, body.firstChild)
          const hr = document.createElement ("hr")
          hr.setAttribute ("style", "clear: none;")
          body.insertBefore (hr, p.nextSibling)
        } else {
          body.appendChild (p)
        }
      }
    }
  ], [
 // (name, index) => "file " + index + " name " + name,
    ((link, speclist) => (name, index) => {
      const m = name.match (/^([0-9a-fA-F]{32})[.]/)
      if (m == null) { return null; }
      const hash = m [1]
      return "file " + index + " md5 " + hash + ' search ' + speclist.map (e => link (e ["href"] (hash), e ["name"])).join (" ")
    }) (
      (h, t) => '<a href="' + h + '" target="_blank">' + t + '</a>',
      [
        {
          name: "r3",
          href: s => "https://rule34.xxx/index.php?page=post&s=list&tags=md5%3a" + s,
        }
      ]
    ),
    (name, index) => {
      const m = name.match (/^([0-9]{13})[-.]/)
      if (m == null) { return null; }
      const time = parseInt (m [1], 10)
      return "file " + index + " timestamp " + time + " date " + new Date (time).toUTCString ()
    }
  ]
)) (
  regexlist => () => (url => regexlist.some (rx => rx.test (url))) (document.location.href)
)

 No.11079

>>11066
Two minutes? Which board is this? It shouldn't ever be that high unless you're on a shared IP during high traffic (such as the Tor node) or making new threads (different message).
I can look into making a more lenient filter, we're currently just using the default basic one.

 No.11081

>>11079
Lainchan was a mistake.

Turns out the long-tern post filtering bug (cannot hide/filter individual posts in threads) was due to them adding a postcontainer div, apparently just so that they could add '>>' to the left of each reply. Since they don't use bloat many of the additional Javascripts, they didn't realize it broke some.

As a side affect, I believe reverting that change fixed the issue where short posts are occasionally stacked to the right instead of below.

Filters appear to work fine now which opens up a lot of opportunities. Shout out if anything seems to have broken.

 No.11091

>>11079
/leftypol/, non-shared private IP. The time between the two posts was 2 minutes when it finally allowed me to post. Sometimes it feels like pressing it resets the count.

 No.11093

>>11081
>adding a postcontainer div
The alternative solution with keeping postcontainer is in >>>/leftypol_archive/1822 2021-01-29.

 No.11094

>>11093
I'm happy to implement either solution, which do you think is better? It looked to me as if the postcontainer didn't offer anything and broke scripts.

 No.11097

>>11094
>which do you think is better?
I have no opinion to offer on the costs/benefits of keeping versus removing div.postcontainer, so I trust your judgement that "the postcontainer didn't offer anything and broke scripts" and should therefore be removed. Regardless of the fate of postcontainer I also recommend the change >>>/leftypol_archive/1822 from .parent() to .parents('.thread') simply because it makes the id retrieval more resilient by causing it to work both in the presence and absence of postcontainer.

 No.11107

Upgrade of >>11074 to add support for lynx-based boards.
((regexlisttest, prefixhr) => ((sitespec, providers) => {
  const site = sitespec.find (spec => spec ["test"] ())
  if (!site) { return; }
  const postfiles = site ["postfiles"]
  const original  = site ["original" ]
  const decorate  = site ["decorate" ]
  site ["filesbody"] ().forEach (([files, body]) => {
    const infolist = postfiles (files).map ((f, index) => [original (f), index + 1]).filter (p => p [0] != null).map (([name, index]) => providers.map (p => p (name, index)).filter (s => s != null)).flat (1)
    if (infolist.length > 0) {
      decorate (body, infolist)
    }
  })
}) (
  [
    {
      test:      regexlisttest ([
        /^https?:\/\/someoldchan\.live\//,
      ]),
      filesbody: () => Array.from (document.querySelectorAll ("div.innerOP, div.innerPost")).map (i => [i.querySelector ("div.panelUploads"), i.querySelector ("div.divMessage")]).filter (p => p [0] != null),
      postfiles: files => Array.from (files.querySelectorAll ("figure.uploadCell")),
      original:  f => {
        const e = f.querySelector ('a.originalNameLink[download]')
        return e == null ? null : e.getAttribute ("download")
      },
      decorate:  prefixhr ({join: '<br style="display: initial;"/>'})
    }, {
      test:      regexlisttest ([
     // /^https?:\/\//,
        /^https?:\/\/leftychan\.net\//,
        /^https?:\/\/leftypol\.org\//,
      ]),
      filesbody: () => Array.from (document.querySelectorAll ("div.thread > div.files")).map (f => [f, f.parentNode.querySelector ("div.post.op > div.body")]).concat (Array.from (document.querySelectorAll ("div.post.reply")).map (r => [r.querySelector ("div.files"), r.querySelector ("div.body")]).filter (p => p [0] != null)),
      postfiles: files => Array.from (files.querySelectorAll ("div.file")),
      original:  f => {
        let e = f.querySelector ('span.postfilename')
        if (e != null) { return e.hasAttribute ("title") ? e.getAttribute ("title") : e.innerText; }
        e = f.querySelector ('span.details > a[download][title*="original filename"]')
        if (e != null) { return e.getAttribute ("download"); }
        return null
      },
      decorate:  prefixhr ({join: "<br/>"})
    }
  ], [
 // (name, index) => "file " + index + " name " + name,
    ((link, speclist) => (name, index) => {
      const m = name.match (/^([0-9a-fA-F]{32})[.]/)
      if (m == null) { return null; }
      const hash = m [1]
      return "file " + index + " md5 " + hash + ' search ' + speclist.map (e => link (e ["href"] (hash), e ["name"])).join (" ")
    }) (
      (h, t) => '<a href="' + h + '" target="_blank">' + t + '</a>',
      [
        {
          name: "r3",
          href: s => "https://rule34.xxx/index.php?page=post&s=list&tags=md5%3a" + s,
        }
      ]
    ),
    (name, index) => {
      const m = name.match (/^([0-9]{13})[-.]/)
      if (m == null) { return null; }
      const time = parseInt (m [1], 10)
      return "file " + index + " timestamp " + time + " date " + new Date (time).toUTCString ()
    }
  ]
)) (
  regexlist => () => (url => regexlist.some (rx => rx.test (url))) (document.location.href),
  config => (body, infolist) => {
    const p = document.createElement ("p")
    p.setAttribute ("class", "miscfilesbodyinfo")
    p.innerHTML = infolist.join (config ["join"])
    if (body.firstChild) {
      body.insertBefore (p, body.firstChild)
      const hr = document.createElement ("hr")
      hr.setAttribute ("style", "clear: none;")
      body.insertBefore (hr, p.nextSibling)
    } else {
      body.appendChild (p)
    }
  }
)

 No.11115

File: 1631011636594.png (232.27 KB, 707x615, ClipboardImage.png)

Why did the date format on the posts change from a beautiful ISO8601 to a horrible and confusing burger date format?

 No.11124

>>11115
Are those posts still like that? Can you link them?
All the posts look like ISO8601 to me. The one I'm replying to is fine.

 No.11137

>>11124
Sorry it's just 4chanX messing up with the format.

 No.11141

Okay lads I have a feature suggestion I have never seen on any imageboard, I am quite pleased to say it is a genius idea and quite simple.
In the reply box, when you start a line with > or <, it will greentext or orangetext the line as it would appear in the reply.

 No.11147

>>11141
>In the reply box
Textarea is a plain text element without subrange styling.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea
The comment line quoter which avoids >>10984 is in >>11046.

 No.11561

i might be the only affected person but i can't upload images via tor browser on android

 No.11636

File: 1632148454808.png (83.52 KB, 972x609, ClipboardImage.png)

There's now a dark solarized theme.

 No.11641

>>11561
It's not just you, I usually don't post images via mobile but I tried and they wouldn't attach (both with and without JS). I'm not sure how it would be fixed.

 No.11642

YouTube now blocks every Tor exit node. Can you change the URLs of YouTube videos so instead of YouTube links, it gives you Invidious links like this? That way we can all watch easily.

https://iteroni.com/watch?v=r65hqtFSoBY

 No.11643

>>11641
that makes two of us

 No.11644

>>11642
i type in watch?v= all the time. making it automatic would probably require an add-on? which is unadvisable with tor borwser

 No.11646

The best part about leftychan is that they reverted your shitty fucking webp thumbnail bullshit and suddenly the site became 10x more usable again because I can actually see post thumbnails on a fucking image board. Do the same here and maybe I'll think about posting again. The mods have otherwise done next to nothing constructive to end the split.

 No.11649

>>11642
Array.from (document.querySelectorAll ('a[href^="https://youtu.be/"]')).map (e => [e, e.getAttribute ("href").match (/^https:\/\/youtu\.be\/(watch\?v=)?([^?\/]+)$/)]).filter (p => p [1] != null).forEach (([e, m]) => { e.setAttribute ("href", "https://iteroni.com/watch?v=" + m [2]); })


>>11644
Array.from (document.querySelectorAll ('a[href^="https://youtu.be/"]')).map (e => [e, e.getAttribute ("href").match (/^https:\/\/youtu\.be\/([^?\/]+)$/)]).filter (p => p [1] != null).forEach (([e, m]) => { e.setAttribute ("href", "https://youtu.be/watch?v=" + m [1]); })


>>11641
If you can upload on other sites with the same procedure look at a var_dump of $_FILES early in post.php:handle_post.

 No.11650

>>11642
How about having a separate button for embedding with a mirror?
Eg:
[Embed] [Mirror]
?
Ive had issues with some invidious instances. How can we choose a reliable one?

 No.11651

>>11650
That would be cool, They could probably allow us to enter a custom instance in the options menu, so long as the default is a sane choice that proxies.

>>11646
If your computer can't show .webp in a browser by now, I think you should look into fixing it.

 No.11652

>>11651
Do you know of a good proxy?

 No.11654

File: 1632225263176.png (358.88 KB, 950x681, ClipboardImage.png)

>>11652
I never really looked into it properly, but I have confirmed https://incogtube.com proxies the videos instead of direct linking, and they also have Tor, I2P and Yggdrasil services.
aka. http://tuberyps2pn6dor6h47brof3w2asmauahhk4ei42krugybzzzo55klad.onion/feed/trending

 No.11658


 No.11660

>>11654
>….onion
This works well. Ok, I'll put it in the backlog.

Maybe if you're on tor, it embeds the .onion, if you're on clearnet, it embeds the clearnet site. That makes the most sense, right? Or is clearnet preferred for both situations?

 No.11664

>>11650
>Ive had issues with some invidious instances. How can we choose a reliable one?
How about the [Mirror] button links to https://redirect.invidious.io/watch?v={youtube_video_id}?

 No.11666

>>11660
It's not just Tor users that want to use invidious instead of YouTube, so I'd rather link both Youtube and an invidious instance on clearnet as well.

Here's a radical idea though: how about we embed an invidious instance by default and provide the original Youtube link as secondary? Like this: [Embed] [YouTube]

 No.11669


 No.11723

>>11660
If it's not difficult, Tor->Tor makes sense.

>>11666
I support this.

 No.11856

>>11643
>>11561
Can you find any websites where Tor android upload does work? I tried on a generic upload site and it failed the same way.

 No.11882

> https://git.leftypol.org/leftypol/leftypol/commit/1e690333a8b91e852fa81d2e5f458d64050c3e53
> Remove instance configuration
Removing instance-config.php from git will make issues harder to diagnose.

 No.11883

>>11882
Yeah but maybe the `salt' and `secure_trip_salt' shouldn't be public lmao

 No.11888

>>11883
> https://git.leftypol.org/leftypol/leftypol/commit/1e690333a8b91e852fa81d2e5f458d64050c3e53
> $config['db']['password'] = '';
Perhaps you could replace sensitive strings with the empty string, as is already done with $config['db']['password'], and restore the rest of instance-config.php, which is a great help in debugging.

 No.11889

>>11888
(NTA) I guess the issue is:
- adding the instance-config so that it has convenient version control
- preventing sensitive information from being added
I wonder if using an 'include' at the bottom of the instance-config to store sensitive values in another config file is an appropriate solution.

 No.11894

>>11889
Whatever system is already in use for wiping $config['db']['password'] can be used for the salts.

 No.11896

Sorry for the unreasonable delays on many of these old issues. Hopefully we can get through them quicker now that we have more active devs with code access and a stable set-up.

File-thumbing on catalogs should now be fixed. Tested it on file uploads and deleting the first image of two in an OP.
Catalog posting without javascript now works, added an inline "list-style: none" to remove the drop-down triangle.
Fixed a few of the themes and added Midnight from >>>/leftypol_archive/1541

Let us know about any outstanding issues that aren't in the Gitea tracker.

 No.11898

>>11888
>>11894
I doubt they replace the password. It is much more likely that they don't actually use one.

 No.11905

>>11898 >>11883
>I doubt they replace the password. It is much more likely that they don't actually use one.
I have no way of knowing that, but we know a password was formerly in use:
> https://git.leftypol.org/leftypol/leftypol/commit/80dc724738310b5c86ff43a7b3c6977ccd74e965
> lots of print statements
> - $config['db']['password'] = 'oijrljqqwjr242kjn';
> + $config['db']['password'] = '';

Here's a generator for >>11883 an instance-config-nosecrets.php:
$ cat instance-config-nosecrets.sh
#!/bin/sh
set -e

keylist ()
{
   #  in: cookies salt
   # out: \['cookies'\]\['salt'\]
   echo "$1" | sed -r -e 's/([^ ]+)( +|$)/\\['"'"'\1'"'"'\\]/g'
}

wipeone ()
{
   #  in: cookies salt
   # out: s/^(\$config\['cookies'\]\['salt'\] *= *')[^']+('.+)$/\1\2/
   env echo 's/^(\$config'"$(keylist "$1") *= *')[^']+('.+)\$/\1\2/"
}

nosecrets ()
{
   sed -r \
       -e "$(wipeone 'cookies salt')" \
       -e "$(wipeone secure_trip_salt)" \
       "$1" > "$2"
}

main ()
{
   nosecrets inc/instance-config.php inc/instance-config-nosecrets.php
}

main

It can be rerun whenever instance-config.php is modified, and instance-config-nosecrets.php can be put into git. To verify:
$ diff inc/instance-config.php inc/instance-config-nosecrets.php

 No.11906

>>11896
>File-thumbing on catalogs should now be fixed. Tested it on file uploads and deleting the first image of two in an OP.
>Catalog posting without javascript now works, added an inline "list-style: none" to remove the drop-down triangle.
👍

>Let us know about any outstanding issues that aren't in the Gitea tracker.

I'll make a list, but it takes a bit.

 No.11907

File: 1633098081688.txt (4.85 KB, userjs.txt)

Trimmed Options → User JS >>10495 for the new backend fixes.
① catalog links in div.boardlist >>9483
② thread stats and Unique IPs >>6744
③ batch loop/once WebM setting >>6819
④ top/bottom navlinks in the top bar >>6835
⑤ catalog link above OP >>6916
⑥ quick reply spoiler sync >>10493
⑦ quick reply before init_file_selector >>10494

 No.11914

File: 1633120548099.jpg (797.3 KB, 720x1080, 1630180285468.jpg)

> outstanding issues that aren't in the Gitea tracker >>11896
+ Unique IPs on the right | requested by >>>/leftypol_archive/1601 >>>/leftypol_archive/1624 >>>/leftypol_archive/1756 | fix >>6744
+ batch loop/once WebM setting | requested by >>>/leftypol_archive/1521 | frontend-only hack >>6819
+ update of old #229 sticky catalog for the new overboards | fix >>9485
+ catalog links in boardlist; as phrased #22 is distinct | requested by >>>/leftypol_archive/1449 | fix >>>/leftypol_archive/1807
+ up/down buttons floating | requested by >>>/leftypol_archive/1832 | frontend-only hack >>6835
+ per-file spoiler | requested by >>7390 | see this thread on the other site #10799 #10800
+ leftover memory leaks from quick-reply sync >>10441 >>10455 >>10478 >>10487
+ restore instance-config.php to git without salts >>11883 >>11905

 No.11923

>>11914
Thank you very much for this.
Also, we might revert the deferring code, at least for things like the file-selector.js where it should be loaded timely to avoid complication.

 No.11926

>>11923
>we might revert the deferring code, at least for things like the file-selector.js where it should be loaded timely to avoid complication
That's for you to decide. On the same theme: >>10104 >>10109 >>10421 >>10429 >>10432.

 No.11927

File: 1633176083089.png (25.16 KB, 625x205, ClipboardImage.png)

please add .jfif as an acceptable file extension

 No.11929

>>11927
and djvu

 No.11930

A backend version of >>6835 >>11914.

The thread view's top/bottom targets are #top and #bottom:
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/templates/thread.html#L61
> <span class="threadlink"><a href="#bottom" style="padding-left: 10px"> {% trans %}Go to bottom{% endtrans %}</a> ]</span>
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/templates/thread.html#L73
> <a id="thread-top" href="#top">[{% trans %}Go to top{% endtrans %}]</a>

The corresponding anchors are placed just after the boardlist and just before the end of the body:
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/templates/thread.html#L32
> <a name="top"></a>
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/templates/thread.html#L116
> <a href="#" id="bottom"></a>

The boardlist assembly:
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/inc/display.php#L80
> 'top' => '<div class="boardlist">' . $body . '</div>' . $top,
This could host a span with two links with titles, some classes and some default styling such as floating in style.css. Inclusion could be controlled by a new optional boolean passed to createBoardlist that defaults to false.
// after trim
if ($topbottomlinks) {
    $body .= ' <span class="topbottomlinks"><a href="#top" title="' . _('Go to top') . '">&#x25B2;</a> <a href="#bottom" title="' . _('Go to bottom') . '">&#x25BC;</a></span>';
}

// in style.css
.topbottomlinks {
    ... style to taste ...
}
.topbottomlinks a {
    ... style to taste ...
}


The createBoardlist invocations that would need the new boolean set to true:
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/inc/functions.php#L1405
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/inc/functions.php#L2331
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/inc/functions.php#L2434
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/templates/themes/catalog/theme.php#L486
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/templates/themes/overboards/theme.php#L216

Plenty of views have boardlists, most of them lacking top/bottom anchors:
$ grep -e '{{ *boardlist\.top *}}' -r .
Out of those the ones that matter and need top/bottom anchors are:
templates/index.html
templates/themes/catalog/catalog.html

The unicode arrows used above:
▲=&#x25B2;
▼=&#x25BC;

 No.11931

File: 1633218508777.png (33.66 KB, 447x420, 1630800257046.png)

Since the sources can now be referenced, here are the per-file spoiler >>11914 posts.


To move towards per-file spoilers >>7390 >>7435 exemptions for spoiler1 through spoiler9 should be added to $config['spam']['valid_inputs'], to allow per-file booleans to pass through the post form. Their number is simply for consistency with the existing file_url9.
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/inc/config.php#L279

The names of the file fields of the post form are file, file2, file3 and so on.
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/js/file-selector.js#L73

Those names can be used to select corresponding booleans sent by checkboxes, and are available as $_FILES keys when processing uploads. The $key can be temporarily stored in $file, for example as $file['formparametername'].
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/post.php#L793
https://www.php.net/manual/en/features.file-upload.post-method.php

The spoiler test
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/post.php#L1064
can then be modified to check per-file booleans:
< if ($config['spoiler_images'] && isset($_POST[str_replace('file', 'spoiler', $file['formparametername'])])) {


For per-file spoilers for the non-JS case the way to have multiple file controls can be found in multi-image.js:
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/js/multi-image.js#L21
> var new_file = '<br class="file_separator"/><input type="file" name="file'+(images_len+1)+'" id="upload_file'+(images_len+1)+'">';

The original spoiler checkbox is in post_form.html:
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/templates/post_form.html#L51
> {% if config.spoiler_images %}<div id="spoilercontainer"> <input id="spoiler" name="spoiler" type="checkbox"> <label for="spoiler">{% trans %}Spoiler Image{% endtrans %}</label></div>{% endif %}

as is the file input:
https://git.leftypol.org/leftypol/leftypol/src/commit/2d16e747a18ba900ec220a4303249402c19dcd37/templates/post_form.html#L149
> <input type="file" name="file" id="upload_file">

The div#spoilercontainer can be dropped and the file input replaced with:
{% for counter in 1..config.max_images %}
    {% if counter > 1 %}<br class="file_separator"/>{% endif %}
    {% set countersuffix = counter == 1 ? '' : counter %}
    {% if config.spoiler_images %}<span class="spoilercontainer"><input id="spoiler{{ countersuffix }}" name="spoiler{{ countersuffix }}" type="checkbox"><label for="spoiler{{ countersuffix }}">S{{ counter }}</label></span>{% endif %}
    <input type="file" name="file{{ countersuffix }}" id="upload_file{{ countersuffix }}">
{% endfor %}


A sample result is attached. This will enable per-file spoilers for the non-JS case. I'll leave the necessary frontend changes for the JS case to those who regularly browse with remote code execution enabled.

 No.11988

>>11642
>YouTube now blocks every Tor exit node.
When you browse via tor, embeds now use an invidious hidden service by default.
In an ideal world, the embed would choose a random proxy from a list of good proxies >>7026 (https://github.com/iv-org/documentation/blob/master/Invidious-Instances.md ).

My wish is something that helps with twitter links to automatically link to a random nitter instance. I absolutely detest the twitter front end. So much so that I avoid clicking twitter links.

Maybe it could look like this:
www.twitter.com/something/something [nitter]
Where [nitter] is a button that takes you to the same link, but on nitter.

>>11927
>>11929
Done. Please test and report.

 No.11998

https://git.leftypol.org/leftypol/leftypol/commit/af8b645b2395cf0d3ac0e6202d2fe1793f74e140
> Adds bar | to unique IP counter
If you want a vertical bar but place it there, you'll get a dangling bar on the right in the non-JS case. By contrast, if you want a vertical bar but place it on the left in
https://git.leftypol.org/leftypol/leftypol/src/commit/2a506d8dec5b9cb10686c8509ec73f112069bd07/js/thread-stats.js#L25
you'll get essentially the same effect but without dangling bars.

 No.12046

File: 1633862319695.jpg (253.81 KB, 566x800, aqua thumbs up.jpg)

>>11988
>Done. Please test and report.
djvu works

 No.12054

File: 1633954114029.png (126.28 KB, 1059x719, lpimage.png)

Here's a graph of relative PPD for the last 30 days for thread views.
((pagetest, install, getdata, draw) => {
  const back   = 'rgba(  0,   0,  60, 1)'
  const bars   = 'rgba(  0,   0, 255, 1)'
  const grid   = 'rgba(128, 128, 128, 1)'
  const count  = 30, step = 15
  const width  = count * step
  const height = 100

  if (!pagetest ()) { return; }
  context = install ({
    width:  width,
    height: height,
  })
  if (!context.ok) { return; }

  context.back   = back
  context.bars   = bars
  context.grid   = grid
  context.count  = count
  context.step   = step
  context.width  = width
  context.height = height
  context.data   = getdata (count)
  draw (context)
}) (
  () => (document.getElementById ('uniqueip') != null) && (document.querySelectorAll ('div.post.op').length == 1),
  config => {
    const holder = document.createElement ("div")
    holder.innerHTML = '<div style="text-align: center;"><canvas id="canvasid" width="' + config.width + '" height="' + config.height + '" style="border: 1px solid; z-index: 100; position: relative;">canvas</canvas></div>'
    const target = document.getElementById ('thread-interactions')
    if (target == null) { return { ok: false }; }
    target.parentNode.insertBefore (holder, target)
    const canvas = document.getElementById ('canvasid')

    if (canvas.getContext) {
      const ctx = canvas.getContext ('2d')
      return {
        ok:      true,
        holder:  holder,
        canvas:  canvas,
        context: ctx,
      }
    } else {
      holder.remove ()
      return { ok: false }
    }
  },
  count => {
    const all = Array.from (document.querySelectorAll ('p.intro time')).map (e => e.innerText.match (/^\d{4}-\d{2}-\d{2}/)).filter (m => m != null).reduce ((acc, m) => {
      const key = m [0]
      if (key in acc) {
        acc [key] += 1
      } else {
        acc [key]  = 1
      }
      return acc
    }, {})
    const now = new Date ()
    const key = k => {
      const when = new Date (now)
      when.setUTCDate (now.getUTCDate () - k)
      return when.getUTCFullYear ().toString ().padStart (4, '0') + '-' + (when.getUTCMonth () + 1).toString ().padStart (2, '0') + '-' + when.getUTCDate ().toString ().padStart (2, '0')
    }
    const ret = Array.from ({length: count}, (x, k) => all [key (k)] ?? 0)
    return ret
  },
  context => {
    const ctx   = context.context
    const data  = context.data
    const max   = data.reduce ((a, b) => Math.max (a, b), 0) || 1
    const w     = context.width
    const h     = context.height
    const count = context.count
    const step  = context.step

    ctx.fillStyle = context.back
    ctx.fillRect (0, 0, w, h)

    ctx.strokeStyle = context.grid
    for (let k = 0; k < count; k++) {
      ctx.beginPath ()
      ctx.moveTo (step * k, 0)
      ctx.lineTo (step * k, h)
      ctx.stroke ()
    }

    ctx.fillStyle = context.bars
    for (let k = 0; k < count; k++) {
      const y = data [k] * h / max
      ctx.fillRect (w - step - k * step, h - y, step, y)
    }
  }
)

Just a demo.

 No.12074

Would it be possible to hide threads from the catalog?

 No.12077

>>12074
It should be. Threads hidden in the normal index page view are hidden in the catalog.

 No.12103

File: 1634121334334.png (244.59 KB, 3177x800, lpimage.png)

Here's a plot for catalog views that shows the relative age of threads, growing to the right, the relative reply counts, growing to the top, and the relative bump freshness, active in red, dormant in blue. The sample images are for /tech/, /leftypol/ and /siberia/.
(tools => ((install, sitespec) => {
  const site   = sitespec.find (spec => spec.pagetest ())
  if (!site) { return; }
  const config = site.getconfig ()
  if (!config.ok) { return; }
  install (config)
  if (!config.ok) { return; }
  site.getdata (config)
  if (!config.ok) {
    config.holder.remove ()
    return
  }
  site.draw (config)
}) (
  config => {
    // > width height insertmode inserttarget
    // < holder canvas context
    const modes = {
      after:  (holder, target) => { target.parentNode.insertBefore (holder, target.nextSibling); },
      before: (holder, target) => { target.parentNode.insertBefore (holder, target); },
      first:  (holder, target) => { target.insertBefore (holder, target.firstChild); },
      last:   (holder, target) => { target.appendChild (holder); },
    }

    const holder = document.createElement ("div")
    holder.innerHTML = '<div style="text-align: center;"><canvas id="canvasid" width="' + config.width + '" height="' + config.height + '" style="border: 1px solid; z-index: 100; position: relative;">canvas</canvas></div>'
    modes [config.insertmode] (holder, config.inserttarget)
    const canvas = document.getElementById ('canvasid')

    if (canvas.getContext) {
      config.holder  = holder
      config.canvas  = canvas
      config.context = canvas.getContext ('2d')
    } else {
      holder.remove ()
      config.ok = false
    }
  }, [{
    pagetest:  () => /^https?:\/\/(leftypol\.org|leftychan\.net)\//.test (document.location.href) && (document.getElementById ('uniqueip') != null) && (document.querySelectorAll ('div.post.op').length == 1),
    getconfig: () => {
      const target = document.getElementById ('thread-interactions')
      if (target == null) { return { ok: false }; }
      const count  = 60, step = 10

      return {
        ok:     true,
        width:  count * step,
        height: 100,
        count:  count,
        step:   step,
        back:   'rgba(  0,   0,  60, 1)',
        bars:   'rgba(  0,   0, 255, 1)',
        grid:   'rgba(128, 128, 128, 1)',
        insertmode:   'before',
        inserttarget: target,
      }
    },
    getdata: config => {
      const dates = Array.from (document.querySelectorAll ('p.intro time')).map (e => e.innerText.match (/^\d{4}-\d{2}-\d{2}/)).filter (m => m != null).map (m => m [0])
      tools.getdatadatecount (config, dates)
    },
    draw: tools.drawrelative
  }, {
    pagetest:  () => /^https?:\/\/(leftypol\.org|leftychan\.net)\//.test (document.location.href) && (document.getElementById ('Grid') != null),
    getconfig: () => {
      const target = document.getElementById ('Grid')
      if (target == null) { return { ok: false }; }

      return {
        ok:     true,
        width:  400,
        height: 400,
        radius: 8,
        insertmode:   'after',
        inserttarget: target,
      }
    },
    getdata: config => {
      const now  = Date.now () / 1000
      const data = Array.from (document.querySelectorAll ('div.mix[data-bump][data-reply][data-time]')).map (e => ["data-bump", "data-reply", "data-time"].map (s => parseInt (e.getAttribute (s), 10))).map (([b, r, t]) => [now - b, r, now - t])
      config.data = data
    },
    draw: config => {
      const ctx    = config.context
      const w      = config.width
      const h      = config.height
      const radius = config.radius
      const data   = config.data
      const [maxb, maxr, maxt] = Array.from ({length: 3}, (x, k) => data.reduce ((a, b) => Math.max (a, b [k]), 0) || 1)

      data.reverse ()
      for (const [b, r, t] of data) {
        const x = t * w / maxt
        const y = h - r * h / maxr
        const c = Math.floor (b * 255 / maxb)
        const f = 'rgba(' + (255 - c) + ', 0, ' + c + ', 1)'

        ctx.fillStyle = f
        ctx.beginPath ()
        ctx.arc (x, y, radius, 0, 2 * Math.PI, true)
        ctx.fill ()
      }
    }
  }]
)) ({
  drawrelative: config => {
    const ctx   = config.context
    const data  = config.data
    const max   = data.reduce ((a, b) => Math.max (a, b), 0) || 1
    const w     = config.width
    const h     = config.height
    const count = config.count
    const step  = config.step

    ctx.fillStyle = config.back
    ctx.fillRect (0, 0, w, h)

    ctx.strokeStyle = config.grid
    for (let k = 0; k < count; k++) {
      ctx.beginPath ()
      ctx.moveTo (step * k, 0)
      ctx.lineTo (step * k, h)
      ctx.stroke ()
    }

    ctx.fillStyle = config.bars
    for (let k = 0; k < count; k++) {
      const y = data [k] * h / max
      ctx.fillRect (w - step - k * step, h - y, step, y)
    }
  },
  getdatadatecount: (config, datestrings) => {
    // YYYY-MM-DD
    const all = datestrings.reduce ((acc, key) => {
      if (key in acc) {
        acc [key] += 1
      } else {
        acc [key]  = 1
      }
      return acc
    }, {})
    const now = new Date ()
    const key = k => {
      const when = new Date (now)
      when.setUTCDate (now.getUTCDate () - k)
      return when.getUTCFullYear ().toString ().padStart (4, '0') + '-' + (when.getUTCMonth () + 1).toString ().padStart (2, '0') + '-' + when.getUTCDate ().toString ().padStart (2, '0')
    }
    const ret = Array.from ({length: config.count}, (x, k) => all [key (k)] ?? 0)
    config.data = ret
  }
})

Just a demo.

 No.12112

Just noticed that we can now hide replies! Based tech team!

 No.12113

>>12112
You're welcome! (Filters also work now.)

 No.12117

File: 1634352869762.jpg (48.94 KB, 426x639, 1628313217874.jpg)

From the meta thread:

How hard would it be to put a cool-down timer on posts? I'm probably the only mfer who would benefit from it but anyone who dumps anything on this site would appreciate it.

 No.12122

>>12117
I'm not sure if it would be too hard, but it's low-priority compared to other outstanding issues.

 No.12317

File: 1636663917616.txt (4.59 KB, userjs.txt)

Trimmed Options → User JS >>11907 for the recent backend fixes.
① catalog links in div.boardlist >>9483
② batch loop/once WebM setting >>6819
③ top/bottom navlinks in the top bar >>6835
④ catalog link above OP >>6916
⑤ quick reply spoiler sync >>10493

 No.12323

Last50 links on catalog pages:
((count, min) => Array.from (document.querySelectorAll ("div#Grid div.thread")).map (t => [t.querySelector ('a[href*="/res/"]'), t.querySelector ("div.replies > strong")]).filter (([a, s]) => parseInt (s.innerText.replace (/^R: (\d+) .+$/, "$1"), 10) >= min).forEach (([a, s]) => { s.innerHTML += ' <a href="' + a.getAttribute ("href").replace (/^(.+)([.]html)$/, "$1+50$2") + '">L' + count + '</a>'; })) (50, 100)

This can be made more resilient by exposing $config['noko50_count'] and $config['noko50_min'] in something like status.php.

 No.12354

test

 No.12383

Would it be possible to add a feature that shows all oekaki images posted on the site?

 No.12385

>>12323
I did something like this in my imageboard:
{% if post.reply_count >= config.noko50_min  %}
							<a href="{{ post.root }}{{ config.dir.res }}{{ link_for(post, true) }}">[50]</a>
							{% endif %}

Still have to figure out a solution for ukko tho.

 No.12386

>>12385
> Still have to figure out a solution for ukko tho.
My recommendation for the backend, for the general case rather than merely for the ukko family, is to only use the template to check if a last50 href and count have been sent in and if so construct the anchor, but to perform the actual last50 href and count computations in generateRecentPosts where you have more freedom and power. This way you can properly handle per-board $config['noko50_*'] settings due to the openBoard call, which you would be hard pressed to account for in the twig template.
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/templates/themes/catalog/theme.php#L428
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/templates/post_thread.html#L56
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/inc/display.php#L412

> >[50]<

You might want the interface to display the actual config.noko50_count here for that post's board.

 No.12387

>>12386
>but to perform the actual last50 href and count computations in generateRecentPosts where you have more freedom and power.
The ukko problem I face it right it now, is that the href points it to ukko link itself instead of the board, eg: /ukko/res/6+50.html.
Tried messing around with "link" in inc/display.php but without luck so far.
>This way you can properly handle per-board $config['noko50_*'] settings due to the openBoard call
Oh, I see it now. What do you have in mind? The only thing I could think of was to make a query to count every reply and check against noko50 but this seems a little too much.

>You might want the interface to display the actual config.noko50_count here for that post's board.

Done, forgot about it.

 No.12388

>>12387
>is that the href points it to ukko link itself instead of the board
Got it right by doing this:
<a href="{{ post.root }}/{{ post.board }}/{{ config.dir.res }}{{ link_for(post, true) }}">[{{config.noko50_count}}]</a>

 No.12389

>>12387 >>12388
>The ukko problem I face it right it now, is that the href points it to ukko link itself instead of the board, eg: /ukko/res/6+50.html.
If you follow >>12386 you will get the right board and settings due to the openBoard call. Notice how on the overboard index the thread fragments, which include last50 links, are built inside openBoard calls.
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/templates/themes/overboards/theme.php#L144

>Oh, I see it now. What do you have in mind?

Quite simply move the last50 href and count determination out of the catalog template and into generateRecentPosts >>12386.
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/templates/themes/catalog/theme.php#L428

>Done, forgot about it.

>Got it right by doing this:
Putting the retrieval and use of config.noko50_* values >>12388 >>12385 inside the catalog template is wrong because that template is also used for heterogeneous boards like the overboards and you'd be ignoring the per-board config values of each post's board. This is why the thread fragments of the overboard index are built separately inside their own openBoard calls, before being handed to the index template.

 No.12391

>>12389
>Notice how on the overboard index the thread fragments, which include last50 links, are built inside openBoard calls.
With this example I was able to see clearly now.
I'm going to try modify my theme with these instructions.

Also, I was looking at the issues of your fork and saw "Post Editing feature", some time ago the lainchan fork received a PR to enable edit mode for users, it works, I was able to test under NPFchan, there is only a problem with spaces that I couldn't solve and didn't want to be bother since the Administrator didn't like it the ideia.
https://github.com/lainchan/lainchan/pull/127/commits/e7213d974952b1d1e8e180b3f1c747c51fc18538

>Embedding can only be done at the top of the page #34

The embed in quick reply is managed by the settings.js default, unless you change these line to work without or set to true "show_embed"
https://git.leftypol.org/leftypol/leftypol/src/branch/config/js/quick-reply.js#L243
https://git.leftypol.org/leftypol/leftypol/src/branch/config/js/settings.js#L38

>Option for automatically archiving threads #1

Its not 100% finished but may give you an idea of an archive system.
https://github.com/Circlepuller/Tinyboard/commit/ff4cd3d041677c46e4eeabc3781aa90d58a1f983
https://github.com/Circlepuller/Tinyboard/commit/de6944710b54e38660ab5ba5827a8e07ef0e4fc6

 No.12392

>>12389
>If you follow >>12386 you will get the right board and settings due to the openBoard call. Notice how on the overboard index the thread fragments, which include last50 links, are built inside openBoard calls.
Got it doing this:
>catalog/theme.php
     private function countReplies($board, $id){
	$count_query = query(sprintf("SELECT COUNT(*) FROM ``posts_%s`` WHERE `thread` = %d", $board, $id));
	return $count_query->fetchColumn(0);

}

private function generateRecentPosts($threads) {

$noko50 = $this->countReplies($post['board'], $post['id']);
($noko50 >= $config['noko50_min']) ? $post['noko'] = '<a href="' . $config['root'] . . $board['dir'] . $config['dir']['res'] . link_for($post, true) . '">' . '['.$config['noko50_count'].']'. '</a>' : '';

}


>catalog/catalog.html

{% if post.noko %}
		{{ post.noko }}
{% endif %}

 No.12395

>>12391 >>12392
>I was looking at the issues of your fork
It's not my fork and I'm not even one of the techs, mate. I'm just a run-of-the-mill prole.

>The embed in quick reply is managed by the settings.js default

See >>7392

>private function countReplies

My friend, do you honestly think it likely that the posts would be missing their reply count information when the catalog template already shows reply counts for every thread?
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/templates/themes/catalog/catalog.html#L78
< <strong>R: {{ post.replies }} /
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/templates/themes/catalog/theme.php#L334
< (SELECT COUNT(`id`) FROM ``posts_$board`` WHERE `thread` = `thread_id`) AS `replies`

>private function generateRecentPosts

This is correct in spirit, although my opinion is that using a plain if statement like a sane person instead of an assignment inside a ternary branch would make for more maintainable code.

>{{ post.noko }}

Doing it this way instead of >>12386 is also fine.

 No.12396

>>12395
>My friend, do you honestly think it likely that the posts would be missing their reply count information when the catalog template already shows reply counts for every thread?
Kek. You're right, just doing:
$post['reply'] >= $config['noko50_min'] was enough.

The href links are fixed now without workaround in the templates, thanks.

 No.12403

Invidious proxy is broke.
Vid as an example

 No.12404

>>12403
Title: `Unexpected char ' ' at line 1, column 1 (JSON::ParseException)`
Date: `2021-11-25T05:45:19Z`
Route: `/embed/N9o1X_TNXWA?autoplay=1&html5=1`
Version: `2021.11.18-b5a96b17 @ master`
<details>
<summary>Backtrace</summary>
<p>

```
Unexpected char ' ' at line 1, column 1 (JSON::ParseException)
from /usr/share/crystal/src/json/lexer.cr:331:7 in 'raise'
from /usr/share/crystal/src/json/lexer.cr:327:5 in 'unexpected_char'
from /usr/share/crystal/src/json/lexer.cr:326:11 in 'unexpected_char'
from /usr/share/crystal/src/slice.cr:213:5 in 'next_token'
from /usr/share/crystal/src/json/parser.cr:13:12 in '_post_json'
from src/invidious/yt_backend/youtube_api.cr:317:12 in 'extract_video_info:video_id'
from src/invidious/videos.cr:972:10 in 'get_video:region'
from src/invidious/routes/embed.cr:122:15 in 'show'
from lib/kemal/src/kemal/route.cr:13:9 in '->'
from /usr/share/crystal/src/primitives.cr:266:3 in 'call'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call_next'
from lib/kemal/src/kemal/filter_handler.cr:21:7 in 'call'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call_next'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call_next'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call_next'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call_next'
from src/invidious/helpers/static_file_handler.cr:167:15 in 'call'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call'
from /usr/share/crystal/src/http/server/handler.cr:28:7 in 'call_next'
from lib/kemal/src/kemal/init_handler.cr:12:7 in 'process'
from /usr/share/crystal/src/http/server.cr:500:5 in '->'
from /usr/share/crystal/src/primitives.cr:266:3 in 'run'
from ???
```
</p>
</details>

 No.12406

>>12403 >>12404
The first script of >>11649 continues to work.

 No.12407

>>12403 >>12404
The issue is an indirect invidious bug caused by the crystal-lang upstrem: https://github.com/iv-org/invidious/issues/2612
The invidious workaround with manual decompression is in testing: https://github.com/iv-org/invidious/pull/2623
When it's merged and the instances update or when crystal-lang fixes the HTTP::Client, whichever comes sooner, the issue will go away.

 No.12424

https://git.leftypol.org/leftypol/leftypol/src/branch/config/post.php#L1115
Is this really how the PDF thumbnail is made? I tried doing it by hand on my machine but it wouldn't let me use `convert' on PDF files because there are known RCE vulnerabilities regarding that:
https://bugs.archlinux.org/task/59778

 No.12427

>>7820
Would it be possible to have an option to search for posts based on filename too? It would be extremely useful

 No.12431

>>12427
>Would it be possible to have an option to search for posts based on filename too?
Sure, but the non-body field test would have to be loosened from always using equality.
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/search.php#L124
> $like .= '`' . $name . '` = '. $pdo->quote($value);

A new filter type can be added here:
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/search.php#L60
> if(!in_array($name, array('id', 'thread', 'subject', 'name'))) {

The file names are inside a json_encode in the 'files' field of posts.
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/templates/posts.sql#L13
> `files` text DEFAULT NULL,
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/inc/functions.php#L1075
> $query->bindValue(':files', json_encode($post['files']));

The 'files' structure is an array of objects with a 'filename' field holding the upload file name.
https://git.leftypol.org/leftypol/leftypol/src/commit/199f9f5fd077e3beb9a7091295e390ac75345de1/post.php#L797
> $file['filename'] = urldecode($file['name']);

So as a trial version a LIKE test can be applied to a new files:value filter in search.php. After that with a little more effort the test can be targeted at the 'filename' field with a json path query like:
'$[*] ? (@.filename like_regex ".*valuegoeshere.*" flag "i").size()'

but this will depend on the quality of the SQL/JSON support available in the exact database type and version in use.
https://www.postgresql.org/docs/12/functions-json.html

 No.12444

>YouTube now embeds as Incognet's invidious on onion site
Amazing. Thank you based devs

 No.12446

Would be possible to scramble original filename? It's a pain in the ass to do it manual.

 No.12449

File: 1638483249769-0.jpg (175.44 KB, 680x986, 0.jpg)

File: 1638483249769-1.png (208.37 KB, 798x680, 1.png)

>>12446
Luckily I have done this before for 8chan, I had to fiddle with it a bit but now it seems to work. Add this to your User JS and it will automatically rename the files just to their index like with this post:
function getFiles(t) {
    return jQuery(t).children('.tmb-container').map(function (i, e) {
        return $(e).data('file-ref');
    });
}

function changeName(i, file) {
    var name = i + '.' + file.name.split('.').pop();
    var newFile = new File([file], name, { type: file.type }); 
    return newFile;
}

function renameFiles(files) {
    return files.map(changeName);
}

function removeFiles(t) {
    jQuery('.dropzone .remove-btn').each(function (i, e) {
        $(e).trigger('click');
    });
}

function addFiles(t, files) {
    transfer = new DataTransfer();
    for (i = 0; i < files.length; i++) {
        transfer.items.add(files[i]);
    }

    jQuery(t).parents('.dropzone').trigger(
        $.Event('drop', {
            originalEvent: new DragEvent(
                'drop',
                { dataTransfer : transfer})}));
}

function stripFilenames(t) {
    var files = getFiles(t);
    removeFiles(t);
    addFiles(t, renameFiles(files));
}

function observer(e) {
    // You have to remove it first to avoid recursion.
    jQuery('.file-thumbs').unbind("DOMSubtreeModified", observer);
    // Always do it on the main form
    stripFilenames(jQuery('.file-thumbs').first()[0]);
    jQuery('.file-thumbs').bind("DOMSubtreeModified", observer);
}

// Initialize
jQuery('.file-thumbs').bind("DOMSubtreeModified", observer);

 No.12452

For a backend version of Anon's >>12449 code a checkbox can be added to the post form wherever convenient
https://git.leftypol.org/leftypol/leftypol/src/commit/0e98c35dc59f42db891ce680f0995ec40cbb782c/templates/post_form.html#L51
then the $file['filename'] can be suppressed between $file['extension'] and $config['filename_func']
https://git.leftypol.org/leftypol/leftypol/src/commit/0e98c35dc59f42db891ce680f0995ec40cbb782c/post.php#L797
if ($config['suppress_filenames'] && isset($_POST['suppressfilenames'])) $file['filename'] = "$i." . $file['extension'];

Checkbox sync is in >>10441 and memory leak cleanup in >>10455 and >>10478.

 No.12462

>>12452
You can change the filename doing this way, but it doesn't change the json value for some reason.

 No.12471

Hey, when you dont F5 a thread, the auto update doesnt remove post deleted by mods, so you can end up replying to already banned retards
what about quickly checking if the replied to post still exist when sending it, and displaying a warning if it does not ?

also what about inline reply expansion

 No.12474

>>12471
>the replied to post
You might reply to several posts, with only one of them having been deleted. You might mean some of the post references in your reply as part of the substance of your reply, rather than as posts being replied to.

What are your thoughts on auto update applying some visual marking to those posts that are still present in your view of the thread but would go away if you were to press F5?

 No.12518


 No.12519

>>12518
Good idea, NPFchan faced a lot of abuse so it has some good moderation stuff that we can sample. Hash filters currently can't be done through the moderation interface.
There were plans for a vichan-NPFchan uplift (getting all the stuff lainchan never pulled), but unfortunately most of the development manpower is on hold for a while and (as one may have noticed) available time is mostly focused on maintenance and easy wins rather than new features and infrastructure improvement. People getting involved in the git repo would help this massively.

I haven't implemented phashes yet but it's always an option and possible with existing tools. I feel that most people able to intentionally evade a hash ban should be motivated and able to evade a phash, so it might be a wasted and computationally expensive effort.

 No.12522

>Perceptual hashing >>12518
>I feel that most people able to intentionally evade a hash ban should be motivated and able to evade a phash, so it might be a wasted and computationally expensive effort. >>12519
This would autoban false positives. Once autobanning a small fraction of innocents is conceded, that would provide an incentive for the spammers to push for a higher false positive rate.

 No.12524

Concerning >>>/meta/15307
>How the hell do you turn it off?
the current snow test is
https://git.leftypol.org/leftypol/leftypol/src/commit/b3db9c52b70f0f7103b96b61891f752791e996ab/js/winter-snow.js#L3
> var snow = localStorage['snow'] ? false : true;
while the current option uncheck handler is
https://git.leftypol.org/leftypol/leftypol/src/commit/b3db9c52b70f0f7103b96b61891f752791e996ab/js/winter-snow.js#L17
> localStorage.snow = false;
which causes snow to remain true regardless of the checkbox state.

To disable the effect without waiting for a backend fix use the dev tools console to set localStorage.snow to a value that evaluates to true in a conditional, such as
localStorage.snow = "nothanks";

then check in dev tools storage that your browser stored the new value, then reload the page.

 No.12586

Bug report that I think is reproducible:
In the following post I place a youtube link in the embed and the enter three lines of [code] text. The result is that only the embed is posted with zero text whatsoever.

 No.12587

text

textblabla

textan bloo blee blouf

 No.12588

The text missing from the above are these three lines, which perhaps (testing) will be posted normally when I now do not enter an embed in the following post:

 No.12589

text

textblabla

textan bloo blee blouf

 No.12594

>>12588
>The text missing from the above
The text is present:
<div class="post reply" id="reply_12587" data-board="tech"><p class="intro"><a id="12587" class="post_anchor"></a><input type="checkbox" class="delete" name="delete_12587" id="delete_12587"><label for="delete_12587"><span class="name">Anonymous</span> <time datetime="2021-12-20T14:45:22Z">2021-12-20 (Mon) 14:45:22</time></label>&nbsp;<a class="post_no" id="post_no_12587" onclick="highlightReply(12587)" href="/tech/res/6724.html#12587">No.</a><a class="post_no" onclick="citeReply(12587)" href="/tech/res/6724.html#q12587">12587</a></p>    <div class="video-container" data-video="NLpPyuzxSf4"><a href="https://youtu.be/NLpPyuzxSf4" target="_blank" class="file"><img style="width:255px;height:190px;" src="/vi/NLpPyuzxSf4/0.jpg" class="post-image"></a></div>         <div class="body"><pre class="code lang-">text</pre><br><pre class="code lang-">textblabla</pre><br><pre class="code lang-">textan bloo blee blouf</pre></div></div>

You can apply this CSS workaround:
pre { clear: both; }

 No.12595

File: 1640037484931.png (79.16 KB, 440x173, ClipboardImage.png)

>>12587
For me (desktop), this text shows a scroll bar.
I assume the issue is that it's invisible on your device so it looks like it's just cut off.

 No.12596

>>12595
Very strange. It is indeed invisible on my end, still.
I'm on desktop using Tor Browser, latest version, which is based on Firefox ESR, with javascript disabled (highest security setting).
Is [code] a javascript function? It doesn't seem like it. Another strange thing is that sometimes it works and I can see the [code] text like regular (leading me to speculate if it's to do with the number of lines). I did a similar test post on /siberia/ with typed in another way with an embed and it showed up normal, which made me think you had just disabled [code] on /leftypol/ as a board specifically. This was all without JS too (I always post without JS).

 No.12598

>>12596
I turned off JS (also desktop Tor; Ubuntu-based OS) and it still showed up. There is no JS involved, just CSS. That is weird. It may be a far show and I have no evidence for this but maybe Firefox's recent theming changes affected it for your OS/current-theme.

 No.12773

>>12724
$(document).on('ajax_after_post', function(e, r) { localStorage.own_posts = '{}'; });

 No.12776

Update of js/show-own-posts.js to allow users to opt out of (You) tracking. >>12724

 No.12777

>>12776
You are a hero of leftypol

 No.12801

So who's the dummy who shat up APNG uploads because of this weird error?
>Failed to resize image! Details: gm convert: fcTL: no space in chunk cache (/tmp/phpsZjJMc).

 No.12809

>>12801
APNG upload works in principle. >>>/meta/15840 The error is "benign" but for separate reasons shell_exec_error considers any stderr output an error. >>>/leftypol_archive/1787 The workaround is the same as for the iCCP family of errors. >>7107 The error means that your image has too many sPLT, tEXt, zTXt, iTXt or unknown chunks for libpng's taste.
https://github.com/glennrp/libpng/blob/a37d4836519517bdce6cb9d956092321eca3e73b/pngrutil.c#L3070
png_chunk_benign_error(png_ptr, "no space in chunk cache");

https://github.com/glennrp/libpng/blob/a37d4836519517bdce6cb9d956092321eca3e73b/pngstruct.h#L440
   /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
    * chunks that can be stored (0 means unlimited).
    */
   png_uint_32 user_chunk_cache_max;

In practice this most likely means that your animation has more frames than leftypol->gm->libpng is currently willing to quietly accept. I assume that your image was good faith but it's also possible that you were attempting a resource consumption attack. I cannot check this as you have not provided a link to an external upload of your image. >>7106 For future reference, uploading your file to http://0x0.st/ or similar and including a link will improve your bug reports.

 No.12819

>>12809
https://litter.catbox.moe/aj8vsc.png

I'm fairly certain I've uploaded this exact animation before here with no problem, and certainly without trouble on other image boards. Fix your shit, I'm never using that webp crap.

 No.12820

>>12777
>>12777
>>12777
Update on the implementation of this?

 No.12830

>>12819
Your image is legitimate >>>/meta/15862 but it has 6228 frames and 12462 chunks.
< In practice this most likely means that your animation has more frames than leftypol->gm->libpng is currently willing to quietly accept. >>12809
You have the option of uploading it spoilered, which bypasses thumbnailing. >>10845 Since the image is a type 3 8-bit PLTE with single-index transparency (tRNS=0x00) which was converted from a gif using gif2apng.sf.net, you also have the option of uploading the source gif, or losslessly reobtaining it with apng2gif. >>>/meta/15864 The techs can try adding [0] to the first %s of $config['convert_args'] to explicitly request only the first source frame, which may or may not fix the problem.
https://git.leftypol.org/leftypol/leftypol/src/commit/c5814178aee666b34902665a0bd0b4667758a875/inc/config.php#L773
     // Command-line options passed to ImageMagick when using `convert` for thumbnailing. Don't touch the
    // placement of "%s" and "%d".
    $config['convert_args'] = '-size %dx%d %s -thumbnail %dx%d -auto-orient +profile "*" %s';

Another option is the general workaround shared with the iCCP family of errors. >>12809 >>7107 >>>/leftypol_archive/1787

 No.12928

>>12776
Hopefully this is update made by a helpful anon arrives soon for leftypol.

 No.12946

File: 1641893877973.png (7.25 KB, 708x236, posthistory.png)

suggestion: username registration and post history. it's the next logical step for this website.

 No.12947

>>12946
cry about it

 No.12964

Viewing the post history of an IP >>12946 for site administration didn't originate with lefty, lain or vichan, in this family it goes all the way back to Tinyboard.
https://github.com/savetheinternet/Tinyboard/commit/78f3ea783394dba14b51b27f7f2db3974ce8b8b3#diff-e7c25d7d73eaa99b1564b025926e24d835d4322fdb65f4b9473b357f0ef64f44
Reusing the same functionality to allow users to access a read-only view of their own post history might be reasonable on a site that doesn't allow VPNs or Tor, but on a site that does allow them it's probably not a good idea.
https://git.leftypol.org/leftypol/leftypol/src/commit/c5814178aee666b34902665a0bd0b4667758a875/inc/mod/pages.php#L892
https://git.leftypol.org/leftypol/leftypol/src/commit/c5814178aee666b34902665a0bd0b4667758a875/templates/mod/view_ip.html#L204
Here's some harmless fun with localStorage.own_posts:
((sortkeys, link, divide, cites, install, slice, groups) => {
  const own    = JSON.parse (localStorage.own_posts || '{}')
  const boards = sortkeys (Object.keys (own))
  const count  = boards.reduce ((acc, item) => acc + own [item].length, 0)
  const html   = ['own posts: ' + count + ' boards: ' + boards.length]
  boards.forEach (b => {
    const ownb = own [b].reverse ()
    const have = ownb.length
    const [div, mod, left] = divide (have, slice, groups)
    html.push ('board: ' + link ('/' + b + '/index.html', '/' + b + '/') + ' ' + link ('/' + b + '/catalog.html', '&copy;') + ' count: ' + have + ' = ' + div + ' * ' + slice + ' + ' + mod + ' + ' + left)
    for (let k = 0; k < div; k++) {
      html.push (cites (b, ownb, slice, k, slice))
    }
    if (mod) {
      html.push (cites (b, ownb, slice, div, mod))
    }
  })
  install (html)
}) (
  arr => arr.map (s => [s, s.toUpperCase ()]).sort ((a, b) => a [1] < b [1] ? -1 : a [1] > b [1] ? 1 : 0).map (p => p [0]),
  (href, text) => '<a href="' + href + '">' + text + '</a>',
  (have, slice, groups) => {
    const take = Math.min (have, slice * groups)
    const mod  = take % slice
    return [(take - mod) / slice, mod, have - take]
  },
  (board, arr, slice, skip, now) => arr.slice (skip * slice, skip * slice + now).map (s => '>>>/' + board + '/' + s).join (' '),
  html => {
    const old  = document.getElementById ("ownposts-report")
    if (old) { old.remove (); }
    const node = document.createElement ("div")
    node.setAttribute ("id", "ownposts-report")
    node.setAttribute ("style", "border: thin solid;")
    node.innerHTML = html.map (s => '<p>' + s + '</p>').join ("")
    const foot = document.querySelector ('footer')
    if (foot) {
      foot.parentNode.insertBefore (node, foot)
    } else {
      document.body.appendChild (node)
    }
  },
  45, 2
)

 No.12986

>>12964
A page history for a user it's quite simple to make in php, it's just a gimp mod_view_ip and template as well.
I got this ideia from wizchan and works quite good. But that leaves you with one problem, vpn, since tor is easily blocked. But again, in my imageboard vpn and tor isn't allowed.
https://wizchan.org/history.php

 No.12987

>>12986
If you have some influence on the wizchan admin tell him to fix the double escaping in his code tags: https://wizchan.org/meta/res/60390.html#60449 08/24/21.

 No.12988


 No.13004

>>12987
Sorry, I don't even post on wizchan.

 No.13007

>>12776
Thank you writing for the code. It has been tested and is now added to the site. (I made a minor change to put them in a frameset labeled (You)s ).
https://git.leftypol.org/leftypol/leftypol/issues/66
Do you have any issue with me trying to upstream this to vichan and lainchan?

 No.13008

>>13007
>Do you have any issue with me trying to upstream this to vichan and lainchan?
None at all. Use it freely and in good health. Same for the other fixes I post here.

Separately, I'd like to point out that you need to treat show-own-posts.js.txt >>12776 as UTF-8 to get Marcin's last name right.

 No.13068

The database has been changed to a different engine (MyISAM -> InnoDB). Reverted lmao, vichan isn't concurrency-safe so a couple of people got deadlocks so we noped out.
If you notice anything weird/slow/broken, let me know.
We've also upgraded the caching, which will hopefully provide major speed improvements.

I think one of the biggest issues we should focus on for now (high impact, possible easy win) is the large delay between a post appearing on the website and the poster being told their post is successful.

>>13008
Fixed, thanks.

 No.13071


 No.13072

>>13068
https://git.leftypol.org/leftypol/leftypol/commit/e906ac74514a415c73593edfad5b540df9d67ac5?style=split&whitespace=
You are ignoring the state of $noko, which if false, such as by manual nonoko, causes:
https://git.leftypol.org/leftypol/leftypol/src/commit/e906ac74514a415c73593edfad5b540df9d67ac5/post.php#L1429
$redirect = $root . $board['dir'] . $config['file_index'];

so you might want the same buildIndex before fastcgi_finish_request order when $noko is false as for "if ($post['op'])".

 No.13073

>>13071
>>13072
These should now be fixed, thank you.

 No.13100

these mf's using php lmao

 No.13103

File: 1642673782004.jpg (3.59 MB, 3720x2800, rare-stallman.jpg)

I'd just like to say I appreciate the work being done to keep the site going
I fetch updates to the repo every now and then just to see how it's doing :3

 No.13115

Wouldn't be possible to expand original filename on hover like what 4chanX/Ponychan does? The current implementation does this with title.

 No.13116

>>13115
why even limit the filenames?

 No.13118

>>>/meta/16074
Array.from (document.querySelectorAll ("span.trip")).forEach (e => { e.parentNode.parentNode.parentNode.querySelector ("div.body").innerHTML = "I am a child seeking attention."; });

idea from: https://textboard.org/prog/34#t34p105

 No.13157

>>13116
My guess is preventing overlap when uploading multiple images.

>>13118
Nice.

>>13103
Great to hear! Now that things have settled down and I have a bit of extra time, I'm focusing on a new effort to rebase the site software from vichan(2015)->lainchan(2017)->leftypol_lainchan onto current vichan, with functional patches from lainchan and NPFchan cherry-picked (excluding broken or unneeded patches like lainchan's broken overboard posting and Slack notification support, NPF's cookie tools and forced flags).
If there's any other vichan-based IBs with features you think we should cherry-pick, let me know.

What this means is a few more features, a far less broken base, and no loss of features.

The functional part (styling ignored) is about a third of the way done but it should always remain stable and working.
https://git.leftypol.org/leftypol/leftypol_vichan/

(The reasons I'm doing this rebase as opposed to moving to another imageboard software entirely is the relative ease, the guarantee of feature parity, and the assurance of migrating without data loss. That said, it could easily happen in the long-term if one is considered objectively better at this scale)

 No.13159

>>13157
To enable overboard post, I this way (using ukko2 from lainchan):
$isukko = true; // only here for exclude somethings because the condition 'no_post_form' will be always false
return Element('index.html', array(
				'config' => $config,
				'board' => $board,
				'no_post_form' => false,
				'isukko' => $isukko,
				'body' => $body,
				'mod' => $mod,
				'boardlist' => createBoardlist($mod),
				'boards' => $boardsforukko2,
				'antibot' => $antibot
			));

then, in the post_form.html:
<table>
		{% if isukko %}
		<tr>
			<th>
				{% trans %}Board{% endtrans %}
			</th>
			<td>
					<select id="boardsUkko" name="board">
						<option value=""></option>
					{% for board in boards %}
						<option value="{{ board.uri }}">{{ board.uri }}&nbsp; -&nbsp;{{ board.title }}</option>
					{% endfor %}
					</select>
					{{ antibot.html() }}
			</td>
		</tr>
		{% endif %}

at this stage is working and need minor modifications in templates because of the widely used 'no_post_form' condition.

 No.13160

>>13159
I'm aware of that, but unless I am mistaken it's incompatible with the antispam function because it requires the antispam to be generated for that page, for the correct board that the post ends up on, which is impossible to predict.
I tried using lainchan.org's /mega/ ukko and it kept telling me my post looked automated.

 No.13161

>>13160
weird, it works fine on npfchan.

 No.13163

File: 1642935677321-0.gif (3.63 MB, 854x480, entrapta sparks.gif)

File: 1642935677321-1.png (1.11 MB, 1920x1090, entrapta weird.png)

>>13157
>I'm focusing on a new effort to rebase the site software from vichan(2015)->lainchan(2017)->leftypol_lainchan onto current vichan, with functional patches from lainchan and NPFchan cherry-picked
neato. have some motivational Entrapta

 No.13164

Bug report:
<Hide a couple of threads
>On page refresh of the overboard see the recently bumped [hidden threads] in the correctly hidden manner, but when scrolling down to pull more, older threads and a couple of said pulled threads have been [hidden] since before - they for some odd reason show up as unhidden.

 No.13165

>>13164
Post your localStorage.hiddenthreads when the bug occurs.

 No.13166

>>13165
Right now I have a lot of the threads hidden, but this happens when I have just a few threads hidden too.

 No.13168

>>13164
Thanks, I can look into it after work if that other anon doesn't beat me to it. Are the hidden threads being duplicated (like, hidden on the first page, then when loading more it's showing up a second time, unhidden) or is it just forgetting to hide ones that are loading up after the first page?

 No.13171

>>13168
>Are the hidden threads being duplicated (like, hidden on the first page, then when loading more it's showing up a second time, unhidden)
No
>or is it just forgetting to hide ones that are loading up after the first page?
Yes exactly

 No.13177

>>13168
> I can look into it after work if that other anon doesn't beat me to it
It's all yours, mate.

 No.13185

>>13164
I've make a quick fix.
https://git.leftypol.org/leftypol/leftypol/commit/0950d4d09d18da30fd0a1d02085e5b8e2782fa49
If anyone wants to look in further, it seems that filter() in post-filter.js doesn't get an up-to-date locallist, so anything after the initial page isn't searched. That trigger above prompts locallist to be regenerated.

 No.13186

>>13185 (me)
I've also noticed another pre-existing (issue?) where hidden threads on the overboard won't have any posts when unhidden. I'm considering that a wontfix because I have more important things to do than making sure there's posts in threads we explicitly choose not to see.

 No.13219

File: 1643174823137.jpg (79.82 KB, 720x540, Mjr. Dr. A.J.G.jpg)

>>13163
Nice goggles.

>>13157
It's 75% complete, excluding theming.
The last quarter will be easier since it's leftypol code and most will just be config changes and unneeded patches. After that, it's just fixing 30 small bugs I noticed along the way, bug checking and porting the CSS themes.
>NPFchan features complete
>lainchan (vanilla) features complete
(excluding rejected features)

 No.13234

>>13185
I think this was only a partial fix (for "hide threads from this board", which now works on scroll), but individual hidden threads still are subject to the original bug in question, namely that they generate on overboard scroll unhidden when they're not supposed to be.

 No.13245

>>13234
Huh, seemed to work for me when testing, not sure what's up with that. It was supposed to fix that original bug.

 No.13269

>>13245
Yeah doesn't seem to have worked, in my testing

 No.13303

So I don't have Internet at home due to being a poorfag but I used VPN at my public library, is that less secure than doing so at home?

While on VPN I can access all the sites that are autoblocked and can torrent freely

 No.13311

wonder if you could use imagemagick or ffmpeg or some other library to detect and block images with watermarks in them

 No.13312

>>13303
Wrong thread. The answer entirely depends on your threat model: who/what are you trying to be secure from?

 No.13313

>>13311
What images do you have in mind? Is something happening when I'm not here?

 No.13314


 No.13316

>>13314
i think they could be easily detected by an algorithm despite being pretty hidden to the naked glazed eyes of a person scrolling through an imageboard. soyjaks are pretty high contrast and always have a distinct color profile and whatnot from most images anyways

 No.13317

>>13314
just don't sample the first frame if there are multiple :^)
The thing about algorithmic detection is it's always a cat and mouse game.

 No.13373


 No.13382

Whoever implemented this captcha just made it impossible to post on Palemoon. Thanks for pushing more gay fucking Google monopoly web "standards".

 No.13389

>>13373
These are just the default vichan stylesheets.
https://github.com/vichan-devel/vichan/tree/master/stylesheets

 No.13394

>>13389
i noticed they have some that this site doesnt

 No.13402

>>13394
Fair enough. Fortunately this transition >>13157 should bring them all in, when it eventually happens.
Do you use any of them?

 No.13414

>>13382
>Palemoon
use IceCat
>>13402
no, just thought it'd be nice to have more themes

 No.13484

incogtube embeds are fucked up i think

 No.13585

>>13484
Are the incogtube embeds working again? Any suggestions of more reliable invidious instances are welcome, so long as they are proxying and not just a frontend.

 No.13586

Update of >>10935 for the new file_multiple[].
((count, spoilers) => {
  const dest = document.querySelector ("tr#upload > td.upload-area")
  if (dest == null) { return; }
  let   have = dest.querySelectorAll ('input[type="file"]').length
  if (have >= count) { return; }
  const sepa = '<br class="file_separator"/>'
  const file = n => (suf => '<input type="file" name="file' + suf + '" id="upload_file' + suf + '">') (n == 1 ? "" : ("" + n))
  const spoi = n => (suf => '<span class="spoilercontainer"><input id="spoiler' + suf + '" name="spoiler' + suf + '" type="checkbox"><label for="spoiler' + suf + '">S' + n + '</label></span>') (n == 1 ? "" : ("" + n))
  const add  = []

  const cleanmulti = dest => {
    const multi = dest.querySelector ('input[type="file"][multiple]')
    if (multi == null) { return false; }
    multi.remove ()
    return true
  }

  if (spoilers) {
    (e => { e.nextSibling.remove (); e.remove (); }) (document.querySelector ("input#spoiler"))
    for (let k = 1; k <= count; k++) {
      add.push (spoi (k) + file (k))
    }
    dest.innerHTML = add.join (sepa)
  } else {
    if (cleanmulti (dest)) { have--; }
    for (let k = have + 1; k <= count; k++) {
      add.push (sepa)
      add.push (file (k))
    }
    dest.innerHTML += add.join ("")
  }
}) (5, false)

This allows files from different directories and shows file order and names for potential per-file spoilers. >>7390 >>11931

test: >>>/meta/16815

 No.13592

>>13585
if youtube has turned off embeds for the video, then incogtube doesn't work at all, let alone in embed

 No.13738

Is there a way to allow oekakis for tor users by loading different wpaint settings? The load image features can be disabled, see https://github.com/websanova/wPaint/issues/113

 No.13741

>>13585
Not invidious, but Piped seems pretty good. I think this is kavin.rocks 's instance. There seem to be multiple video feeds that need to be allowed in NoScript but they are all v3 tor proxies

piped2bbch4xslbl2ckr6k62q56kon56ffowxaqzy42ai22a4sash3ad.onion/

 No.13743

>>13741
this instance seems not to play videos without allowing a non-torified domain, so actually I was wrong, nevermind. Pretty nice UI though, fits more videos on a 1kx1k window than Incognet, maybe there is a better instance out there.

 No.13792

get rid of /alt/, it inundates the side boards with low-effort shitters

 No.13959

>>13157
Update: There were delays due to other priorities and burnout, but the functionality is essentially complete and now it just needs some styling changes.
After that I might open an instance to public testing, but I don't think the ultimate switch-over will happen for a while, at least until site activity stabilizes and thread migration is tested.

 No.13964

Currently there's a 500 Internal Server Error response to requests for status.php, causing >>13960.

 No.13977

>>13964
status.php was never upgraded in the move to Composer, causing it to crash on the require_once('inc/functions.php') line. I've made a hotfix that should resolve the problem, which will be updated in the git codebase soon

 No.14055

I think the site is wigging out to DDOS, I keep getting server down messages and my posts duplicate or don't post at all.

 No.14081

>> console.log (Array.from (new Set (Array.from (document.querySelectorAll ("span.name")).map (e => e.innerText))).sort ().map ((s, idx) => (idx + 1).toString ().padStart (4, " ") + " " + s).join ("\n"))
   1 Alexandra Kollontai
   2 Alexandra Petrovna Kim
   3 Angela Davis
   4 Camila Vallejo
   5 Celia Sánchez
   6 Chizuko Ueno
   7 Clara Zetkin
   8 Constance Markievicz
   9 Elizabeth Gurley Flynn
  10 Emma Goldman
  11 Gladys Marín
  12 Helen Keller
  13 Itō Noe
  14 Juliet Chin
  15 Kathleen Neal Cleave
  16 Kshama Sawant
  17 Li Qiu
  18 Lin Guan Ying
  19 Linda Chen
  20 Louise Michel
  21 Lucy Parsons
  22 Lucía Sánchez Saornil
  23 Marsinah
  24 Marta Harnecker
  25 Mother Jones
  26 Nadezhda Krupskaya
  27 Nathalie Le Mel
  28 Nguyễn Thị Định
  29 Rosa Luxemburg
  30 Simone de Beauvoir
  31 Soong Ching-ling
  32 Vilma Espín
  33 Voltairine de Cleyre
  34 Võ Thị Sáu
  35 Võ Thị Thắng
  36 Đặng Thùy Trâm

data: >>>/meta/17

 No.14117

A member of staff can perform the following test with impunity. Pick a random post, inspect its checkbox, edit the number in id and name "delete_NNN" to some higher number that has not yet been reached by post ids on that board, and report that post with a test message. This simulates reporting a post that has been deleted immediately before submitting the report, but without having to actually delete anything. This should result in a false fetch
https://git.leftypol.org/leftypol/leftypol/src/commit/985d6f4dd66bfead158c2be016024347073f8864/post.php#L340
https://www.php.net/manual/en/pdostatement.fetch.php#refsect1-pdostatement.fetch-returnvalues
which causes the link_for in the subsequent event call argument list to attempt false['id'], resulting in >>>/meta/18331. In that case something similar to
// check if post was deleted before the report arrived
if ($thread === false) continue;

could be added just after the fetch.

 No.14131

>>14117
or you can just do:
$thread = $query->fetch(PDO::FETCH_ASSOC);

		if(!$thread)
			error('404');

 No.14135

>>14131
Reports support multiple posts at once.

 No.14141

>>14135
it stills works if i deliberate change one of the hidden inputs to a higher a number and the others reports are normal. the error() isn't triggered and the (valid) reports goes normal and the undefined key isn't triggered aswell

 No.14158

>>14141
If your statement is true within the context of a correctly performed >>14117 test, then simply provide us with a var_dump($thread) for the non-existent post id, so that we can see what $query->fetch returned while obeying the restrictions;
> WHERE `id` = :id
> $query->bindValue(':id', $id, PDO::PARAM_INT);

 No.14171

>>14158
youre actually right. the earlier tests i did, was selecting the posts and going down to where report-delete.html is being rendering and press report from there. it never considered the altered value. when i did more tests and reported from the quick-post-controls.js, the altered post id begins to trigger the error('404')

 No.14228

>trying to upload 5 pics
>collective size is less than 18mb
>File Too Big
<hmm.jpg
>upload a 50mb video as a test to see if file size got decreased
<uploaded perfectly
The fuck is going on?

 No.14233

>>14228
I don't know. Can you zip up the 5 pictures and post that so I can test?

 No.14234

>>14233
Sorry for late response, I realized the problem. I forgot the image size limit also applies to literal size, so a 11000 pixel image of 4mb reads as too large. Thanks for the response though.

 No.14496

The backend currently responds with
> Content-Type: application/octet-stream
to requests for jfif files >>>/leftypol/928733 which causes >>>/meta/19540. If this is switched at the server level to
< Content-Type: image/jpeg
or similar, the problem will go away.

 No.14531

The default catalog hover:
https://git.leftypol.org/leftypol/leftypol/src/commit/6f2e953bd51e273af63e49b457ab410c6e33684a/stylesheets/style.css#L865
.theme-catalog div.thread:hover {
  background: #D6DAF0;
  border-color: #B7C5D9;
}

Dark Red currently lacks catalog rules so it gets the default.
https://git.leftypol.org/leftypol/leftypol/src/commit/6f2e953bd51e273af63e49b457ab410c6e33684a/stylesheets/dark_red.css

The lainchanjp catalog hover:
https://git.leftypol.org/leftypol/leftypol/src/commit/6f2e953bd51e273af63e49b457ab410c6e33684a/stylesheets/lainchanjp.css#L653
.theme-catalog div.thread:hover {
  background: #4e4e4e;
  border-color: #1f1f1f;
}

Custom catalog hover can be added to Dark Red and friends to fix >>>/meta/19655.

 No.14658

Can the /tech/ team try and implement optional spoilers, at least for /siberia/? It's a real pain in the ass because a bunch of OPs are arbitrarily spoilered by the mods for being porn…. on a /b/ board. I get that overboard has all boards on it but making it optional ought to at least give non-prudes less of a headache searching catalog.
An example of such a script https://pastebin.com/R5G1JvFy (https://archive.ph/WOccP) by the late Bell.

 No.14664


 No.14687

You need to add the ability to search thread headers. I cannot find threads that I follow with the search function.

 No.14689

>>14687
Use the catalog search

 No.14690

>>14689
Thanks, Mah brudda.

 No.14840

Here's a recurring use-case problem:
Say I write a post and it had a formatting error or something. Let's say the thread is somewhat active and I copied my reply, deleted it and try to repost it. This will lead to a multitude of problems:
1. Since the thread not only bumped and a lot of people have the thread opened (which doesn't auto-update to correspond to the post-deletion!), the amount of eyes at the deleted post is now very high.
2. As I try to repost the corrected post fast to at least indirectly counteract this apparent bug, I am met with a hindrance which exacerbates the mess: a "flood detected" error message. Now I'm sitting waiting for an entire minute to post my corrected post to the deleted one that already have multiple green >>111111 replies.

Proposed solutions:
a. refresh the contents of the thread for all having the thread opened when a post is deleted
b. don't count a deleted post as a post in anti-spam mechanism
c. both of the above

 No.14841

>>14840
d. don't make mistakes

 No.14845

>>14840
This has been brought up previously >>12471 but there wasn't enough interest from the bug reporter to answer a follow-up >>12474 question.

 No.14849

>>14845
I guess >>12474 sounds like a good solution too. But I still think not counting deleted posts as posts in the anti-spam mechanism is still a good addition too. >>14840

>>14841
lmao fuck, why didn't I think of that

 No.14850

Here's a patch to implement the first option from >>14840 and >>12474 to make auto-reload.js mark deleted posts. Theme maintainers can customize the marking using the div.post.reply.auto-reload-removed selector. JS users can do the same in User CSS. Deleted posts are not considered important enough to reset the update timer, but if this is desired the removed_posts counter is available for this purpose. To test, inspect and edit a reply id to a non-existent one. Keep in mind that this is narrowly aimed at marking deleted posts, and auto-reload.js has other bugs >>>/leftypol_archive/1759 with which this patch does not concern itself.

 No.14862

>>14850
Is this not being implemented by default?

Also I tried copy-pasting the contents of the .txt into first User CSS and User JS and neither seemed to have any result on thread. Or does it require browser restart / clearing cookies and cache?

 No.14865

>>14862
That is a patch for files served to you by the backend. So first we wait patiently until the techs apply the patch on the backend. After that, if you don't like the default visual marking for deleted posts, you put
div.post.reply.auto-reload-removed {
  border: ...;
  ...
}

into User CSS and replace the ellipses with your own rules.
https://developer.mozilla.org/en-US/docs/Web/CSS/border#syntax

 No.14998

you made a mistake in https://leftypol.org/robots.txt
remove the last "Allow: /" line because A) it overrides all your preceding disallow rules, and B) is redundant/unnecessary, since anything not disallowed is already allowed by default
read https://www.robotstxt.org/robotstxt.html

 No.15005

your rotating banner system (/banners.php) is inefficient because it's impossible for users to cache these images in their browsers. everyone is constantly re-downloading previously-seen banners.

you can see if a file is already cached or is downloaded by refreshing a page (e.g. https://leftypol.org/banners.php ) by checking http responses in firefox in the Network tab in Firefox Developer Tools (ctrl+shift+i) and seeing if it says "cached" under the "Transferred" column for the file

you can instead make it so twig serves the direct path to a random image from your banners folder instead of sending it to your inlined banners.php image file stream so that browsers can actually cache these images. this can speed up frequent visitors' page loads and reduce a bit of bandwidth per frequent visitor.

1. go to /inc/lib/Twig/Extensions/Extension/Tinyboard.php
2. add this line in that list of Twig extension functions:
new Twig_SimpleFunction('random_banner_url', 'twig_random_banner_url'),

(don't forget to put a comma at the end of that previous item or you'll get php error / blank page)
3. at the end of the file add this function definition:
function twig_random_banner_url() {
	$path = dirname(__DIR__, 5) . '/banners/';
	$isDirEmpty = true;
	
	if (!file_exists($path)) {
		return '/static/blank.gif';
	}
	
	$handle = opendir($path);
	while (false !== ($entry = readdir($handle))) {
		if ($entry != "." && $entry != "..") {
			$isDirEmpty = false;
			break;
		}
	}
	closedir($handle);
	
	if (!$isDirEmpty) {
		$files = scandir($path);
		$files = array_diff($files, array('.', '..'));
		return '/banners/' . $files[array_rand($files)];
	}
	return '/static/blank.gif';
}

4. go to /templates/index.html, and change
<img class="board_image" src="{{ config.url_banner }}"

to
<img class="board_image" src="{{ random_banner_url() }}"

5. do the exact same thing in #4 for /templates/thread.html, /templates/generic_page.html, and /templates/themes/index/index.html
6. rebuild all boards/threads in mod.php and test new banner system

obviously you need to test this in a dev environment first, i did this on vichan but it looks like it's identical on lainchan. the only minor drawback is that the banner changes on each thread/index based on user actions (a new reply, thread, delete, mod action, etc.) instead of refreshing the browser due to twig's caching system, but because leftypol has high enough traffic this will not be a problem, it will change frequently enough and it's worth it for the improved page load times and minor bandwidth savings of frequent visitors not having to constantly re-download previously-seen banner images. also in theory this may reduce cpu usage a bit because the banners.php opcode is no longer executed each time any user refreshes his browser or goes to a different page, whereas this new twig function would execute only on user actions which are obviously far less frequent than refreshes / page loads. the other minor issue is it will ignore whatever you set $config['url_banner'] in instance-config.php, it will only pull images from a "/banners" folder if it exists, can't think of a way right now to have this twig function work together with that, you can put a TODO comment on this function to change it later, i don't think it's a real priority.

 No.15016

>>15005
> $isDirEmpty
If the directory is not empty, you call scandir on it. If the directory is empty, scandir would do no more work than your while loop. What is the purpose of prescanning the directory instead of testing whether the result of array_diff is empty?

> the other minor issue is it will ignore whatever you set $config['url_banner'] in instance-config.php, it will only pull images from a "/banners" folder if it exists, can't think of a way right now to have this twig function work together with that

The twig_* functions can take parameters from the calling templates. The templates can take parameters in their Element(template_source, array) invocations. The invokers of Element(template_source, array) will pass in config values for whichever openBoard call is in effect at the time. >>12386

 No.15018

>>15016
>>15005
function in step 3 is now:
function twig_random_banner_url($path) {
	if (substr($path, -1) !== "/") {
		$path = $path . '/';
	}
	$path_twig_relative = dirname(__DIR__, 5) . $path;

	if (!file_exists($path_twig_relative)) {
		return '/static/blank.gif';
	}

	$files = scandir($path_twig_relative);
	$files = array_diff($files, array('.', '..'));
	if ($files) {
		return $path . $files[array_rand($files)];
	}
	return '/static/blank.gif';
}

in step 4 & 5 it is now:
<img class="board_image" src="{{ random_banner_url(config.url_banner) }}"

and now there's a new step between 5 and 6:
5.5. in instance-config.php set $config['url_banner'] to "/banners/" or "/banners" (either will work)

 No.15020

A note about Anon's >>15018 updated code. While it will pick up the correct config.url_banner in single-board template calls, on the overboard index pages, which feature banners, it will pick up the config.url_banner of whichever board had the last thread in the $top_threads, because that board had the last openBoard call in buildOne.
https://git.leftypol.org/leftypol/leftypol/src/commit/631a5b5fc705252697734c74a69e9edffbd55bec/templates/themes/overboards/theme.php#L172

If this random pick by the last $top_threads item is not desired, config.url_banner can be remembered before the first buildOne call and sent into the index template separately in the Element invocation. >>15016
https://git.leftypol.org/leftypol/leftypol/src/commit/631a5b5fc705252697734c74a69e9edffbd55bec/templates/themes/overboards/theme.php#L204

This way the overboard index pages would use the config.url_banner setting from the global instance-config.php. On the other hand, the random pick of the banner folder by the last item in $top_threads might be considered a feature.

 No.15104

File: 1653781104387.png (130.7 KB, 1819x857, alt_is_dead.png)

Currenly overboards use the default theme of the board their last visible post is from. Perhaps this should be changed in the new overboard code, if it isn't already.

 No.15161

this commit for checking report length is incorrect it will give an error saying strlen is expecting a string not an array if someone bypasses the input maxlength set in html
https://github.com/towards-a-new-leftypol/leftypol_lainchan/commit/bb0b7007fd5e27bd29c76235cf7a1b8148995f99
if (strlen($report)

should be
if (strlen($_POST['reason'])

 No.15172

File: 1654145706733.png (679.45 KB, 1022x731, ClipboardImage.png)

Anyone know of an LGBT content blocker extension or something? I don't hate gays, I'm just sick and tired of all the retarded idpol "pride" shit slapped onto everything in the most nauseatingly liberal way, I can't avoid it even though I search for content not even tangentially related to gay stuff.

 No.15173


 No.15287

File: 1654993228127.png (755.51 KB, 1064x6307, flaglist-git.png)

Flag list for >>>/meta/20864. This version uses the git repo static/flags folder https://git.leftypol.org/leftypol/leftypol/src/commit/631a5b5fc705252697734c74a69e9edffbd55bec/static/flags which is out of sync with the live site and the hidden >>11882 >>11883 >>11905 instance-config.php, so it will not match the live post form. Adjust the 80px height in the img tag's style to taste. Rerun when a new flag shows up in the git repo.
$ cd leftypol/static/flags
$ { echo '<div style="text-align: justify">'; for f in $(ls | grep -e '[.]png$' | grep -ve '^flags[.]png$'); do echo '<span style="display: inline-block; border: 1px dashed; text-align: center">'; echo '<img style="height: 80px; image-rendering: crisp-edges" src="'$f'">'; echo '<br>'; echo '<span style="font-size: 20px">'${f%.png}'</span>'; echo '</span>'; done; echo '</div>'; } > test.html

 No.15288

File: 1654993342506.png (386.26 KB, 1064x2264, flaglist-live.png)

Flag list for >>>/meta/20864. This version uses the live post form. It has to use the live static/flags folder because the git repo is out of sync >>15287. Mobile app users get their flags through https://leftypol.org/status.php which automatically syncs https://git.leftypol.org/leftypol/leftypol/src/commit/631a5b5fc705252697734c74a69e9edffbd55bec/status.php#L55 with the live post form, so it will match this version. Adjust the 80px height in the img tag's style to taste. Rerun when a new flag shows up in the live post form.
$ { echo '<div style="text-align: justify">'; wget -q -O - 'https://leftypol.org/meta/res/20864.html' | grep -E -oe '<option value="[^"]+">[^<]+</option>' | sed -r -e 's#^<option value="([^"]+)">([^<]+)</option>#<span style="display: inline-block; border: 1px dashed; text-align: center"><img style="height: 80px; image-rendering: crisp-edges" src="https://leftypol.org/static/flags/\1.png"><br><span style="font-size: 20px">\2</span><br><span style="font-size: 20px">\1</span></span>#'; echo '</div>'; } > test.html

 No.15346

I get 404s for images on /hobby/, /games/, /draw/, /anime/, /edu/, /music/, /AKM/, /meta/, /dead/ and /gulag/ when using the onion service.

 No.15348

>>15346
Image posting is temporarily turned off for everyone so that's expected

 No.15357

https://leftypol.org/search.php?search=Grace&board=siberia
1. Why doesn't this find anything at all?
2. Why do I have to select /siberia/ again in the search form?

 No.15359

File: 1655221706870.png (1.09 MB, 1080x1080, ClipboardImage.png)

Did the mods disable clipboard images for /siberia/? It works on the other boards, but not siberia (pic rel is an example)

 No.15360

>>15359
works on my machine

 No.15362

File: 1655224315297.png (357.75 KB, 690x506, ClipboardImage.png)

>>15360
It's not on mine, Tor didn't let me use it on /siberia/ either, pic rel is attempt 2 that failed. Like I CTRL+V it and tried Right-click+Paste but it just doesn't appear in the files. Neither does uploading images for that matter.

 No.15364

About >>15357
> 2. Why do I have to select /siberia/ again in the search form?

The board parameter sent from search.php to search_form.html is called 'board':
https://git.leftypol.org/leftypol/leftypol/src/commit/631a5b5fc705252697734c74a69e9edffbd55bec/search.php#L18
> $body = Element('search_form.html', Array('boards' => $boards, 'board' => isset($_GET['board']) ? $_GET['board'] : false, 'search' => isset($_GET['search']) ? str_replace('"', '&quot;', utf8tohtml($_GET['search'])) : false));

But search_form.html tests for equality with 'b':
https://git.leftypol.org/leftypol/leftypol/src/commit/631a5b5fc705252697734c74a69e9edffbd55bec/templates/search_form.html#L10
{% for b2 in boards %}
    {% if b2 == b %}
    <option value="{{ b2 }}" selected>/{{ b2 }}/</option>
    {% else %}
    <option value="{{ b2 }}">/{{ b2 }}/</option>
    {% endif %}
{% endfor %}

If either the board parameter sent from search.php to search_form.html is renamed to 'b', or the equality test is switched to 'board', the search form should pick up the correct board as its initial selection.

 No.15365


 No.15374

>>15365
Maybe the global $board interferes with the twig template, although I can't see why it would, and we should just switch both the loop variable equality test target and the Element parameter to searchboard.

> Benjamin

This is the same Southall guy who adds parens around &&, which took precedence anyway, instead of >>>/leftypol_archive/1691 around the || chain:
https://git.leftypol.org/leftypol/leftypol/commit/1792bf48eec755ee9a07aa5bef5fbf1e27d406c4

 No.15377

>>15374
It's Appleman1234 of Lainchan fame.

I would just revert b89fe3046bfbc0d7db8e7e8773e92c0536417450.

 No.15464

The report function doesn't seem to be working on /leftypol/.
The /leftypol/ thread "Why is /pol/and so fucking right-wing?" Is overrun by /pol/yp raiders and constantly derailed. Mods don't react to reports. Could you please look into it and clean up?

 No.15636

>>15464
I know it fails on posts that have already been deleted (a refresh will show if that's the case), is this a different issue?

 No.15908


 No.16143

Bug report:
When you have set another theme from the default, the Rules and FAQ pages look atrocious / almost unreadable

 No.16145


 No.16149

>>16145
Dark Bunker Red, which is one of the very few dark themes with good contrast between the text v background, so please don't change anything else with it, it saved my eyes on here

 No.16159

You idiots do realize that Cloudflare is who shut down 8ch, right? Don't you think it'd be smarter to pick a different DDoS "protection" service?

 No.16161

>>16159
In general, complaining about something isn't really useful. If you're going to complain about something, it helps to have a plan to fix it, at least. Even better if you're willing to commit the work required to make it happen.

 No.16162


 No.16165

> the Rules and FAQ pages look atrocious / almost unreadable >>16143
> Dark Bunker Red >>16149
The relevant property of dark_bunker_red.css is that it lacks ban class styling. >>16145
https://git.leftypol.org/leftypol/leftypol/src/commit/858a501b1f652831feafd9b51c6f06c3b92e30a0/stylesheets/dark_bunker_red.css
The default dark_red.css has three div.ban sections.
https://git.leftypol.org/leftypol/leftypol/src/commit/858a501b1f652831feafd9b51c6f06c3b92e30a0/stylesheets/dark_red.css#L157

To fix add div.ban { … } and div.ban h2 { … } sections to Dev Tools → Style Editor → New Stylesheet while on the Dark Bunker Red theme, adjust the foreground and background colors as well as any other desired properties until the faq and rules pages are no longer "atrocious / almost unreadable", then once satisfied post the changes for inclusion into dark_bunker_red.css.
https://developer.mozilla.org/en-US/docs/Web/CSS/color#syntax

 No.16209


 No.16236

I just realized that this site is literally fully fucking functional without using JavaScript.

I want to give the devs a french kiss right now. A commie imageboard run by unpaid volunteers handles JavaScript better than most Fortune 500 websites.

 No.16239

>>16236
I thought all imageboards are fully functional without JS unless they add crap like recaptcha.

 No.16241

>>16239
I admittedly only really use 4chan so I can't speak for others, but with 4chan the catalog, posting (as you pointed out with the captcha part), and many other smaller little things don't work without JS. You can still browse and read but it's a much less pleasant experience than /leftypol/.

 No.16491

Why does the site now load when clicking >> links between posts in a thread? It's pretty annoying tbh

 No.16622

… U+2026 Po HORIZONTAL ELLIPSIS >>>/meta/22513 &hellip;

space >>16162
no space >>16162…

Happens here:
https://git.leftypol.org/leftypol/leftypol/src/commit/858a501b1f652831feafd9b51c6f06c3b92e30a0/inc/config.php#L557
// Automatically convert things like "..." to Unicode characters ("…").
$config['auto_unicode'] = true;

https://git.leftypol.org/leftypol/leftypol/src/commit/858a501b1f652831feafd9b51c6f06c3b92e30a0/inc/functions.php#L2076
if ($config['auto_unicode']) {
    $body = unicodify($body);

https://git.leftypol.org/leftypol/leftypol/src/commit/858a501b1f652831feafd9b51c6f06c3b92e30a0/inc/functions.php#L1976
function unicodify($body) {
    $body = str_replace('...', '&hellip;', $body);


Cite markup:
https://git.leftypol.org/leftypol/leftypol/src/commit/858a501b1f652831feafd9b51c6f06c3b92e30a0/inc/functions.php#L2089
https://git.leftypol.org/leftypol/leftypol/src/commit/858a501b1f652831feafd9b51c6f06c3b92e30a0/inc/functions.php#L2136
> ((?=[\s,.:)?!])|$)

To fix add the ampersand to the character class.
< ((?=[\s,.:)?!&])|$)

 No.16848

>>16622
You broke my ascii :(
>>>/leftypol/1178093

 No.16849

File: 1663541209002.jpg (366.99 KB, 1392x2048, nitter.jpg)

User JS snippet for twitter → nitter conversion >>>/meta/22665
Array.from (document.querySelectorAll ('a[href^="https://twitter.com/"]')).forEach (e => { e.outerHTML = e.outerHTML + ' <a target="_blank" href="' + e.getAttribute ("href").replace (/^https:\/\/twitter\.com\//, "https://nitter.net/") + '">[nitter]</a>'; })

test link: >>>/meta/22666

 No.16975

Should there be an option to see "other pages" of posts? There are topics that seem to be visible only through enabling the catalog, but without that you can only see the newest posts on a single "page" of the standard UI. This is in contrast to some other imageboards (notably 4chan, among others) where you can select page 2, 3 etc.. displaying posts without having to go to the catalog display.

Is it intended functionality to not have that feature here (and a few other boards that seem to be on a similar vichan codebase like lain )? Or is there some strangeness going on on my browser's end, possibly because of addons or the like? Thanks.

 No.17152

File: 1665034717185.png (10.81 KB, 967x46, ClipboardImage.png)

>>16975
(Sorry for late reply, I've been away from /tech/)
Looks like it's a local thing if you're not seeing the page list at the bottom of the board index.

>>16849
Has anyone asked you if you want to be part of the dev team yet? We've been pretty slow for a couple of months due to other obligations.

 No.17207

can't report cp spam from /alt/

 No.17209

Onion link asking me for a login? Then if I don't just saying "Authentication required"

 No.17300

> Failed to resize image! Details: gm convert: iCCP: cHRM chunk does not match sRGB (/tmp/phpxeccyD).
When posting this: https://upload.wikimedia.org/wikipedia/commons/0/0b/Romance_languages.png

 No.17307

Dear tech team,
Can you guys make it possible to attach .mobi files?
Thanks

 No.17328

Can .webm’s finally be uploaded on the site?

Last time I tried that it didn’t work, so I had to convert it to a .png instead.

 No.17338

>>17328
Do you mean .webp?

 No.17406

>>17338
NTA but probably.

Also IMO .webp is shit

 No.17440

OGG support when


Unique IPs: 57

[Return][Go to top] [Catalog] | [Home][Post a Reply]
Delete Post [ ]
[ home / rules / faq ] [ overboard / sfw / alt ] [ leftypol / siberia / hobby / tech / edu / games / anime / music / draw / AKM ] [ meta / roulette ] [ cytube / git ] [ GET / ref / marx / booru / zine ]