Stepped on a rake of my own devising

Streamed

scratch


topics:
x new chat room mods https://github.com/lobsters/lobsters/compare/ddafed453aa08d9543ea65185fccda487e03e8ed%5E..d7a929243b295c8dd04ded6b6c4f79d87a915bf5
x closing out cloud-init outage https://lobste.rs/s/ndvf0z/2024_09_22_cloud_init_outage_midmortem#c_ym2wes
x tabindex -> heinous_inline_partial
  PRs!
x   disappearing submitters https://github.com/lobsters/lobsters/pull/1345
x   disappearing errors https://github.com/lobsters/lobsters/pull/1343
x   disappearing tags https://github.com/lobsters/lobsters/pull/1342
x   not at all disappearing-related https://github.com/lobsters/lobsters/pull/1335
x   churn for next thing https://github.com/lobsters/lobsters/pull/1326
x stream chat plays https://tvtropes.org/pmwiki/pmwiki.php/Main/SpeakOfTheDevil
  avatar uploading https://github.com/lobsters/lobsters/issues/547
  copy/support avatar from github? https://github.com/lobsters/lobsters/issues/986

story tags complexity: abstractions from UI to storage
  tomselect for better ui
  browser text input element
  serialize to POST
  controller deserializes to a ruby array
  Story tags_a: array of strings
  Story tags associations: activerecord models
  Story/Tags/Taggings records in the database

making code easy to delete?
  https://programmingisterrible.com/post/139222674273/write-code-that-is-easy-to-delete-not-easy-to
  https://www.pretzer.io/professional/theory/coding_practices/write_code_that_is_easy_to_delete/
  probably Sandi Metz talk
  raganwald (Reginald Braithwaite) blog parable about adding features w monkeypatching/aspect-oriented programming

avatar todo
x survey usage: inline on stories/comments and big on profiles
x figure out why we have 32 and 100 px sizes
x decide what sizes to support: 16, 32, 48 for inline and 128, 256, 512 for profile
x /settings: allow user to upload their avatar
x /settings: allow user to delete their avatar
x force active storage to exclusively use vips
x avatar: max file size

  photos: enforce max dimensions
  photos: strip exif metadata from jpgs (but not orientation)
  test: what happens if you upload a non-image?
  how does rails handle resizing non-square images to square? https://github.com/janko/image_processing/blob/master/doc/vips.md#resize_to_fill
  manual test: can I DOS by uploading a huge image?
  replace existing avatar service with ours (avatar_img, rm avatars#expire)
  migration to fetch avatars (ignore placeholders) for all users
  generate placeholders for users without uploads
  trigger rails generating various file sizes
  nginx config: download avatars


title:
  stepped on a rake of my own devising
  I already wrote the evil code so why not use the evil


post-stream:
  list of moderators is not prominent enough on /about (not linked!?)
  doublecheck db01 cloud-init
  surf browser from suckless - terminal based?
  file issue to make _comment.html.erb <a> tags work without js - all href="#"
    

Transcripts are generated with whisperx, so they mistranscribe basically every username and technical term. They're OK but not great, advice appreciated.

Recording



02:32Hello, hello. Hey, folks. Nice to see you all on this totally quiet and uneventful Monday on which absolutely nothing is happening.

...51frici Hello there!
And let's see, for once, I'm actually going to look at users in chat. All right, I see some familiar names. I don't yet see ARH68 who needs to be cautioned about jumping ahead on things. Ah, hey Freechie, welcome back. dpk0 moin
Let's see. I have a lot of things on the agenda here on my scratch list. But... And I realize I'm tempting fate. Oh, hello, DPK. I appreciate you filing that GitHub issue about the CSS bug that will never go away. chamlis_ hi!
easeout cheers
If you didn't see my comment there on the issue you just reported, the way we style comments to kind of gray them out causes the comment to gray out and the UI to gray out. But when we float the flag menu over things, gmem_ congrats to the new chat mods :D
css makes it a new layer and either it's invisible and kind of broken or it's not because it's its own oh it's you know it's been 18 months i want to say since i last looked at that bug because we have to solve it like every year and I remember it has, I think the current version of it has a really brittle selector. And so nudging something around in the comments must have broken stuff. Ah, hey, GMam. You're going to come up in a minute. Your pull request is in here. And I was going to talk about that churn. dpk0 the three scoping disciplines ranked from best to worst: lexical, dynamic, CSS
And hello, Shamless and EaseOut. Good to see you all again. I guess if I... It's funny, the Monday streams are a lot more active, and the simplest reason might be because I remember to tweet about them a couple hours beforehand, where the 9 a.m. For me, it's 9 a.m. Thursday one. I'm not always up at 7 a.m. to tweet a couple hours beforehand. Maybe I've got to get one of those scheduling, multi-posting apps. DBK, the three scoping disciplines ranked from best to worst, lexical, dynamic, CSS. Does that make JavaScripts with scoping the absolute best because it kind of encompasses all of them? Because it is lexical and it is sort of dynamic. It's not quite CSS, but JS and CS are such kissing cousins. I feel like it maybe qualifies. Yeah. I think there's like... It's almost a bumper sticker slogan of if you think you can use JavaScript with, you have misunderstood and it's going to bite you. It's such a foot gun. There was, you know, there's that old meme image of the two O'Reilly books, JavaScript, the complete guide, which is like two inches thick and JavaScript, the good parts, which is like a hundred pages long. dpk0 β€˜with’ is banned in strict mode and thus in modular JavaScript!
Well, there is a new, hold on. Let's see if I can find it.

06:08a new edition of not overview it's by thanks school wait is it yeah here we are by meyer and i'm forgetting her name estelle whale so there is a new edition of the meyer whale book and it is 1200 pages long Oh, dpk, I didn't realize with was banned in strict mode. I thought it was just like every linter would yell at you, don't do that. I'm sort of glad to hear it was banned. But there was a... What did I do with my personal browser? I tucked it away.

07:03pushcx https://www.youtube.com/watch?v…
There was a nice interview with... I'll throw it in here. with the two authors and they hold up a copy of the book. And I don't remember where in here. Oh, thanks YouTube. Yeah, the book is literally 1200 pages long. easeout I don't think I even knew about `with`.
And I almost feel like there could be a CSS, the good parts at this point, you know, now that CSS is 20 plus years old, maybe somebody could write the like hundred page CSS, the good parts. easeout there for damn sure could be a css the good parts
You know, even instead of all the different layouts and things, it would just say use grid. Just use grid, save your sanity. Talk about how to do the, oh, I don't remember their name because they're newish. The layouts where you can make nesting contexts, cascade contexts. I forget what they're called. See, that's why we need CSS, the good parts. So DPK, I look forward to your book.

08:13Oh, this is me trying to find stuff for the stream. Ease out for JavaScript with, it was a feature so that you could say with some object and then run code in the context. So what looked like a local variable would actually be a method on the object, but it wasn't quite principled enough. And so it sort of looked like it was really useful, but it had a whole bunch of corner cases around what your scope was actually going to be, and there was no way to use it responsibly. It's sort of just kind of the legendary just a little too clever code feature. I think it's a great example of how difficult it can be to make language features. So GMEM looked ahead. The first thing on my topic list was this diff for our page, lobsters slash chat, that aside from me tidying things up a little bit, we have added two moderators to the chat room, C-Cube or Companion Cube and EBPF or D76D5. Don't ask me what it's short for. I couldn't tell you. Although I did notice, hold on, it's easier on the live view here. So there's the list of operators. And humorously, I'm the only person who uses the same nick on lobsters as on IRC. Everyone else is slightly different. And it's funny, I know for a couple of us, it's just, well, for Hunter here, it's a limitation of IRC that Nix can't start with a number. And I think for at least some of us, it's we've been on IRC forever. Or we've been on lobsters long enough that our usernames have slipped out of sync. easeout just too hard to get the same one everywhere
So anyways, there are folks who both Companion Cube and eBPF have been really helpful for moderating stuff in the chat room. by highlighting stuff to mods as things are going sideways on the site or in the chat room and we've had some increased excuse me excuse me we've had a little increased trolling in the chat room in the last month or so there was one particularly irritating person who just kept coming back because they were just kind of the classical let me pick a fight with everyone kind and It would be, so I was like, you know, oh, we're overdue on adding new mods. I think there is a kind of, I think there is a, I don't have a great metaphor for it. I think of it mostly as a responsibility that I need to keep adding new moderators and training folks up and ensuring that there are enough people involved with the site that we're not super limited on any one person's availability. Because we are, especially on the site for moderators, a little tight right now. And that's a long-term thing, along the lines of the long-term acculturation stuff that has come up many times on streams. Oh, speaking of longer-term things, I released that origin code dpk0 who are the site moderators other than you? πŸ€”
couple of days ago a week i'd have to look at the date to remember but just before the last stream it's been working fine there haven't been there was like one minor production bug that i got a couple of 500s about and then they're off oh who is site monitor is other than me that's a good quick good question so it's linked on the about page right i thought it was higher up it probably should be So our moderator list is public and is... See, I'm trying to find it on the page. dpk0 i couldn’t find it on the page which is why i asked …
I know the URL off the top of my head, but I wanted to... Is it not linked here? Hold on. dpk0 aha
So it's slash users moderators equals one. And so...

13:00okay i'm glad i could show you and it sounds like that's missing or i'm gonna put it in the the notes here that i'm here

...37It is not linked. That must be a bad edit sometime.

...49Yeah, that's just straight up a bug that it's not in there. Why don't I just fix that right now? Because that one is an easy fix, and it's pretty bad that you can't find it.

14:08I'm trying to think where is a great place to put it. I would like to have it high up. Oh, wait. Identities. Oh, I forgot there was an alternate link. Yeah, so slash moderators will take you there. dpk0 ahhh
I forgot that we added that route. That's where I couldn't find the old query-based route. Okay, so it is in there. I just couldn't remember. So dpk... I think you have a good... I think you have a good concern here, though. Like, if you had to ask... Honestly, it should go on the first sentence here, the contact him.

15:07Yeah. Got to get that tab going in the background so that I can take a look at this. I know if I don't read it on the page, I'm not going to see the obvious typo. And then I'm going to ship it and have to fix it. I had an embarrassing typo on that chat page. OK. All right, so that's good. That's an improvement.

16:06All right. So continuing with the interesting meta topics or site news topics, I guess. A couple of weeks ago, 21 days ago, we had a outage when I tried to update to Ubuntu 24.04. Every, what, 18 months, Ubuntu comes out with another long-term service. This one was delayed because of packaging issues that are not worth explaining, but they're linked somewhere down here in the chat. And two of our servers came back up fine, or one of our servers came back up fine, and then the others didn't, which, yeah, me. Actually put something on my post stream list of.

17:04So we were in the very unfortunate situation that The server was up, but didn't know any of its networking info. And any time I tried to run the commands to fetch the new info, it instead totally wiped the networking setup. That was no bueno. A VPS that doesn't know what its IP address is is not really doing a good job of hosting a website. So that was kind of a frustrating couple hour outage, and with some big help from Hunter. This is, by the way, in case you've wondered, this is the hex code for a Hunter green color. See what he does there? So I just a couple of hours ago remembered to come back and update this thread. I got an answer from them more than a couple of days ago i don't have the exact date in front of me but it was responsive and i wanted to be clear that because there was a lot of skeptical actually it's right here that people were pretty skeptical of digital ocean support and when we had the ocean or when we had the outage i noted that i'd had a kind of frustrating experience with digital ocean support before but this actually went pretty well. They really dug in and understood what went wrong, and I was able to get us out of that degraded state we were in by following their explanation. So CloudInit is a script that... easeout clever name.
I mean, yeah, it's basically a big Python script, and when a VPS comes up, it's just a virtual machine, And I had just sort of, if you had asked, I would have just said, oh, they just DHCP to see where they come up. But to even get to that point of, should I look for DHCP or anything? There is this package cloud in it for initializing virtual private servers, basically. And whether or not it's a scalable cloud-shaped thing or a rent an individual server like DigitalOcean kind of thing, they use the same package. And unfortunately, it had a bug. And until DigitalOcean figured it out, I had thought it was a misconfiguration in their hypervisor that when we ran cloud on it, we were just losing all networking. However, it was a bug here. script knows a bit about how various packaging or hosting providers do their networking info. And there was a bug in the one that digital ocean uses. And it was, not especially an interesting one. This one word ADDR was missing. Instead of grabbing these four attributes out and passing them along, it was just leaving out the address. And so this included the important, I know this one is IP and I haven't, tried to read this whole code base because that would actually not be super useful it's not software I'm ever going to be involved in or can change or anything but this was it like one word was missing and so every time cloud and it ran the box ended up with no IP networking That was not a fun outage, but I did want to highlight that it's happily solved. We are out of the degraded state. Should our boxes restart, we will be back up just fine. So that's very nice.

21:09And if there aren't any questions on that, we can jump into pull requests. easeout how do you feel about periodically killing a server to see it come up normally?
And I don't know if... So I did see GMEM was in here in chat, but if any of these other authors are in here in chat, how do I feel about periodically killing a server to see it come up normally? I think that is wonderful in a... Well, I guess a more mature hosting environment. We run on three virtual private servers. We're a little bit over-provisioned because it was easier to just throw RAM at stuff. But at the same time, we don't have any redundancy. easeout not a lot of cushion yeah
So there's one web server, one database server, one chat server. Well, just for the IRC chat bot. And if the chat bot goes down, no big deal. But if the web or database server goes down, there's no redundancy. The site is hard down. Well, if it's the database server, at least Nginx will be up and throwing 500s that are, pushcx https://lobste.rs/s/ndvf0z/2024…
easeout j says hi
some notes on the page that says hey we're maybe we're in the middle of a deploy but that's still not a great situation this did this kind of thing came up in the comments there if you want to read the comments on cloud in it someone had a similar idea of could we have fixed this with like a blue green deployment strategy and the short answer is yes and the long answer is we run on beer money ease out hello to jay i don't know who jay is maybe i don't know who you are and i should know who jay is if you are a person who knows me i can turn off the do not disturb on my phone and peek if you want to throw me a message on signal but otherwise i don't actually recognize your nick to know who jay is so although i can think of like pushcx https://www.youtube.com/watch?v…
nine different people it could be there is of course the excellent song from my generation from mike doughty called 27 jennifers about common names that start with j i got to see him a couple weeks ago soul coughing reunited to do a small tour very great news for our nation's middle-aged slightly hipsters All right. So where I was going with that is if... Ah, he's out. Hello, I recognize you now. Okay. That was my likeliest guess, but didn't put it together. Thank you. So we have a couple of pull requests open that I wanted to run through. And... easeout βœ…
bsandro chikaiLurk
If you are the author of one of those and you would prefer I not talk about them on stream, I can punt till later. Just let me know. I try and ask people beforehand, but it seems that no one is pretty concerned about it. Oh, hey, Bissandro.

24:38And we have... These are actually... A couple of these pull requests are things that have come up recently on stream. So I'm wondering, especially if Eduardo LPZ, if you're here, thank you for jumping in on these. So let's talk about what story disowning is. There is a tension in community sites for people leaving between the individual's right to take off and not be associated with a site anymore, and the site's wanting to remain coherent. So what I mean by this is if we have a whole bunch of comments on a site, imagine we have a tree of comments here, and there's 20 with three or four different people talking. If one person decides to leave and the site allows them to delete all their comments, kind of turns the conversation into swiss cheese so if you go look at for example reddit which does this a lot of old discussions and sometimes even very recent controversial discussions turn into illegible swiss cheese and the community around it has to stand up tons of external services for recovering deleted comments and there's like nine of these on reddit and since the api changes a year and a half or two years ago they're much less reliable but there's a lot of you'll see a ton of comments that are like what did this say what did this person say what happened here that especially gets more complicated because they don't have a public mod log with we do and then on the other side of the fence there are sites like hacker news where I don't believe you can remove comments. And so even if you go back to a conversation that's a couple of years old and fairly contentious, you will still see all of the comments there. It might be possible if you email the mods, a lot of the stuff you can't do directly through the site. If you talk nicely to the mods, they will do stuff for you. So for example, Hacker News does not have the ability to rename your account. And I emailed them once, God, I don't know, 10 years ago, and they were like, no, sorry, you can't. And then I emailed them again five years ago and they were like, yeah, we've kind of got a process for it now. And they renamed my account to PushCX, which is the username I use everywhere now since I got married. dpk0 HN refuses to delete a lot of old stuff as a matter of policy (in a way which is GDPR-noncompliant)
So there's that tension between is the community staying coherent or are we respecting individuals kind of right to be forgotten or be left alone? dpk0 yeah HN actively disrespects the right to be forgotten
And lobsters, before I became the admin, kind of split the difference on it, and it was not super well considered. DPK, yeah, it sounds like you are more familiar than I am. I don't want to speak more confidently than I am, but that's basically my understanding of how they work. So the way we split the baby on lobsters is When a comment is new, for the first couple hours, you can see it in this screenshot, for the first couple hours, you can just click delete on it and it's gone. Because as long as you can edit the comment, it's, you know, sometimes people write something and then they think better of it, or they're like, I just don't want to be involved in this, or I said more than I meant to, or that came out really badly, or I feel foolish because I learned something. You know, whatever the reason is, there's some amount of take backsies that's really healthy. But then once a comment has been up for a certain time, and I want to say it's about six hours, we'd have to look in the comment model to see, but I'm pretty sure this is the same as the, well, it must not be the same as the edit window where I would see it here on this screenshot, right? Oh no, they've made their account a moderator. That's why they have the delete link on someone else's comment. So when someone, after six hours or so on lobsters, is not happy with their comment and wants to be done with it, the delete link changes to a disown link. And if you disown a comment,

29:20We update the user ID to this user called inactive user, which is, this is not a great name. When someone leaves the site, there is an option at the bottom of the settings page that is kind of the, like, I'm done with you checkbox. And you can click the checkbox and say, just disown all of my stories and comments. I'm out. So that one is extreme, but you know, it saves someone the chore of going through and clicking all of them themselves. And it gives people a way to really express displeasure with the sight of the community on their exit if i had it to do over again i would probably change this to like author disowned or something this is a little confusing there was a so someone maybe it's been two or three years ago there was like a minor drama where someone saw disowned comments and they saw it said inactive user and they assumed that the person had been banned no that's kind of added gasoline to the fire so that's why i keep thinking about this coming back to this username is the username is a little misleading but i don't want to break all the links and have to like re-explain everything so i just built out a dpk0 can banned users disown their comments?
profile to try and say what it means yeah and explicitly it does not mean the author was banned so i talked around it but there's a very small missing feature that eduardo has and can banned users to sell their own own comments no because they can't log in there was one user who emailed, gosh, it must be two months ago, where they really wanted their comments disowned. And so I hit the button for them on it. And I added a note in the mod log because it wouldn't have been possible for them to have clicked the button. And so it was like, how did things get into this state? But otherwise, no, it is not possible for individuals. It's also... easeout If I can change my own name on lobsters, and that's cool, how bad is it to change that user's name?
It's also a real iffy one, especially when... The real common thing that happens is if someone is banned or abused for trolling, for spam, and people see this in the mod log immediately when it happens, you know, within minutes often I have a message about it from someone who's curious. then I don't know. With banned users, if they automatically had their comments disowned or could disown, it would make that whole process a little harder. dpk0 i’m often curious about bans but have never been curious enough to send a message :D
And it is hard to want to do things for people who have caused that much stress. So ease out. If you can change your own name on lobsters and that's cool, how bad is it to change the inactive user's name? yeah probably not super bad and i could probably add a redirect for it i just didn't want to have to explain it again because it's weird enough and there are still regular users on the site who don't know why like who don't recognize an active user when they see it Because why would you? Mostly you see that on old comments. And if you're an active user on the site, you can go quite a while with never seeing it if you're only looking at discussions that are a couple hours old. Yeah, DPK, you are welcome to message me or... Oh, gosh. I hesitate to put a number on it, but fairly often when there's a ban, there's some discussion of it in the chat room. Sometimes the banned person shows up to discuss it more or less calmly. So a missing feature was you could disown individual comments, but you couldn't disown individual stories. You could only do it if you were deleting your whole account. And you could reactivate your comment, but obviously that's overkill. And so it's just an oversight that that was missing. So let's take a look at Eduardo's code. There's a bug here, 1331, if anybody is curious to see that write up. And I know this is going to go up and down the code because there's going to have to be some JS, but let's see. It looks like they have done a really nice job of following the pattern for comment disowning.

34:34Grab with post. I'm glad they're using the short ID instead of the integer ID.

...46It's funny. I read this, and I was thinking, I don't know this story, but it's dishonorable by user. I have to look that up. And then I glanced down, and now I see it's a new function. So this is all one of the nice things about Rails is when you are doing a simple CRUD action, things get very short. Yeah, load the user's votes. That makes sense. You want to see that it's still upvoted. This is written in a way that it will only work with JS. And it's specifically this layout false is saying, oh, we're just going to return the section of the page that changed, which is Not everyone has JavaScript enabled. So I think I might want to touch that so that we return the full page if we can. Let's see. Is disownable. Need validated created ad. Is disownable.

36:05I'm not sure I follow this question. If anybody immediately gets it. Oh, yes. Yes, it does. So the comment model they must be linking to is disownable by yes.

...29And this is the is the streaming browser rather than my personal browser that's why i can't just leave a comment all right so we're gonna i'll just leave a comment there and then if we look at the story model do we have a nice constant to point at like i don't think Is there a deletable? Yeah. So in comment, you can delete a comment. And you know, I had said six hours. I was thinking of the edit window. You can actually delete a comment for up to 14 days, looks like. Totally misremembered, excuse me.

37:52And I'm going to, pardon the sudden jump over to light mode. My personal browser, I always keep it that way. Otherwise, it's hard to keep track of these things, you know? So we're going to just review this.

38:40And then otherwise, let's jump back to the diff.

...53Is disownable by?

39:01Why the tab index 0? I don't understand the purpose of that. Let's look at the template real quick.

...18Yeah, that doesn't have tab index.

...27We do have, that's probably invalid to just have tab index zero on everything. So they probably just, copied it from this code. And tabindex is just what order you go through the fields, right?

...52I thought this was, I'm thinking of tabindex as something for forms, make elements focus I don't know why we would want to override this unless equals 0 does something special. First in tab order. -huh. Not tab-able, so.

40:31All of these things are A tags, which are tab-able by default. Should be focusable in sequential keyboard navigation after any positive tabindex values. We don't have any of those.

...52Yeah, I think all of this tabindex is basically dead code You're recommended to only use 0 and negative 1.

41:13easeout sounds like 0 is the default for keyboard-navigable elements
Yeah, that's just what I'm thinking. Some focusable elements have a default tab index of 0. These include A. And if I jump back to my search, all of our uses are A tags. So this is dead code.

...37Let me just hit that.

42:07Oh, actually, there is a second thing.

...15And I can't, what is it going to be? All of the, so I kind of wanted to add disown as a route so it could work without JavaScript. But I glanced down. And I saw, along with the search for tab index, all of our comment disowner works like this, and the comment deleter works like this, and the comment moderator. All of these are JS dependent, and I didn't notice it. So that is something to clean up later. I try not to give pull request contributors big chores like, the other tab indexes. I'm happy to do that. But then also a fixing. I'm not going to ask them to make disown work without JavaScript because if none of these are working without JavaScript, there's, you know, it's a little much to ask them to break the pattern. Okay. Was there anything else here? They added a route. Hey, they added a spec. What a wonderful person.

43:38shows disown does not show an active stories page why not so slash active is our route for oh i think they're just saying that it only shows on an individual story so this this list detail is the name of the partial is reused between story pages and lists of things in stories and i bet this section is this link is only in a section that's only present if you're on an individual story let me just see it here rather than try and see it squeezed into the

44:33So the hide button should always be there. Yeah, so it's the if single story. I see if is disownable. jangomandalorian Hey @pushcx πŸ‘‹πŸΌ . Hi chat!
And here's an example of single story.

...57Oh, hey, Django Mandalorian, welcome back.

45:26Okay.

...57All right. So that's really nice. That's in a great state. Eduardo, if you are here in the chat and you want to make those revisions right away, because they're very quick or they're reasonably small, please put your hand up. I may not remember to check back before the end of the stream, but I would be happy to merge it on stream if you happen to get to it. Let's go over to comment, comment, and remove those extra tag indexes.

46:47Good. And if I have a Rails server up, I have to trigger a request. will not explain that one it's funny the the heinous inline partials i keep alluding to them they're like lurking in the background but they never quite come up enough to be worth diving into on stream there we go so let's let's let's get the terminal back on screen here not thinking Occasionally, so I try to just keep my focus on the section of the screen that y'all can see. Every once in a while, I peek at something off screen. hahamza oh hey pushcx
And then if I do that more than once or twice, I start thinking like, oh, yeah, it's fine. I can just use the terminal that's off screen because I can see it. It's so easy to forget.

47:56hahamza I caught a stream \o/
Ahonza, welcome. You'll have to let me know how you say it if I say it too terribly wrong. And then you'll have to look at the chat log to see what AWS Transcribes makes of it, because I still haven't had a few minutes to look at Shamless's attempt to improve that.

48:28justinhhorner Hello, everyone o/
hahamza ur alright
Hi, Justin. Welcome. Oh, I wonder if I'm featured. We have all of a sudden a bunch of new people. All right. And then I'm going to go ahead and push this just in case Eduardo wants to see those tab indexes. All right. So there's that. Some checks were not successful. So I will leave that for Eduardo, or if they don't want to do linters, that's not a big deal. I can do linting for people. pushcx Can y'all see my terminal still?
So over here in the scratch, is the stream dead?

49:33dpk0 nope, still working
dpk0 yep, can see
jangomandalorian Yes
justcallmedizzy ye
easeout stream is live for me
justinhhorner Yeah all good
easeout I see vim
you all see my terminal i'm getting still working okay then the hi dizzy thank you all right i'm gonna reload the the stream manager ah there it goes okay the okay if you see vim that's great obviously vim is what everybody should see when they're coding all day the i misclicked and jumped over to another tab and i have i have some code in the window manager config to say like hey if you switch tabs try and pause the stream or something and when i came back obs was saying i was streaming but twitch's little dashboard manager had fallen back to the off-air screen and so i just literally you know if the two things are not agreeing i don't know which one i'm not seeing So that is the first of our disappearing trilogy. The other one was one that we saw on stream just on the last stream when I was working on that warning message for origins. So origins were if we're getting stuff from people that says from brand new users submitting new unseen sites and maybe doing bad self promo, we try and nudge them. And we saw that behavior where you can see a form warning. And then if you look at it, or click on it, or change focus, they've even so Eduardo has written up a great solution, I thought it would be something like this. So the basic example of the bug, which we had reported a couple of weeks ago was that if you saw this error trying to submit a story, and then you interacted with the form some more, the error would disappear, which is no good because you can't actually, like in this one, I linked to a longer comment to explain something that doesn't fit in a band message, but you couldn't actually grab the URL, which was pretty frustrating.

51:54I see. So yeah, this was a focus change. Let's take a look at the code change. I think I can get what they are doing. So one of the things the form does to be convenient is if you have the URL field focused, when you fill something in and unfocus it, it tries to send that up to just literally Ajax up to lobsters to say, hey, is this story a dupe? Or is it to a banned domain? Or is there like that warning message to print? But if you already have a warning message and one has been Ajaxed in, when you focus out again, if you should somehow get refocused, that's going to disappear on you. So here's the focus out. Where is this moving? They just deleted the code. Okay, so it looks like we have a correct diagnosis, but not a fix that I want to accept because this is actually very useful code. So what this code does is if your URL ends in PDF, we add the PDF tag. If it links to YouTube or Vimeo, we add the video tag. And then the other thing... Let's see. Yeah. dytomode Shouldn't you also check headers by doing HEAD request?
And then we look for a URL if there's a dupe. This is... Yes, removing functionality removes this. Should I also check headers by doing a head request? We run a Rails backend. Welcome, by the way. So this is all frontend code. So it doesn't need to do a head request. It just needs to grab the server's response for errors. I appreciate them being thorough by realizing that if they removed the only call to checkStoryDuplicate, they could remove the function, but this is not actually useful because I don't want to lose that.

55:03And then what is the, I got to look back. What is the other line of code doing there?

...17So this one grabs the URL and then for each tag, I don't remember what this code is for. If the story URL matches. Oh, it's just implementing the URL tags thing here. I got it, okay. 575.

56:03So they say that, what's going on here?

...45I want them to have immediate feedback that the URL has been seen before. Or expand. dpk0 that commit removed at least some non-redundant tabindex attrs
Because I want to select tags and decide what to write in story text. dpk0 it’s only implicit on a elements if there’s an href attr as well
It removed non-redundant tab index errors. Oh, let me finish this comment, DBK, and I will jump in. But if you want to pull a specific line number... Oh, it's only... Oh.

57:28dpk0 first one i see in the diff :-)
Let's go back to MDN.

...35All right. I'm going to get that open. Let me just finish the thought on this comment. Well, and if we have an A without an href, Either there's an anchor there or something very odd is happening.

58:45dpk0 they should probably also be changed to be button elements in the long run. (i learned this only recently, that a href="#" is considered passΓ©/bad for accessibility/whatever)
You know, I keep saying Ajax because I'm old. It's actually the Fetch API now.

59:35So I am trying to be, and DPK, I see what you're saying. I'm going to come back to that and I just have to finish a thought. dpk0 yep, understood
Otherwise I get very scatterbrained if I get too split up, but I appreciate you catching that. So they've correctly understood what's happening here and I'm trying to encourage them to revise their solution. dytomode Unless you use polyfills to support old IE :D Then it's still ajax
If we were a bigger project that was swamped by stuff, I would be tempted to close this PR, but I don't want to do that because in the same way I don't want to discourage feedback, I don't want to discourage them from taking another run at this, even if it's a false start. I really appreciate them taking a look. All right. So let's go ahead and check off that I've reviewed the 1343. And then I'm going to put tab index here, because if I goofed it up, it's clear.

01:00:59Let's read closer.

01:01:07So data mode, you're correct, but we do not polyfill to support old IE. We actually don't even really use any JavaScript libraries. I think we have one for the nice tag selector that's at use on the story form. And then otherwise, we don't use jQuery or anything else. when we when the site had gotten i don't know eight years after founding i realized you know the browsers are similar enough and things like query selector all are mature enough that we're not really benefiting from having jquery and someone took on the rather sizable job of removing jquery and just extracting the couple of dytomode Do you have some kind of linters or guardrails to prevent people from writing JS with newer ES features?
not extracting the functions we need, but writing equivalents to the couple of functions we needed for error for attaching events and selecting elements. Okay, so DPK has pointed out that this first one doesn't have an href. So data mode, this is Let me get my justification for my answer up before I give you your answer to your question.

01:02:34TomSelect is the name of that library. So here's those common functions I mentioned. We have one for attaching event handlers, on. OnPageLoad is just an even shorter convenience method for a very common thing. And then there's some DOM traversal stuff, like give me the parent of the objects I have selected. A just literally shorter version of querySelector and querySelectorAll. And then we get into DOM manipulation a little bit. There's replace. There's a replace with a little bit of animation. A couple of convenience methods. And then there's stuff that runs on ours. And this whole file is 811 lines long. So given that we have 811 lines of JavaScript, including white space, no, we don't have any linters. We don't have any guardrails. We don't actually have any tests of JavaScript whatsoever. I don't think we even, I don't remember if we even still have a dependency on node. I keep pulling it out and Rails keeps trying to sneak it back in. But maybe with Rails 8 leaning away from uglifiers and minifiers, it will stay removed. I have fought the asset pipeline a lot over the years, and I have especially ended up fighting with Node because it's enough of a pain in the butt keeping our Ruby version and our bundled gems in the right versions, keeping Node in the same version as the develop machine. has also been painful, and this was a lot more painful years ago when Node was newer. It has matured, but it's still just a big dependency and one more moving part to have in. So that does mean we don't have any tests of JavaScript features and they break occasionally. Not so great. Speaking of things that are not so great, dytomode Makes sense. I'm doing one project with Go+JS but to avoid node and node_modules I used esbuild binary that is also written in Go so easy to install on same project.
The pattern here that DPK has pointed out and that Daitomode has pointed out is, well, no, DPK also pointed out that it is old. So this href equals anchor is a very old JavaScript style. So you're doing go in JavaScript, but avoid node and node modules. I can totally see why you would try to keep your dependencies down. Yeah. If you just have a little bit of JavaScript, just keep it as a text file. And our JavaScript, we don't add to it very much. We don't touch it very much. If we had more churn in the JavaScript or more breakage or more features, I would bite the bullet and add an opinionated linter like standard RB. I think standard RB is inspired by just standard in JavaScript, right? And then I would add some tests. But as it is, we keep being not quite there where it seems worth it. Because I feel like I would end up spending more time debugging the dependency than I would debugging my own code.

01:06:14So this pattern of an a tag without a link, because we're adding JavaScript to it, and then the older version of just having an href with an anchor tag is very old code. It feels like the href equals anchors is very 2003 to me. And we figured out pretty quick that it was a bad idea about 20 years ago. But it's a whole bunch of the fix is not small. So the proper fix would be make sure there is a link here and make sure that you can click this without JavaScript because occasionally a browser fails to load it or People have it disabled. That's unusually popular in our user base. Or people are using very uncommon browsers like, you know, I don't know their feature sets well enough to say if they have JavaScript, but things like links and net positive and literally homebrew browsers. So I would like most site functionality, if not all site functionality, or at least all user functionality. I'm OK with requiring the mods to have JavaScript. I feel like there's few enough of us that I can yell at us. dytomode surf is the browser I use sometimes. It's terminal based and usually doesn't work great on modern sites.
But users, it would be nice if the whole site worked without. And this does not work if you don't have JavaScript. You just end up focusing on the comment. And so DPK, I really appreciate. Surf, it's terminal-based. Oh, I don't know surf browser. Hold on. Let me put that on my list. If you have a link. dytomode It's from suckless
I do a lot of stuff, as you can guess by the fact that the stream is mostly Vim. I do a lot of stuff in terminal and over SSH connections. It's from Suckless. Ah, there's a familiar name. That's enough to find it. Surf is a pretty generic word for a browser.

01:08:34So I think I'm just going to add the tab index back to the one anchor that doesn't have an href because the right way fix is bigger than I want to get to on stream. I will put it in the notes for later. And I understand the idea of Making these buttons.

01:09:10And I have even did this because I was playing with making a new rails APP because I wanted to play with hot wire and turbo and bullet train but. So I've played with styling buttons to look like anchors and styling anchors to look like buttons. And I love how easy browsers make that nowadays. Yeah. But I think these should stay links. dpk0 i see two of them which are basically the same, one in app/views/comments/_comment.html.erb and the other in app/views/comments/_threads.html.erb
And I will file an issue to make

...57Yeah, so dpk, what you're seeing dpk0 on GH
is you're clearly, do you have the code base locally or are you browsing GitHub? I'm asking because it's gonna say how easy this is. GitHub, well then let's just, I'll grab the link here. There is a SYN in the code base. dpk0 😱
And like all good sins, it is for performance. Where did I hide it?

01:10:42Oh, well, if you already have that emoji, maybe you skipped ahead. Can I even spell heinous?

...55It's called the inline, right? I'm not signed in. All right. I will switch browsers. Google, GitHub. I wonder if that's an always thing or if they're just busy right now. Because I feel like sometimes I can search when I'm not logged in. So heinous inline partial. Let's bring that code up. Actually, let's bring it up here. pushcx https://github.com/lobsters/lob…
I was going through all this to link it. Let's jump back up to master. Heinous inline partial has been lurking in the background since like the first stream. But the gist of it is there is a overhead to calling a partial. dpk0 did i discover an easter egg in the Lobsters stream?
And on our comment pages, we have the comment partial, the one that we were just in. And we might render that 100 times. And the overhead of starting a new partial, it's not an Easter egg. It's just a thing that keeps coming up because it goes by or we see the server log output about it. We can't really do the render collection. So anybody who's familiar with Rails performance stuff is going to immediately say render collection. There is a kind of an item potence mismatch between our markup and the ability to do that because comments are nested. If they were a linear list of comments, we could render collection. But we need to render things in between. We need to render the open li or the open ul tags and then the close for those. And the code for that is fairly hairy. But it means that the top level thread, let's go look at that. Did not expect to get into this one on stream, but you're clearly very curious about it. And you've been really a helpful community member in the chat and on the site, especially lately. I saw you this morning in the surely totally calm and rational thread about the Free Software Foundation that's at the top of the homepage. dpk0 it’s a very calm and very normal thread indeed
So here's that code to manage the OLs and the LIs. That's as we're looping over all of these comments, which ones are indented children and which one are not. And then at the end, we have to do the inverse and recognize if we are coming from children here it is if we are coming from children back up to the parents at the end we also have to print those closing tags and this is totally sane and reliable code that doesn't break every time i look at it funny right so the contents here from what is this line 34 down to 198 this is that comments html heinous inline partial and i gave it that name so people know to be a little scared of it is a little bit of rails plugin that when the server boots or in development mode when it sees requests it goes and it gets this comment HTML template and it copies and pastes it into this one, replacing the text that's here. So the edits that I make to comment.html.erb get copied into this file. So if we go down to that here, I believe this is the link. Let's view it.

01:15:23If yeah, so you can see these are let's line them up. These are the same template. So over here, I have changed tab index to say zero. And the heinous thing is it has not yet gotten updated because I haven't loaded a page on the development server. So that's why the other minute I like started the rail server in the background and open this tab. So if I reload this, And then I come back to my editor and I edit this page again. Look what just came over. Now the tab index has been over. easeout so it's an #include, but done at runtime on request?
So a very calm and very normal feature that edits code out from under you when you load pages. I understand. easeout spicy
how dangerous and frustrating this is because it is, yes, it is an include that happens, well, in development mode, it happens at runtime. In production mode, it happens once at startup. And that is also part of its heinosity because it's different between dev and production. I swear the performance improvement is worth it. I promise. Please believe me. It is significant because the setup and teardown to render an individual partial is fine, is cheap, but when we have a 50, 100, 150 comment thread, it adds up. It also reduces GC pressure, but in a totally unprincipled and indefensible way, I did not attempt to measure that. I got enough of a performance when that I was happy with it and I didn't measure GC pressure, even though that is probably I mean as we saw with the. The whole memory leak allocator incident on stream with not incident but investigation with by route weeks ago that was a fun stream if you haven't seen that one in the archive. site does like all rails app deal with memory pressure and there's more if you render partials than if you just do things straight so that is that is the deep dive into heinous inline partial and i wouldn't do it if it wasn't like one of our god objects on our hot path on our most frequent thing is viewing a list of stories it's It is every hot button issue. And so I thought the performance improvement was worth it. And only about, only about twice a year do I end up editing this file and then seeing my changes disappear and then, you know, yell at the sky and feel like I stepped on a rake of my own devising. There we go.

01:18:33So let's just put back that one tab index. And I'll file an issue to do these properly. And maybe some console will take it on, but maybe I will do it. So I tried to skate over a TPK, but you didn't let me. easeout so that's what that rake's doing there
And this is why I edited one file and two files changed.

01:19:08Yep, that's what that rake is doing there. There is a comment at the top of the heinous inline partial about it. And I added logging, so you will occasionally, if you see my Rails server output, whenever the server boots, it prints a like, hey, I'm doing this awful thing warning. It's worth it. We also do it on the list detail. It is less performant because there are only 25 of them. per page, we've list 25 stories per page on the homepage, the search index, other various places. So the value of that is less, but again, it's such hot path and I already wrote the evil code, so why not use the evil?

01:20:11And if I had a Twitch API key, I would make it so we could vote on silly titles. Where'd we go? All right. So there's a fix. So unless there's anything else on tab indexes or committing sins in the name of performance, I am going to jump back to pull requests. Let's give it a second. So yeah, you can see. Oh, why did I split that up into a different file? Oh, because it's hard to hook the controller. easeout βœ“ rake in the lake
If I had said class action, this runs before the controllers get loaded. So rake in the lake. What is the lake?

01:21:25dpk0 not as bad as some cases where effectively build scripts. Chez Scheme still has all those boot files in the repo from when you needed to regenerate all the platform-specific blobs every time you changed the runtime, so people would be able to do the bootstrap when installing the compiler. so you have to remember to --filter=blob:none when cloning or you download all of those gigabytes of files from many many commits (which are now useless since there’s a portable bytecode bootstrap system)
Yeah. dpk0 *where effectively build scripts’ output gets committed
Yeah, I don't usually commit debug code, but the debugging this is such a nightmare that I wanted to keep it easy. All right, TPK, I'm reading your long message. Not as bad as some cases where effectively build scripts. Yeah, it is a sort of build script. That's fair. SheaScream has all those boot files in the repo. I do not know Shea's scheme. Shea? When you need to regenerate all the platforms. Huh.

01:22:04Yeah, I see where you're going there. Yeah, and in part because of how it works by interpolating into the middle of a file that has new custom code above and below it, if that threads HTML-ERB could be just... It seemed better to commit that file than to make a template for a template. then interpolate the comment in it so that the thread's html erb was like git ignored that just seemed so just running erb twice kind of seemed a little wild it doesn't actually use erb in this substitution it just string replaces it because otherwise I would have to add a layer of escaping to templating. I don't know. I was trying to make this fairly obvious and fairly hard to get wrong and very easy to delete so that dpk0 on the other hand, one of my projects includes an ISBN formatter, which depends on an irregularly-updated data file published by the ISO. so the build/install script downloads it with curl, and occasionally one of the tests that’s supposed to test unassigned ISBN prefixes breaks because the example unassigned prefix gets assigned. should probably use a frozen version of the file for the tests, but that project is in maintenance mode now
should the way rails handles partials change or they have some kind of cache so if you are rendering the same partial over and over it just keeps that in memory instead of having to you know build the whole object graph again like that would eat most of this speed up i wanted to make this very easy to delete all right there actually is it's not original i don't know who i'm coding but someone who writes about code quality and refactor during maybe it was sandy metz has said that if you write code with an eye towards how easy it will be to delete it you will end up with very well factored code And I'm surely nowhere near the actual wording of that quote, but that's the actual sentiment of it. If anybody remembers that one, please link it. But I do think that pushes designs in a pretty good way. easeout nice, I'd like to find that source
So one of your projects includes an ISBN formatter, which depends on an irregularly updated data file published by the ISO. Sure, is that a list of prefixes owned by which publisher? So the build install downloads it. occasionally one of the tests that's supposed to test unassigned breaks. Cause the, ah, yeah, I see exactly. Yeah. You know, sometimes people say that software engineering is not engineering, but I think a big chunk of engineering, like civil engineering and mechanical engineering is figuring out where you can cut corners to save money and where it is appropriate to skimp on quality. And as a programmer, I skip on quality all the time. easeout software work is highly concerned with practical knowhow
For a more serious take on how programmers are engineers, Hillel Wayne has a very nice, I think it's an article series,

01:25:37easeout when that's all you consider, it is the worse for it, but.
pushcx https://github.com/lobsters/lob…
all right so coming back to the scratch for a second so that was tab index that led into heinous inline partial so the next pr to review is 1342 i'll just throw the link in the chat to make it easy Yeah, he's out. That's a good point.

01:26:13So there is a bug. Humorously enough, the bug was created by some performance code. What a thematic transition.

...29There is performance code to avoid one plus n queries in the code base very generally. And somewhere deep in the story previewing that does a little bit of black magic to map tags from HTML input text to nice UI to post variables onto the model and back out. There are like seven layers of different data structures for story tags. That's how it goes with the got objects. Oh, they must have revised. This isn't the bug. I thought it was going to be the bug. Ah, here we are. So the bug is that if you fill in a story and you fill in tags and you click preview, you get a preview. It's off screen here, but then your tags get forgotten. And it's a hairy one because there are so many layers of abstraction here. Ah, yeah. So I mentioned there were multiple layers. I wish story tags would just work on save stories. Yeah. So one of the layers is that tags are active record models. And so story has many tags through the taggings table, which means that on a unpersisted story, a new story, and sort of also unedited story, you can't really use the association. So this is going to be an interesting one to review because the two commits are independent from each other. I left them this way if you prefer to apply the first without the questionable approach of the second. Well, Or do I love questionable approaches to things, as people saw in the heinous inline partial, which was a questionable approach to performance? OK.

01:28:50So with this change, starting the server also changes the files.

01:29:00How funny. They have noticed heinous inline partial working.

...39All right, there we go.

01:30:23Anybody in the IRC channel? Yeah, I just peaked. So the IRC channel, the main Lobster's chat, is pretty busy today because of a totally calm and normal morning. So remember tags when previewing a story. And you know, I'm joking about that, but if anybody seriously wants to talk about it, we can. Either of those stories or what the site policies are, the basic bit of it is Yes, there are very difficult and contentious social issues in programming. Some of them are appropriate for the site. Some are not. When they feel more like brigading, there isn't a great line between the two things. An article was submitted this morning that the two exciting things are, one is someone... reigniting the criticism of Richard Stallman, who heads the Free Software Foundation. And then the other one is a whole bunch of stuff going on with WordPress, which only runs 40% of the web. And while we try and keep lobsters a pretty chill place, people disagree pretty strongly on the various issues and actions involved. We'll see how it goes.

01:31:55albynton Hello!
I mentioned it in the chat room, but I have a comment a couple of years ago that I've been thinking about a bunch this morning that while I wish we could, we kind of all wish we could just have like abstract debates about the principles that did not involve people getting mad at each other. The way humans, oh, hey, Elbington, welcome back. The way humans handle these kinds of what should our social norms be, what's acceptable and unacceptable behavior is we kind of figure it out by lurching from crisis to crisis. It's just how everything works, it seems. So no utopia, unfortunately, but hopefully a reasonably okay place. And there is story hiding if you want to tap out on it. I wonder if I should just, I'm gonna go through these two commits separately. If the pdomain is talking about them very separately. And I also wanna read the commit message which the diff doesn't show. So tags a, so I've mentioned that there's like seven levels. So let me say what's going on here. So we have, the browser input element, which is text.

01:33:25Let's make a little section.

...34And then on top of that, we have TomSelect for better UI. And then we serialize to post. And then the controller d serializes to a Ruby array. dpk0 there is one guy in the Stallman thread pulling a repeated motte-and-bailey trick
And then story has tags a, which is a, is it? Yeah, it's an array of strings. And then that becomes the story. There's a guy in the Stallman thread. Repeated trick. I'll go peek. So you're going to hear me type off stream a second because, well, I think this has definitely made it as the most flagged story in Lobster's history. Super. So I'm scrolling it off screen because the moderator view has a ton of extra info, like who has flagged what.

01:35:18OK, I'm not going to, since I'm kind of distracted by stream, it doesn't look like there's anything that is super on fire.

...43dpk0 okay
DPK, if you want to throw me your thoughts on IRC, just please go ahead and message me. I'd appreciate hearing more of what you're thinking there. So the story tags. And lest anyone think I am being totally reckless, the other moderators are all awake and keeping half an eye on the site because we have noticed that there's two spicy threads happening right now. We are going to talk around that second one a little more In a minute.

01:36:49So what's happening is I'm kind of put that on top. So this is roughly like in order of abstractions in the order from UI to storage and Previewing starts out here and it goes down to tags A and then it tries to render that, but the rendering stuff wants to fetch a record out of the database, is my guess at part of what's happening in this bug. And there are so many levels that debugging this is a little... It's hard to know exactly which level things are going wrong at. Let me grab this over this way. I'm trying to... Trying to check something with all the off-stream fun.

01:38:55easeout I found a couple of posts that might be the source for your "easy to delete code" note. guessing this is the one https://programmingisterrible.c…
You found my oh you found quotes for making things easy to delete ah. Thank you ease out for for digging around on that. let's make this bigger.

01:39:23easeout Wonder if this rings a bell
I've seen this article before in case anyone is imagining that I'm a speed reader. easeout nice
Yeah, I think this is the article that I am thinking of that it's about practices. The other one I'm thinking of is, so I'm going to bring your link in here.

...59If you are dpk0 raganwald?
easeout Another post said Sandi Metz mentions it in her talk The Wrong Abstraction
a googling mood assuming google still works anymore instead of just giving ai snippets there is an author named reginald braithwaite and i don't remember the name of his blog because it's been 15 years but he did he wrote this kind of parable that was about someone organizing their code by functionality and doing easeout Excuse me that's not the name of the talk
really doing almost everything by monkey patching and it was an interesting thought experiment another post said sandy metz mentioned it in her talk the wrong abstraction dragonwald is the blog i'm thinking of yes dbk thank you i'm not going to google for that that's going to be painful but yeah so raganwald we'll just note it here

01:41:18Really, was it... It was monkey... Don't need to wrap it. Or it was about aspect-oriented programming, which is one of those you don't hear much about anymore. It was an interesting experiment in the 90s, but it was not super maintainable.

01:42:07So if somebody finds it, great. I'll throw a link in. If not, no big deal. Where was I? Not in heinous inline partial. Previewing. So previewing has all of those layers to jump through. And tagsA is the one that's in the model, but not using all of the active record model associations.

01:43:01easeout Anyway, I found the reference to both the above post and a Sandi Metz talk here. https://www.pretzer.io/professi…
How would this work? So if we grab all the tag objects that are not on taggings that are marked for destruction, and we grab just their ID, how could we pluck a tag off of them? Let's take the tag record. You found a reference to the above post. All right. Izad, I appreciate you doing this.

...39Yeah, this is familiar. Well, this one, maybe they changed layout. I don't think I've seen this article before, but it's definitely hitting the exact topic. So we'll throw it in Scratch. For anybody who's viewing for the first time, I have that Scratch file. It goes into the archives. The link is under the video on Twitch. Typically, I have archive pages up for streams. I don't know. Depending on how fast my upload wants to be, which is depending how much it's raining, those are usually up an hour or two after stream.

01:44:28So I don't see how this can work, because if we map to a tag ID, which is the individual See, it says tag ID, but I'm really confused by this code. Because it says tag, but we're filtering by taggings, which is the join. And then we're getting just the tag ID, which is the name of the field on the join.

01:45:12Let's see how that can work. I can't imagine this one in my head. easeout The map is within the where, so .pluck does not see the id alone
I like this test. If this test doesn't pass now, the map is within the where, so pluck does not see the ID alone.

...45Oh, I see what you're saying. easeout It's, tags where a tag's id is this tag I got by mapping
Yeah, so that's why they didn't break the line here. Yeah, so we're saying where ID is in on these. And this one, you know, it says map, but this could also just be a pluck, except pluck only works, I think, if you go and hit the database. We just have an association of objects. So there's one more layer of this of... Active record objects act a little bit differently if they're actually persistent to the database. Hmm. It's tags where a tags ID is in this tag I got by mapping. Yeah. A temporary variable would probably clear this up a little, but I understand why the memoization doesn't include it. dpk0 apropos of nothing: i have to go and sleep soon so now isn’t the time, if this were even on topic for this stream, but i would love to hear about the worker co-op you are setting up for your recheck project
If we had decorators in Ruby, this would be easy to include a variable for. So the thing I'm really curious about is this test.

01:46:54You'd love to hear about the worker co-op that I'm setting up for my recheck project. It's not super lobsters related, but hey, the stream is my username, not just lobsters. I know I kind of had it for years on Twitch. I would be happy to talk about that. We could come back and handle that on the Thursday stream or the next Monday stream, depending on your personal schedule and time zone. I'm happy to talk you to death a bit. I went to... So here in the U.S., there is a national... What are they called? dpk0 always happy to see co-op projects in technology!
The United States Federation of Worker Co-ops? USFCW? US... It's like wrestling. URS Federation of Worker Co-ops. easeout us wrestling football club.
And they just had their meeting here in Chicago maybe a month ago. And I went because I'm starting a co-op. The very short version of it is... it's a company like any other except instead of investors and possibly other people but primarily investors owning shares in a company that divide up who owns the company in a worker-owned co-op there are a few ways you can set it up but basically only the workers or the majority of the shares have to be owned by the workers and I am yeah if I start talking about it i'm going to go for a while and I don't need to keep you up but drop me a line on irc and we'll talk about when i'll jump into it on stream because i'm happy to.

01:49:06So what I want to do is. run this test in the console because. The setup implies that it wouldn't work now, just the general context. I'm super curious about that. So if we have a story with the tags of an empty array and we set, yeah, that's fine. Okay, so they just added this test to make sure that they didn't break functionality.

...59I was gonna be very surprised. if that didn't work. So we say grab the tags.

01:50:14I know I occasionally go through gyrations for active record, but I feel like there must be a cleaner way to represent that. But on the other hand, had enough pain with the disassociation and the various levels of persistence that maybe that's it all right now externalized

...58Loads all tags names.

01:51:06Does anybody follow what they're saying here? Story tags A equals.

...15Nukes the memoized. They're not. Oh, down here, the tags A equals. Okay. Oh, gosh. If the assigner tagsA equals didn't have this line, and it didn't until now, that certainly explains some of the pain I've had before with these objects where they don't quite persist properly. So, man, even if there wasn't anything else, this one line of code would make this pull request worth it.

01:52:04dpk0 hahaha rms supporters are now squatting a similar domain to the one where the β€˜report’ is hosted, and redirecting it to their rms fan club site. very calm, very normal day where very normal people are doing very normal things
And this commit is missing. Did they rewrite it and it's down here? I guess.

...17And they force pushed 12 minutes ago. Epitomain, are you here in the chat right now? I don't spot your username. It doesn't...

...54This is... mildly heinous.

01:53:14Let me grab the shot one for this. Heinous inline partial is biting other people. So it was... I know what this code was. Someone recently committed a fix for Not a fix, a name.

01:54:18dpk0 righto, i’m off. i’ll see about Thursday. i start a new €€€ job this week (alas, not a co-op, though a small cool company that almost exclusively does free software stuff!), so i have to learn by experience how working hours fit with stuff (since even if i could technically make it, i might be too tired after work to hang out, etc. etc.)
Well, DPK, good luck with your new job. Congrats. dytomode Any good recommendations of resources for learning Ruby? I am planning building SDK for one devtool to also support Ruby but I have zero idea how to go about it.
I hope you have a good start. And if you want to ask about worker co-ops, honestly, we don't have to schedule anything. Just drop by whenever. dpk0 thank you :-) okay, will do
easeout good luck FutureMan
Do I have good recommendations for learning Ruby? You're planning on building an SDK? My... You've been talking like you're an experienced programmer, Dido, so I will just suggest the book The Well Grounded Rubyist.

...55pushcx https://www.manning.com/books/t…
It's my go-to reference for programmers who want to pick up Ruby, and it talks about... It assumes you know how to program, and... It talks through the language features in a very nice and interesting way. Yeah. Is this only Ruby 2.5? Is there not a fourth edition? Maybe it is slipping a little out of date. Darn. So 2.5 is a couple of years old. 3.1 and 2 added some small but nice language features. dytomode Yep, I'm programming for over 10 years. But mostly Go, Java, Python
I don't think this is so far behind that you'd be misled by anything here. There's just a handful of new features that are worth finding nice things. You know, find new features in Ruby 3.0, 3.1, 3.2, and you'll be all set. dytomode Ok, thanks, added to my notes. Thanks!
justinhhorner Another book recommendation: Programming Ruby 3.3 from PragProg. I'm going through it now and have learned a lot already.
But I really enjoy that book. All right, so let's add that missing line of code. Oh, Justin, you are probably more up to date. I don't think I've read the pick act books in a long while.

01:56:44justinhhorner Yeah it does
don't remember so justin is that book has a pickaxe on the cover right that's the pickaxe books and i don't remember if it's aimed at beginning programmers yeah okay so that's the the pickaxe books that's right it was just updated by somebody famous i'm blanking on and

01:57:20It's quite good. easeout it's a far cry from the beginner focus of _why's guide
I don't remember if it's one of those books that's like, let's introduce you to this programming language. This is a variable. A variable is something you can change. I kind of can't read that level of intro book, even if it's a language I'm learning anymore. Far cry from the beginner focus of Wiseguide. Yeah, I saw someone recommend Wise in a conversation just a couple of weeks ago, and I I checked my first impulse to leap across the table yelling no, and I just kind of politely came in to give a different suggestion. easeout it's fun and all but chunky bacon is distracting
dytomode Yeah, I usually fine jumping into a different language quickly. But would be great to learn idioms and some practices.
Wiseguide is wonderful and charming and whimsical and very out of date and not super useful for experienced programmers. It's a great artifact, but I wouldn't point someone to it right anymore. Yeah, it has a lot of personality, ease out. And that is both a benefit and a curse. So yeah, for idioms and practices, I like well-grounded Rubyist a little bit more than I do the pick act books that Justin is recommending. But, you know, given that it's up to date, maybe Justin's suggestion is better. Why don't you start there?

01:59:04justinhhorner I'm just now picking up Ruby so I can start working in Rails. Pretty stoked about it.
Now I am reloading the dev server so that I get extra updates. There's heinous inline partial working. Oh, Justin, welcome to Rails. It's funny to realize that Rails has been out for 20 years now. Someone could have a whole programming career that was just Rails. It's wild to me. Let's say I lost the one.

02:00:05So there's that fix. And I'm going to push it, because clearly this developer is around right now. If they are responding to stuff, even if they're not here on the stream.

...25Hmm.

...33dytomode I met the guy who is still coding PHP 5.6 for 10 years. I pitty that guy :D
So we have, if we're previewing, so I talked about how there are those many layers where story tags are, because tagging is an association record that has the tag ID and the story ID. Well, if the story isn't persisted, you can't have a tagging. You sort of can, but you can't really, because as soon as you try and access one of those fields in a way the code does all the time, like ask for its tag ID or really ask for its story ID, it'll break in surprising ways. I talked on stream maybe a week ago about wanting to have a feature that would store submitted stories in kind of a, well, I concluded it's got to be some kind of like JSON serialization rather than A table because of this kind of complexity of you can't store join records until you know ids. anyways layers of abstraction all leak. We live in a fallen world. This is. This is probably fine.

02:02:24So story previewing is a pretty core feature, and I've been bothered that it's been broken for a minute.

...37frici PHP 5.6 for 10 years sounds like a rough time but at least it's job security for 2 people. The programmer and their Psych.
And I think I'm willing to accept a slightly weird way of solving this. Someone coding PHP 5.6 for 10 years. Oof, that's rough. So, yeah.

02:03:10My professional career mostly started with PHP. And this was back in the... PHP 3 was new. I still occasionally saw... What was it? Two... two points something maybe 2.4 and then it went to three i don't remember the exact numbers anymore now that it's been 25 years or so but three was a an improvement and then four was big and five was big yeah there's a nice clear commit message So when someone goes in the blame to find out what this is about.

02:04:11Yeah, I would bike shed this message a little bit, but I don't want to make them incorporate. So if this is good, I'm just going to take it. Yeah. Okay.

02:05:30Yeah, there's really not much more to say.

...39Let's keep an eye on this. So now is a great time to ask any questions. If anybody has questions about the code or the site or anything, we're going to wait for this build. And when the build succeeds, fingers crossed, knock on wood, I will take a second to merge down that pull request. Ah, and just as fast as I say it, yeah, the couple of lines are saying it succeeded. So just rebase them. That's fine.

02:06:18Great. All right. So following along on the scorecard here in the scratch file, that was the third pull request to review. And we are, because of digressions into heinous online partial, way behind where I want it to be. But that's OK. These pull requests are really important. So ease out. You have been in Ruby for a minute, if you remember why. And chunky bacon. All right. Next up, we have a pull request for fixing CSS. We were talking about CSS earlier on the stream. So there is a bug reported by Kay Connor If anyone doesn't recognize their username, they are the person who added dark mode to the site. So they have literally painted the bike shed. Well, no, I guess that's still figurative. There isn't a physical bike shed, but you know where I'm going. And Mobile Safari, the TLDR of the bug is Mobile Safari has odd opinions. spent a while just this last week i'm sighing about mobile sorry safari because i spent a while conspicuously this screenshot where there are 21 comments does not have a scroll bar because i don't know apple decided that understanding how long a page is is decadence or is a distraction from interacting with the thing i guess and then for a while they had a way to work around it with very browser-specific CSS, and then they deliberately broke it because they didn't like that people were adding scrollbars to things. And so instead, pages, even on Noun Safari, add those irritating horizontal scrollbars because scrollbars are actually super useful. So, me ranting a little about scrollbars aside, There is an odd behavior about font sizes and Kay Connor has been basically right about CSS all of the time that they have chosen to talk about CSS on the site. So I'm going to skim their article, but I'm really tempted to just merge the PR directly because they know their shit. yeah so the the feature that's happening is trying to improve websites for mobile and especially the experience of what happens when you rotate your device and basically Since Safari picked up this behavior, smartphones took over the world and the web, and now everyone codes... Most everyone codes mobile first. easeout well I know more about css than ruby LUL
dytomode tbh, Safari is new IE.
And so the behavior is maybe not so needed anymore. Yeah.

02:10:13Oh, Dido with the spicy take.

...36All right, so let's go look at the pull request.

...54Portrait. OK, portrait didn't change, so we can go pretty fast. OK. This is going to be just a couple lines of CSS.

02:11:21Is it Phones or is it Safari? frici is Safari really all that bad these days ?
I think it's just Safari does this.

...31They added a comment saying, easeout I think the article said Firefox also did it? Don't remember
force a vertical scroll bar to avoid page shifting how i wish that it worked so i try not to nitpick these things but if this is does firefox also do it because otherwise i'm gonna nitpick and try and get them to change it to say fire say mobile safari

02:12:11dytomode Had to port browser extension for Safari on MacOS few years back. They changed 3 times how browser extensions should be published. From web extension > native app > web extension + native app
easeout I just scooted the comment inside to go with the particular property, since I split the class to having two reasons to exist
So there is a note to make sure that this code works in Firefox.

...37I think this is just Mobile Safari. But then they mentioned Chromium and Firefox. All right, I don't know. Boy, do I not want to try and dig out devices and emulators to test that.

02:13:01All right, great. My favorite thing of a pull request that I can just merge.

...27And so with that merged, this bug should close. Great. Huh. Funny to see two of them. I wonder if that'll still be there if I reload. Yep, that's a strange one, GitHub. easeout Happy to scratch my own itch :)
I would have expected just one for the pull request rather than one for the PR and its commit. Oh, it's because I rebased, right?

...55Great. Yeah, so ease out as long as you're saying it. I didn't know if you are using a different NIC from... Okay, Connor, on purpose, so I didn't want to call you out, but yes, hello, ease out if anyone would like to directly thank ease out for adding dark mode and fixing this bug and other, I think, feel like there have been other CSS issues. Thank you. dytomode @easeout Thanks for dark mode! My eyes thank you a lot!
easeout oh no there's just no way I could grab "kevinc" or "kconner" on as big a platform as twitch.
So let me bring the scratch up because that is the not at all disappearing related. dytomode :D
And then this pull request, I don't think GMM is here. Ah, there's just no way you could grab Kevin C or Kay Connor on Twitch. Yeah, that's one value of doing push CX. I did Harkins for a while because I was early enough to the web that I could just be Harkins. frici Right yes my eyes are very glad for your work LUL @easeout
But that stopped working. I also used Malaprop for a while. And again, I was early, but that stopped working. And then I got married, so I couldn't use Harkins. So that's where PushCX came in was. It's weird enough that nobody has used it. Although I think on Hacker News, I saw somebody who was like PushAX and I was like, how dare you? Maybe they were PopAX or EAX. They were somewhere in the neighborhood. easeout πŸ™‡
And I felt like someone had copped my fashion, you know, like in Zoolander. All right. So this one turn for the next thing i'm going to check it off, because I just wanted to talk about this. GMM if you're here, you can say hi I know, sometimes you come by these streams and I believe this is still a work in progress. or it was. A half an hour before the stream when I last looked at it. But. Lobsters has a mailing list mode. And if you would like to leave comments, well, you can subscribe to get news stories and subscribe to get comments by email. And you can also respond to those comments to get emails. And since Lobster started a dozen years ago, Rails has added a feature called Action Mailbox that is specifically for, I want my web app to read email. justinhhorner Appreciate the contributions @easeout! I just learned about lobste.rs today and already benefiting from dark mode.
I think their canonical use case was you're going to send transaction emails like hey here's your password reset or Jim has replied to your note on Basecamp and then I gotta find a are there no pushcx <3
How wild I assumed that a twitch would have some. Like a heart emoji I could use oh there we go there's a purple one. Alright, much love for ease out. So our code that takes incoming emails and turns it into comment replies is. is hard to keep working. easeout all these compliments, and breakfast too!
And if you want to see it, you can look in the lobsters Ansible repo, hop up to lobsters, dig around in lobsters Ansible. But the gist of it is we're using post fix to accept incoming messages and have a dot forward file that pipes into calling the rails script. And it's a whole bunch of moving parts. And if you look too hard at it or we rebuild a server, it breaks. And then the couple of people who use mailing list mode get pretty grumpy about it because it's super frustrating to lose. So one of the themes for Lobster is the last, I don't know, five or six years I've been maintaining it has been let's lean on Rails more because Rails has added more features and fixes for things that we have had to custom build. So we have been slowly replacing our custom things with Rails. And so I filed an issue to say, hey, would somebody like to use Action Mailbox and GMEM, ah, Gabriel Simmer. has popped up to start it. And I wanted to mention the churn because Action Mailbox requires the use of Active Storage, which is another new to us Rails feature that we don't use. So Action Mailbox is for taking in incoming emails. Active Storage is a general purpose file storage solution, especially for uploads. Rails has had a lot of popular upload plugins a little across the years. It's kind of like background job queues where like every two or three years there was a new hotness. I think the last one I remember was Paperclip and then I haven't worked on a Rails app that had file uploads for, God, six years. So GMM went ahead and added active storage Over the weekend, I realized it would be great to have Active Storage set up earlier separate from this PR so that we could support users uploading avatars. And all of this is a long way to talk about the game that we are all going to play.

02:20:20pushcx https://tvtropes.org/pmwiki/pmw…
So there's a TV Tropes page here for anyone who would like to waste an hour or two. about the trope of, oh, here we go. There's dark mode. The TV trope for this idea of say their name and they appear, you know, like Candyman or Bloody Mary, or I mean, I think Satan or the Fae or the old school ones, but you know, it's kind of a recurring thing in fiction. It is also a recurring thing on the web. So I would, without anyone saying proper nouns, that's the game. I would appreciate, especially ARH68, if you are here, I know a couple of times you have jumped ahead on stories because you figure out where I'm going. Let's do it without proper nouns. we have avatars on the site they appear on users profiles and users comments and they use a third-party service so let's go here let's just grab a random user and so they have a little profile image this is one of the automatically generated ones and so in the pronoun game or in the proper noun game we are not going to say the name of this service and especially not the name of the company that owns it and especially not the name of the really rich guy who owns that company and is having a very litigious couple of weeks because so here's a custom avatar because someone who Over the weekend, I saw a YouTube video where someone just kind of like the archetypal, like sitting at their desk with the camera two feet away, kind of talking off the top of their head for 45 minutes. The channel had maybe 100 subscribers and the video had 300 views. And the centimillionaire who owns this service was in the comments. defending themselves and picking a fight. And I would prefer not to catch the attention of very rich and very litigious people who are clearly Googling the name of themselves and their company and getting way involved in the comments and posting through it. There is a story on the homepage right now about it, I believe. I don't think it's scrolled off. I think at this point, like, Let's see. I think maybe one of the other mods has merged it. Ah, so here's one of them. Story removed by submitter. So we are going to avoid saying proper nouns because we don't need rich people showing up and hassling me. My God, I don't want to get involved publicly. dytomode ohh, w******** drama is too crazy rn :D
it has meant i went boy you know we've wanted for a while for users to be able to directly upload their own avatars to the site and there's been a bunch of code issues related to that and it kind of hopped up on my priority list the last week or so because every day there is another bit of development in that story, and I don't want to depend on a service from someone who, oh, Dido, you broke the rule. You said the proper noun. Now I have to go and edit the chat transcript. You're making work for me. dytomode Nahh, noone will catch it :D
And I just don't want the famous person showing up. That's all. And clearly they are, because if they showed up on a YouTube video, No, they showed up on a YouTube video with 300 views. How do you find that, right? That's a level of posting through it that I don't even know what to say.

02:24:50dytomode He is busy doing podcast with Lex Fridman
frici Letting users upload their own avatars sounds scary...
So we're going to do security by obscurity, where I am going to cruelly edit your mention. pushcx https://github.com/lobsters/lob…
So Fritchie is directly on topic and absolutely correct, and that is my comment here. While it would be great to have users upload their own avatars, there are a couple of serious security concerns there where, speaking of security, let's get out of... I don't need my personal browser because I'm not going to be merging any more pull requests. And then also we get back into dark mode.

02:25:34The concern with uploaded images are that they are uploaded files that go and get persisted on our file system. And a Rails app is a series of scripts that are just files on your file system. So if you could trick an upload system into persisting a file name that ended in .rb or was otherwise inside the Rails source code, there is the concern that maybe then you could trick Rails into loading it, because Rails wants to autoload files, right? And Rails has gotten better at this, much better over the years, by shifting autoload in production to only happen once at startup. That ameliorates the issue, but that just means it still can happen if the Rails server restarts, or if certain other kinds of scripts invoke Rails and boot it. But it's very scary that someone could upload a file and then get it executed as source code, right? That's remote code execution. That's game over. Heck, there are even famous blogging engines that power 43% of the web, whose name we're not saying. And this happens kind of constantly to those plugins and other stuff. So...

02:27:05I have liked that this service handles this. The other issue about uploading avatars is that they are binary files. And if you resize images, we got into this a little farther in the comments. Someone asked about, wait, what could go wrong with an image? Well, the answer is maybe the image is bad data that can trick the image processing program into crashing and running arbitrary code. and image magic for, man, 15, 20 years was the hands down like that was your default choice for image resizing and other chores. albynton Is there a moderation functionality with the existing third-party system in case someone uses an illegal or obscene image as the avatar?
It does so much wonderful stuff. However, it was begun and primarily coded before buffer overruns and other secure coding concerns were really well understood and image magic was not designed ground up with hostile input in mind. dytomode @Albynton g******?
And so there have been over the decades, many security bugs in image magic where badly crafted images, not badly, maliciously crafted images could cause crashes.

02:28:36albynton @DytoMode We said no proper names!
Dido, you are losing the don't say the proper noun game. easeout craftily crafted images
So Elbington, yes, the service we use does have that hassle of deal with moderation issues. dytomode Ahh, yikes...
We would be taking on a moderation issue of that. However, I feel like that's a fairly small acceptable risk because we already have Oh, I could actually add, hold on, where's this guy? What if I took this and I said, here we go.

02:29:33Here, I'm going to do something really tacky.

...42So that's usually my I'm headed to the restroom indicator. So I don't think we have too much problems with really obscenity because we have all of those same kind of risks with allowing commenting, and they're fairly minimized by the invite system and site norms and other stuff. Images do come with extra legal obligations related to child sexual abuse material, but those are pretty rare and small. I would die of shock if they came into play.

02:30:34easeout spoiler warning message on the screen all the time = you're a journeyman twitch streamer now
so in the couple of decades that folks have been using image magic there's now been developed a library called libvips and i want to what does it stand for it's it's image processing system but i don't remember what the v is maybe the v is for performance I'm a journeyman Twitch streamer now. Oh, yeah. albynton as you say, the risk is low, and the mechanisms are already in place for usernames and co
Well, given that I'm not going to be a Twitch affiliate or a partner, I will settle for being a Twitch journeyman. And maybe one of these years, I will talk Twitch into letting me have an API key, because I'm a normal and can be trusted with API keys. Yeah, usernames are another vector. I mean, any place that you have user-generated content, you have these moderation issues. I don't feel like images terribly improve our risks. They do increase the risks a little bit. I don't want to dismiss that, but it's not a huge amount to what we already have. So I talked GMEM by politely asking. into submitting a separate PR that just set up Active Storage, which was some churn for them. And on my local, I have started adding avatar uploading.

02:32:15Yeah, this is probably gonna go away, actually. I don't want to continue depending on the service from the... very exciting source of news the last two weeks. The other feature that is related is an option to take images from GitHub. And if we were just going to drop our existing service in favor of another, I would probably do that, although we have a fairly significant percentage of the site, which is, I don't know, maybe five to 10% that really strongly dislikes GitHub and doesn't have an account there for one of several principles. And so if we added that, we would be adding a feature that a bunch of people can't use and buying a bunch of churn. dytomode Wait, could it be possible to pull google account avatars/
So I would rather make the first thing, let's just let people directly upload. So if I pop my git stash, I'll show you where I've gotten so far. It would be possible to pull Google account avatars. dytomode No google account? :D That's rare
I have no idea what that API looks like, and I don't have a Google account for that same kind of I object to this service reasons. I am assuming there are other people who really don't like having a Google account. Yeah, I know. As much as Google has tried to make it mandatory to use the web, I do not have one. And at this point, I'm just being stubborn. frici Google account avatars aren't all that safe either, even when it comes to obscenity (again)
I mean, I've had Google accounts for jobs, but I've never had a personal one. dytomode I mostly use proton services but still have google account for youtube and other stuff
easeout (Chrome is in fact the new IE)
Well, I might have tried it back when Gmail was new. Maybe I'm wrong. Maybe some Googler is checking me. Chrome is the new IE. Man, everything is the new IE on this stream. My cat is the new IE. He has weird moods. His behavior never improves. He's not compatible with sleeping in. easeout cats = quirks mode
So there's a little bit of CSS, and then the primary bit of addition is this has one attached so this is the active storage code cats are quirks mode excellent yes i like it we have the avatar code on the site now is a little bit complicated in that we use multiple sizes of avatars but it's not clear for what so you see in the code this is like straight work in progress code i have this name duplicated because i realized on profiles we use this 200 size but then something was leaving behind 100 square size images and i didn't know what was happening here and so i just duplicated the line so i didn't forget The code for attaching a file upload form and getting it into active storage is basically no code at all. You know, it's these couple of lines. This is just Rails at its best of we have this feature. We know lots of people want this kind of feature. Let's just make it very, very easy. And they have... really paved a happy path for, yeah, maybe we'll be uploading images. So let's integrate with libvips very nicely so that we can say when someone uploads the attachment, we're going to create these variants. And let's make sure that you can configure things for production and dev. So the code to work through,

02:36:49chamlis_ tuned back in to an incomprehensible yet ominous warning
This is not at all a user model.

...58Oh, so shameless, the incomprehensible warning is that lobsters currently uses an avatar service that is provided for free by a rich person who is in the middle of a lot of litigation, but making time to find various small no-name people who talk about him in public, like I saw a YouTube video by someone who is not at all famous. It had 300 views, and it had a comment by him piping up to say very angry things. I would prefer not to attract his attention, and he is clearly just Googling his own name and posting through it. chamlis_ ahh didn't know who was behind that
If you scroll up in chat, Daito mode broke the rules. Daito has lost the game. God, I have the feeling, Daito, aren't you younger? dytomode 30
I don't mean to insult you, but you're... You're probably like 25, and so you don't know the game. frici you were close LUL
But you have lost the game. 30? Okay, maybe you know the game. It was an early internet meme. gmem_ dangit i lost the game
albynton Oh no, we all lost the Game :(
Yeah, I was fairly close. The other weird one I do is occasionally people say things and I can nail where they're from. frici pretty much yeah
Yep, GMem, you lost the game. So GMem, if you are just tuning in, I talked through... Albinton is older. Thank you. I'm glad somebody got it. GMem, I just talked through how you very nicely helped me set up active storage and you took on the churn for... your other very nice pr adding action mailbox support so that we could go ahead and replace the avatar code sooner rather than later because yeah i would prefer like i know avatars are not an enormously important feature for the site. And if they broke and I had to turn off all avatars for a couple of days before I coded this up, that would not be the end of the world. I mean, it wouldn't even be as bad as losing tags off of previews, right? But I've been pretty frustrated by events. They have kind of pushed buttons for me. pushcx https://xkcd.com/386
And this is a nice, productive, chill thing I can do of, well, in response, I can improve this rather than succumb to the impulses of... Here, and I'll add the link for anybody who hasn't seen it. It's the one I know by number. Succumb to the impulses of someone is wrong on the internet and get involved. because boy would that be a mistake so the existing code has this function avatar image and last stream of the stream before we talked about whether we use url helpers or just directly put urls in text And avatar-img is sort of a URL helper. However, also, also, that's not it. Oh, somewhere. easeout love to depend on a nice base SDK. in some sense the most successful path a third party library can take is to deprecate itself due to a base SDK upgrade path it inspired
My machine accidentally got rebooted yesterday when I was yesterday, two days ago, where I was in the middle. Who is the other user? Oh, me on a different TTM. Somewhere also in the views, we have some line of code that directly constructs avatar URLs. So I'm going to have to find it again. I lost it to that unexpected reboot. And I didn't have a note. And it's been a busy couple of days.

02:41:41The other question that's worth revisiting about avatars is, aside from understanding why we have these, oh, this 32 by 32. So the 16 exists. for inline on comments. So if you look at, let's grab something with active comments. Let's choose a less exciting one. So here, this user has an avatar to the left of their comment. That's the 16px height. It is roughly the font size. I don't know why there's a 32. The 200 is the one that's used on the user profiles. So let's just click on this person for their profile. So this is the 200. I don't know why there's a 100. easeout hi-DPI displays of same?
So we have to investigate these two sizes. Let's make a to-do list.

02:42:52High DPIs. It might be. That was my best guess, except they're in opposite directions. Like, we know the 16 is the inline text, and 32 of, okay, for high DPI. easeout yeah one is double and one is half…
But I know we show the 200 on the profile page, and so it's weird that we support the low DPI. I don't know. It's happening in opposite order in the code. So I'm going to just dig in.

02:43:37dytomode My usual sizes for squares are: 16, 32, 48, 64, 96, 128, 192, 256, 384, 512.
I also just wonder for squares, yeah, you do powers of two. Oh, not quite powers of two if you got 192 in there. Also, these images are so small and the site, the site, the web has generally gotten such bigger pipes in the dozen years since the site started that maybe we want to add a larger. I don't know. easeout and these days we have @3x phone displays
dytomode Scales pretty well if you start painting favicon from 16x16 in vector and upscale
I'm also, I'm not sure to what extent in practice do browsers even use those low DPI sizes. Ooh, do we now have 3x DPI sizes? I didn't know. Yeah.

02:44:50So there's a quirk here about our current avatar implementation. chamlis_ in my experience browsers are good at picking the right-sized <source> from a <picture>
easeout iPhones have a 3x since the… 6 Plus I think. But 2x is still in some of the lower end models
We do not directly hotlink to the avatar service whose proper name we're not going to say. If we open this up, you will see that this is a URL to lobsters. So we go ahead and fetch and locally cache these easeout to my knowledge desktops just go up to 2x
It's two things. It's kind of a reliability thing. It is also a privacy thing that someone should be able to browse lobsters without generating hits to some third-party service. So when we had jQuery, we never linked out to some random public CDN. easeout phones don't generally need the 1x anymore afaik
We always hosted our own copy of jQuery. And when we used proper name avatar service, we always fetch caches. Phones don't generally need the 1x anymore. Okay. So we could do like a powers of two thing where we do like 16, 32, 64 for text and 128, 256, 512 for profile pages. Those are really the only two places it's worth mentioning. Yeah. albynton Not using a public CDN also helps in respecting the GDPR
Survey usage, I kind of started that and zipped past it. But if you look at these, they appear in the list detail. Not using public CDN also helps in respecting GDPR. Yeah, not that I want to pick a fight with GDPR, but it's an American website hosted in America.

02:46:48So there's the appearance inline on stories, the appearance inline on comments, and the big one that appears on profiles. Those are, and I'm going to hand wave a little. So there's heinous inline partial here. And then there's comments and stories are basically the same presentation. They're using the same size for very similar visual effect here and here. So we basically only have two uses.

02:47:34I meant to mention, I do generally recommend the strategy of when you see dramatic online events, Maybe write some code instead. There are lots of things that are worth getting involved with, and I don't at all mean to take away from the folks who decide to become activists, but I guess I'm saying pick your battles, and if something bugs you, find something productive to do. It's good for you. So yeah, the 32 is the real puzzling one. was it was in the app helper yeah so this must be where the 16 and 32 are coming in and then the 100 becomes the 200 what did i see here in this call yeah these just say 100 So the tempting thing here is to make them, if 1x is 16, well, then it would be 16, 32, 48, which are like, okay, those are round numbers as far as programming goes. But then it would be 100, 200, 300, which it's not the beauty of powers of two, right?

02:49:25easeout powers of 2 is a good policy. that's how OpenGL mip levels generally worked, and I find that using a texture that's up to twice as dense as the pixel grid is ok, but any further risks aliasing. so 1 <= x <= 2 is a good range of texels/pixel
So there's a decision to make. So we understood on those two now. I feel pretty good about that. PowerZ2 is good policy. That's how OpenGL MIPS worked. Yeah. Let me say my concern better of if we do 100, 200, 300, I can just persist all of the avatars that we have on disk now in cache. If we do 128, 256, 512, or sorry, 384, easeout since you have specific places where they're used at specific sizes, it's also fine to just specialize to those
we have to go fetch those from the service and we can do that that's just i write a migration it has like a sleep one in there and it'll fetch a couple thousand oh but so maybe we maybe that's fine so our cache So I just visually recognize that this one is an arbitrary random image. So they generate these that take emails. So grab it. I almost broke the rules. easeout because being right on the grid will look better than being a little bit off, unless it's a photograph where it doesn't matter so much
The service generates a stable but random image for users who have not yet uploaded their own avatar. We're going to need to do that. But right now, we can't differentiate between placeholders and custom avatars that have been uploaded. dytomode do they have api to check if avatar is set?
So perhaps that says we're going to have to fetch all of these anyways, because I believe the service has a way... Yeah, I believe there is a way to say Well, actually, I know there is because there are a couple of different styles that you can use. Like one makes little monsters. This one is nice and geometric. We're going to have to figure out our own placeholder code. But I know because you can select between different ones, you can say, hey, if you don't have an image, just give me a 404. So we'll have to write that migration. easeout API docs say you can supply a default parameter to override when there is no avatar set.
regardless yeah okay so let's go ahead and say 16 32 48 for inline and 128 256 512 for profile k connor says it's okay no i don't need to put you on the spot but thank you i have appreciated you typing in with your knowledge So instead of saying persist, it's going to be, ah, thanks.

02:53:01And then we have

...17So where the code is, is the upload works. It's not actually using it, but so place.

...49All right. Seems like a pretty good order to work through them in. Yeah. So let's go ahead and set this up. I don't need that comment anymore. Ezout, do you have a good URL on this 1x, 2x, 3x sizing? It would be really nice to put in a, hey, we have three of these where we always used to have two because. Because I certainly didn't know that phones are now doing 3x DPI.

02:54:54easeout here's some evidence for iPhone in particular https://iosref.com/res
And that makes me want to say, we're going to call it. So the purpose is in line. Oh, it's a symbol. And then we'll just, and then this can be profile one X iPhone in particular, let's grab the browser. I just want something I can stick in a comment really. because I'm not going to remember why. Ah, scale factor, good name for it. And we're just looking at Apple devices here, but my experience for Android is they do everything. They have every possible resolution, every possible DPI, every aspect ratio, every points per inch. So I don't feel the need to find a link for Android because the answer is going to be like, yes.

02:56:25Thank you for finding that. easeout when we write iPhone apps, well these days we use vector images usually, but previously we'd supply a 1x and a 2x raster version, then later a 2x and a 3x.
All right. So there's allowing the user to upload. Well, there's sizes.

...45Hmm. That makes a lot of sense. Doing vector and raster. All right.

02:57:05Here's the controller where I said you're allowed to set your avatar. Oh, one thing I forgot to prepare. All right, so let's jump over to localhost, where I'm probably logged in, not logged in.

...33And go over to my settings page. easeout I assume user-uploaded SVG would be a ten foot pole problem.
So this one is just going to have my familiar profile image. I use this one everywhere. It's from the game Baba Is You. If you would like a wonderful puzzle game. It's nice and mind bending. Baba Is You. Yeah, I'm not touching user uploaded SVG. SVG. easeout +1 for baba is you
dytomode @easeout Unfortunately we can't use vector images in emails.... Ran into so many times when scaling fails
I can't remember if it allows internal debugging. But yeah, we're just not going to do vector images.

02:58:21chamlis_ user-uploaded fragment shaders?
easeout now we're talking
Oh, yeah, emails, you know, there's a what is that named? The interop community, there's like an interop council. easeout yeah html email is an upside-down world I have not visited
There is some browser consortium that's Safari and Firefox and Chrome and Opera, and they kind of get together and talk about what next standards are going to be. And if they didn't have the occasional secret veto, it would be totally above board, but they do. I wish they could make one of those councils for email, because email has not been much revised. We kind of bolt things on the side for security, but otherwise, like the HTML you can use hasn't changed much in 20 years. I think that would be kind of ripe for a little update now. dytomode Still using tables to build UI in emails 2024
dytomode That
dytomode is wild :D
user uploaded fragment shaders that would be great the yeah there's a former co-worker of mine named justin duke who runs a service called button down email which is nice i'm using it for recheck i really like button down quite a lot and you know i'm biased as heck because he's a Former coworker and a generally nice guy. chamlis_ is there an agreed baseline for html email? I'd always assumed it was just whatever web engines in clients could handle
but it's great and now running it he has a front row seat to the horrors of the legacies of email he has some fun cursed knowledge if you follow him on he's mostly active on blue sky occasionally he will mention things and it's just like oh right that's that's four decades of complexity right there and things being uploaded or maintained by people who hate each other. Is there a agreed baseline for HTML email? No. I mean, people have sort of reversed engineered what the lowest common denominator is out of there, but no, it's not agreed. And there are so many pitfalls to doing HTML email with better CSS support.

03:01:08dytomode There can't be basline. Each email application renders html & blocks features differently.
So the thing I didn't prepare before stream saved is I didn't get myself a nice test image or two to use. So I'm going to browse off screen a second and see if I have a good, Ooh, that's good. All right. So I am going to upload a cat photo for my avatar. And if I need to upload a new one, aside from deleting it, I can just switch back and forth between this cat photo and the actual avatar I use everywhere. All right. So it says it uploaded. And I don't have a lot of, actually, I don't have any experience with active storage. So I kind of want to just poke around, see what it did on it, disk. That's interesting. So I got a file. And this must be from the previous one I uploaded. So I got a file, but it doesn't even have an extension on it, which presumably is to help with things like the web server, helpfully treating it as code. And I see that. So for the eagle eye, yes, in development mode, the storage directory is here directly in the rails repo in production, GMM configured it to be outside of the rails tree. So. At some point, there is going to be production config.

03:03:19I'm not sure what this is going to look like. because I don't wanna tell Rails, hey, you go find things because Rails app workers shouldn't be fetching static data. On the other hand, there's probably some level of URL rewriting. I'm not sure what that's gonna look like. We're gonna think about that.

...47All right, so if I say, Should be a JPEG, right? Yeah, good. I didn't think it was going to get wrapped up in any kind of container format or anything. The real question is... Yeah, I should have done that one off stream. So anyways, it's not actually secret that I use an iPhone 12. But if that had had... Oh, yeah, so it just printed GPS. chamlis_ phew
Didn't actually print the info, which I appreciate. I don't think that photo is my current home, but that still would have been irritating. So strip metadata, right?

03:04:50And I think we're going to take jpegs and pngs actually maybe we just want to only do we can do both i was going to say maybe smash jpeg to png but then if anybody has a photo that just blows up the file size because natural tones and photos compress poorly in raster data

03:05:21So we're going to have to look into how to do that in Rails. dytomode what about uploading png with transparent background?
In the meantime... Yeah, Shamless, I'm also saying few. On the other hand, my stream is not big and popular, and mostly things are fine by being unimportant. dytomode How do you pick dark or light background for JPEG?
And if rich guy who owns... Current avatar service wasn't picking fights all over the internet. I wouldn't bother with this pronoun game nonsense. JPEGs. So Daito PNGs with transparent backgrounds are fine. JPEGs don't have a notion of transparency, so we don't have to interpolate one.

03:06:23dytomode Do you convert png to jpeg or keep it?
So let's remove this debug. No, I was just saying I don't want to convert PNG to JPEG. dytomode Ahh, I see.
I would rather just have two files or two file types supported. Oh, yeah. So I guess I want to test.

...52I don't know what. So rails has active storage and it's a very generic, any kind of file. I want to make sure that that is limited so that if you upload a PDF or a text file, you know, you get some kind of error message and it gets properly thrown away somehow. All right. I'm going to do some of the. the UI stuff first. So here's the settings page. Let's just view it again. Oh, that's interesting. So I saved or I reloaded the page, and it changed from knowing that I had one attached to saying I don't. So there's something odd going on with the API here.

03:08:02Yeah, so it says avatar attached, or I can replace.

...20dytomode Ok, got to go. Good luck removing *cough* from lobsters :D
But then when I have reloaded the page, it forgets. That's odd. Settings controller should be persisting my users. Let's ask the Rails console.

...35Thanks, Dido. You pulled it out for a win in the land there. Hope to see you on future streams. Hope to not play the no proper name game on future streams. On the other hand, usually these run about three, three and a half hours, and I am definitely not going to get through all of this in a half an hour, so I don't know. If I see... dytomode I'm in Europe so my timezone does not usually match
dytomode its 1AM right now :D
ridiculous and irritating news i may be driven to spend some more time off stream coding on this we'll see okay so this avatar attachment field knows but if you say dot avatar dot attached i don't totally understand this active storage api yet

03:09:40Oh, so Dido, you would probably prefer the Thursday streams. So I do the Monday streams are now, obviously, my afternoons. And then the Thursday streams are early. And I was specifically trying to get some better European coverage. So whatever 9 a.m. Chicago is, is will be the stream on Thursday. And the Twitch calendar will tell you what that is in your time zone. If you, I don't know, there's a link somewhere under the video stream for it. It's called schedule or calendar. frici seems to be about 5PM for dyto
So why does this say true? But then if I load the page again, is it going to lose it or keep it? Lost it.

03:10:35chamlis_ are there image dimension limits? I'd imagine there must be image-bombs
frici if i'm getting their timezone right πŸ˜…
So that's puzzling, especially because I'm calling .avatar.attached.

...48So if I fetch the user again, it's still true. So how is it true in the console and not in the Rails server. Are there image dimension limits? Oh, yes. That's another concern here.

03:11:23So I believe that because we're specifying sizes that Rails is going to do the reasonable thing and say whatever image you give me i'm going to resize it to the sizes i care about also so i have a chance to compress it

03:12:08Yeah, I don't think I need an automated test for this, but I would like to know how Rails handles this. At least, Shamless, the image format, like the reason we're doing this whole different sizes notion is the image is not a container format that has multiple sizes in it. Yeah, that would be pretty weird. You'd end up partially fetching a file. One of the reasons for these source sets is to allow people on low bandwidth connections to fetch smaller images. But I don't know.

...55How is the settings controller loading edit user, I guess, is the question.

03:13:09We call user dupe. Oh, we're duplicating the user. Well, no, the user should come. I'm wondering if the user is getting serialized into the session and we're retrieving an old objects.

...43easeout for the todo list: when you remove exif data, you may need to avoid removing the orientation.
frici Ohh good point
now we fetch it out of the database each page load when i remove xf data you may need to avoid removing more oh yep there's a gotcha well i have the I have the feeling that Rails should, if I can find whatever its method is, the Rails will probably do that for me. Because it seems like an obvious foot gun that it would be very Rails-y to do the right thing on. easeout mm yeah that would be nice of rails
Let's look at the server layout when I load this page. I want to see that that query for my user happens. Yeah, so it's grabbing. my user out so if it's grabbing my user out where did the image go right it's one of the nice things about working with rails has been a lot of the times you're like oh i have to do this obvious thing wouldn't it be nice if rails did the obvious thing and then very often it does

03:15:31So I'm confused. If I ask for the avatar... Oh, okay, hold on. This is saying name avatar, and then we're doing a circular thing where the avatar... What's that famous line about object-oriented code? You wanted the banana, but you got the gorilla holding the banana, and then you got the whole jungle that the gorilla is in. So I wanted the avatar... But the avatar contains a reference back to the active record object. And so I get the whole giant user model in here.

03:16:10New record. That can't be right.

...22Maybe that's happening because of the dot, dot. easeout sounds like a rich hickeyism
I wonder if I had said, well, let's just edit the debug. If I had said debug at user, would it still think that's a new object? Sounds like a rich hickeyism.

...48So this looks like, you know, so I see one, two, three, four, five, six, and it says new record false. This is something about how the edit user gets created by duplicating the active record model up here. So if I said, let's, yeah, let's just say,

03:17:33Let's remove that duplicate.

...58easeout yeah that's the ballpark
nope it's joe armstrong i feel like rich hickey is a close miss for saying slightly grumpy things about object orientation all right so that oddity alone where the duplicate record doesn't see that the model is hydrated, that's an odd one that I don't want to think about. And I'm curious. So this is kind of implying that there are the six versions. But I think Rails is being lazy about it. Yeah, and it didn't actually generate the six different versions. There's still only one file on disk. Unless it, does Rails have a temp? Oh, hey, old dump files.

03:19:17Yeah, it doesn't look like there's anything in the cache. No, just sprocket stuff. All right. Rails is being deliberately lazy about... So we need this and we need to...

...48And I say we need to trigger this generation because the production config is going to be nginx directly going to the files. So if the files aren't there on disk, we're SOL.

03:20:29So let's figure out how to remove an attached image.

...43Rails is doing the convenient thing of just giving me the file selector, but this is a file selector rather than, you know, I'm directly manipulating the object, so how do I detach the attached file? So we're going to go to the docs when all else fails, right? Oh, lazy versus immediate. That's on our to-do list.

03:21:46Purge, very political. All right. How convenient that they're using my exact example. So I think I'm going to have to make a route.

03:22:02I'm just going to make it its own page rather than AJAX things in and make this a partial. Yeah, I'm not going to get into like, let's import Turbo. Let's just do the simple thing.

...26All right.

...32It is kind of funny how much I have started preferring flex. I've really only played with it for a few hours and I haven't put it into production, but I never remember the order of operations on like link to even after all this time. And I'm totally comfortable in flex because it's just like, yeah, just write your href. So that means let's go up to the routes. This actually might be a good point to have a little checkpoint here. Oh, man. Let's delete that old origin branch. And let's make a branch for this.

03:23:40Just it's a nice point to check or a nice place for a little checkpoint and what the basics are there will be nicer for me reading the history to be like what did I think I was doing if it's not just yeah here's 600 lines of code all at once.

03:24:12So we have a avatars expire. This really wants to be a... pro_noi_ac Just to check, is the "remember the proper noun game" note still relevant?
This is an old Rails hassle. This really wants to be a post or a delete.

...34And there's a way to... pro_noi_ac (I was out for a bit)
The note is still relevant because we're trying for the rest of the, you know what, let me, I don't recognize your name from being in here like an hour and a half ago. So let me just edit the note to current avatar service.

03:25:16All right, so if I just save that, then there's just weird font size hassle. Thought it resized itself.

...34I'll just make it two lines.

...42There we go. So anyways, I hope that's clear, Pronoi. pro_noi_ac πŸ‘
There we go. We do like that. frici still out of bounds but clear enough XD
And I will try and remember that I put this doopy thing on screen so that I reset it. There we go. That's a better size, right? Doesn't need to be huge. Still out of bounds. frici ah better size and all clear
Yeah, my little preview is quite small. How's that? All right, doing it live like Bill O'Reilly.

03:26:27chamlis_ hate to keep dumping edge cases on you, but does the rails resize do filling/letterboxing/pillarboxing if the images are non-square? I'm trying to find the relevant code
And it's not the end of the world, it's just if they're running around hassling anyone small. No, I want you to keep dumping edge cases on me, shameless. frici Nothing like testing on production LUL
Does the rails resize, do filling, letterboxing, pillarboxing if the images are not square? Oh, that's a good question.

...51Nothing like testing on prod, yeah.

03:27:05You know, actually, we're going to see this edge case because the image of the two cats is not square. It's just a photo of my two cats on a table or on the floor. That one's going to get a workout, but thank you. I do appreciate you and ease out figuring out all of these corner cases, because it's nice to just have a list and work through them rather than blunder into them, especially in prod, right? Because that's the eventual goal for all this.

...43So I was going to say,

...56Yeah, so I can tag method delete on the end, or I could just make this a button, and then it would be a nested form. Oh, so painful.

03:28:13We'll do the least painful thing. We'll add this method delete. Let's say delete.

...39And I'll end up deleting this, but that's gonna come along in a minute. Where's... There we are. So there's the to-do list. chamlis_ I think it'll preserve the aspect ratio https://github.com/janko/image_…
so the user can delete their own let's go let's look at that route okay so we get a it's just called avatars it's not avatar delete so we'll just call it or is it it's avatars plural okay rails

03:29:43Oh, resize to limit. You'd think it'll preserve the aspect ratio. OK. That's handy to know. So I may want to include some microcopy on there, saying square. On the other hand, this is fairly cheap with a technical audience. If someone uploads a non-square image and then it doesn't look great on their page, I don't know. Yeah, I would really rather chop it because I don't want to have to account for non-square images in the CSS. That's just no fun.

03:30:28Man, how much do you like seeing file.unlink called in a Rails controller? Feels a little dangerous, huh?

...56justinhhorner I don’t want to distract from your work, but if you have time, would you share a couple things to be mindful of for someone learning Rails (but not new to programming)?
Don't? So since it's on the avatar, purge is immediate. Oh, you're not interrupting, Justin. Would you share a couple of things to be mindful of someone learning Rails, but not programming? know i think building on your mention of the pick act books i think it is if you can spare the time it is worth at least skimming through the pick act books or well-grounded rubius to get an understanding of what kinds of things are happening in rails and what are ruby features because stuff like like blocks here, that's just a general Ruby feature. It's not a Rails feature, although this particular and this API is actually Ruby itself. chamlis_ I think you'd want resize_to_fill https://github.com/janko/image_…
But I think having an idea of that dividing line is useful. And if you learn, if you do take the little time to get comfortable with Ruby, it A lot of the magic that Rails does, you can kind of look at it and be like, oh, they're monkey patching that class. They're creating a DSL with blocks. And they're calling instance eval to set a variable. That kind of thing helps a lot.

03:32:35All right. So there's, let's say, avatar deleted. Let's load this page. You'd think I'd want resize to fill. OK, let me grab that link. And I'm going to stick it in the scratch notes. Thank you, Shamless. All right, so now I see my delete link. And I'm going to paste. Just throwing that link into the scratch. easeout +1, from reading those resize_* methods' intros
So no route matches. Why are we mad? The route should have been reloaded. It didn't get the method. Oh, Kevin, thank you for confirmation. So the method variable got missing.

03:33:46Do I need to do old style?

03:34:04No. chamlis_ by the way, is anyone else getting stream stutters?
I'm getting, oh, it needs to move into the call to avatars path. justinhhorner Cool, appreciate that. Thank you.
just misreading the nesting. That's all. That one bites me on the regular. There we go. And then I still might have to make that underscore method. Yeah. If I had said, oh, can I not do this anymore in Rails to just kind of slop a get into a delete route?

...54justinhhorner @chamlis_ Yeah, I thought it was on my end
Cause I'm actually not, you're technically not allowed to nest form elements. It's anyone else getting stream stutters? I hope. frici same HahaSweat
Oh, no, it's not you. It's me. The, stream health bit rate is dropping. That's a little strange. Sorry for those hassles. So is it just the video that falls behind or are you losing my voice? frici I was downloading things so figured it was just me
easeout I'm seeing the appearance fuzz out and restore periodically (once per keyframe?) but no interruptions.
Because if you're losing my voice, you know, this isn't like a high FPS, I'm playing a racing game or something. But if my connection is going to be trash because it's rainy in Chicago, you're seeing the appearance fuzz out and restore periodically once per keyframe, but no interruptions. Well, that sounds like a bad bit, right? I'm trying to think of how I get this on screen. I'm getting conflicting info from Twitch.

03:36:14I'll show you. It just takes a second to bring this on a stream. So Twitch is telling me. that my bit rate is excellent, but then also it's trash. chamlis_ for me twitch drops to 160p which lower audio bitrate too
Like this number should be, I think it's set to, well, not 5,000. I thought it was set to 2,000 or 3,000. It was going to be plenty. So I don't know. easeout voice is clear
It's an odd combination to be excellent and also not working. All right. Well, we're running about three and a half hours. And I'm dicking with dumb Rails stuff. Maybe it's a good place to call it. Because I'm just going to have to make a form and a button and run through those things. Yeah.

03:37:05Yeah. I'm sorry to call it, but if the... Oh, how weird. frici your bitrate is excellent you have more than 56kbps
So I just thought to look over at the OBS indicator. And it's like, oh yeah, everything's fine. It says no dropped frames. The bit rate is high.

...29My bit rate is excellent. You have more than 56 kbps. Ah, you know, I spent a lot of the time in the 90s on bulletin boards at 2400 baud. Shameless, can you tell me, has it happened in the last 30 seconds or so? Because my little graph has recovered now that I've reloaded that one page.

03:38:04chamlis_ I think it's gotten better
frici you're fine its not something you can help if your line tanks 🀷
easeout it has.
easeout gotten better.
You think it's gotten better. Well, let's hope it's gotten better. Yeah, Fruity, but if I'm running about at time and the quality has gone to shit, I would rather just call it than drag it. All right, so...

...39chamlis_ hasn't happened for me
What am I looking for? I'm looking for the route.

03:39:03justinhhorner It's much better now for me
So wait, if comments are just posting. frici I'm no longer getting buffering/delays or pixelation so i'd guess it has recovered or its well on its way to.
All right, so we touched on it earlier on stream. But if comments have this, well, you can just post to the delete method. Yeah, maybe my neighbor turned on a microwave. I'm kidding.

...46It's at least a wired connection.

03:40:09So that thing I said I wanted to clean up, I'm gonna just make that a little worse. We have the JS for the comment deleter and the comment undeleter and all these, and I'm gonna add one for avatar deleter.

...33Because it's the easiest way right now to get to sending an HTTP post or delete instead of a get. And I don't want it to be possible to just have a get URL that deletes avatars, which is effectively what that question mark method equals that I was trying to do. I forgot, like, oh, right, that's just dangerous. And I'm not going to have an if. Just going to go ahead and.

03:41:25Well, at least use the right HTTP for.

...32And really, what I want to do is just reload the page now, I can just have that. Yeah, we'll grab all this.

03:42:08And I'll have to fix this to say what?

...16Is it a div? Fine. I'll just replace the div.

...47And then the comments controller, I want to see its render. It just does a render with that. OK. espartapalma I'm having the buffering a few seconds ago.
So then here, instead of setting the flash, we will say,

03:43:18The buffering. Oh, my graph is happy at the moment, though. I wonder if the graph is just wrong. And hello again, Esparta Palma. Thanks for coming back.

...43I mean, that's a lot of lines of code to get right in one go, but that might actually be okay. Or not.

...58chamlis_ holding steady here
So I called it. Oh, not enough room. I missed the symbol.

03:44:20And so now if I click delete, yeah, add JavaScript link, but nothing happens. JS error. Oh, can't fit things. Man, how did I live on 1080p before?

...52Hmm, it's not even causing a JS error. Did I reload this page and I'm not thinking about it?

03:45:11Oh, I didn't change the CSS class of it. That's what it is. So this delete link doesn't have a class. So then this is hooking to the wrong.

...43It's just not firing at all. I should have seen the hash appear in the URL. That was the old way to know that you would failed to hook a JavaScript link was this comment, huh? Did I just edit the wrong line of code? chamlis_ I think there are duplicate avatar handlers?
Yep.

03:46:09I had it right in the JavaScript, but I didn't have the class on the link. chamlis_ curses, just too slow
You think there are duplicate avatar handlers? No, it was I had it right in the class, but not the link. Oh, and that last one must have fired because my avatar went away. So I'm going to grab Put the two cats back on. Save.

...33And then delete. Cool. It replaced with a missing template error. But if I go look at the Rails output, yeah, so deleted file from key, deleted files. Good, good. So that part is right. Yeah, all of that is right. Now I just got to have the avatar controller render text correctly.

03:47:11Let's render plain, not render text.

...25content underscore type all right now let's not reload one more time around oh yeah shameless you almost made vip for anybody who's new yes to be a vp in the channel just catch a bug faster than i do And I have the advantage because I'm a couple of seconds ahead of you. I also have the advantage if I'm making all these bugs. It's my fault. chamlis_ I'm going to end up switching back to qwerty so I can type faster
All right. Attach the cats.

03:48:12Oh, look. Got my nice thing. You can switch back to QWERTY to type faster. Oh, avatar deleted. It'd be nice if it stayed here, because that's where your eye is. So I guess I am going to have to insert a intermediate div or span or something. Yeah, I used Norman layout for a while. I think I picked that up from Gary Bernhardt, who used to tweet about it back when Twitter.

03:49:09easeout 20+ years Dvorak here
I built a couple of hardware keyboards and ergo docs, a plank. I feel like there was something else that I'm forgetting, but columnar split keyboards. Oh, yeah, after the plank was... I forget its name. I'd have to dig it up. But a similarly minimal but split keyboard. Oh, 20 years on Dvorak. Nice. And I liked it, it was comfortable. Once I had a split keyboard. And one of the nice things that I couldn't have predicted was

03:50:00By always doing QWERTY on staggered keyboards and Norman on columnar keyboards, they were just kind of different enough motions that my muscle memory could keep track of both. But then after I got a few months into Norman, they started to overlap. And it just, it pained me to be running Norman at like 50 words a minute. instead of QWERTY at 100. And I just didn't want to keep trying to climb. Look at that. That's very nice. Didn't want to keep climbing the skill curve. It was just too irritating to not be typing at full speed. If I was getting better faster, fine. But I was also like doing deliberate typing practice.

03:51:04Really what it was, was the attention and distraction was the biggest thing. If I ever had to think about my hands on the keyboard, that was, I mean, it was distracting in much the same way trying to keep up a stream of consciousness is distracting.

...30easeout I think if you want to use another layout you need to have some long cold turkey period to come up to speed
easeout and it's just going to be a chore for a while
All right. easeout but then it's real cushy
frici I keep thinking abou split keyboards but if I type anywher else it gets an issue same with Dvorak or other... not every device you hold will be on it.
so there's uploading and deleting i mean ship it right it's basically done oh a long cold turkey period can you ease out can you maintain qwerty because i found other people's keyboards got real annoying when i was comfortable with norman Or do you find that like you sit down and for 30 seconds, you are just constantly starting off wrong.

03:52:11Well, the nice thing preachy, the nice thing about those hardware keyboards I was running was, or was building was that they ran, like QMK was the most popular firmware, but. you would flash the keyboard firmware with the layout. easeout I type qwerty maybe once a month, and when I do I'm not as fast as I used to be, but that's not the one I want to optimize for
So anywhere I plugged that keyboard in, it was my layout. It wasn't any kind of operating system support.

...51easeout I don't generally get my wires crossed about one or the other.
Makes sense. Thank you. Well, if you don't get your wires crossed about it, you got better wiring than I do. You know, the most ridiculous bit of wire crossing? It came up today. I took a nap today. You know, very middle-aged man thing to do. easeout I do keep my phone in qwerty still because dvorak has benefits for ten fingers, not two
easeout certainly not one
If I'm napping, I am most comfortable laying flat on my back. I cannot sleep the night on my back. I can only nap on my back. If I lay on my back at the end of the day, trying to get eight hours, I will never fall asleep. I have to be on my side. But I can nap in any orientation. It is the weirdest, I don't know, call it a habit?

03:53:51easeout that's interesting
chamlis_ do the vim folk tend to keep the hjkl positions or letters if they switch layouts?
Oh, I don't want to set up active job. Oh, that's so painful. Active job. That's a big moving. Oh, yeah. So Shamless is hitting the key point here. What do you do in Vim? easeout I keep hjkl where they are in Dvorak. but then I learned Dvorak first and vim second
I did not remap HJKL because the keys that were then on the home row were then n i o h and so it's like oh well neck n is next match and i is insert and o is insert a new line and h well is move left so learning you know if i changed h the movement keys to be the home row it would also mean moving three more things away And honestly, I don't use HJKL that much in Vim, you know, a little bit for scrolling, but it's okay. Mostly I end up using word motions and block motions. easeout h is still to the left, l is still to the right on my right hand. j and k are together. it's _fine_. vim is arbitrary anyway
So I'm a little concerned here that I'm going to have to add active job.

03:55:17just to get width and height. It's also a little concerning, and this is a little railsy.

...31If image analysis provides width and height, you really want to do everything lazily. And how is it going to be enforcing things Oh, here's that resize to limit.

...56What did Chamlus dig up resize to fill? I hope they have an API for that.

03:56:11And this API. This is very Rails-y, where it's like, just take the upload and store garbage, and then afterwards call .representable to figure out if it's garbage.

...33Honestly, this else should be calling purge. If it's not this, just delete it. All right, because I want to enforce at upload time that I have an image, that it has a valid size, that it has a valid dimensions that are meeting my business rules, as opposed to upload it and have a race condition until something deletes it. chamlis_ deleting files from a view D:
But it's the Rails way to just apply user data It's a little much to. Yeah, so I'm thinking this is going to end up in the settings controller.

03:57:34If you want to generate URLs, I'm not generating URLs.

...46images with all variant records each.

03:58:04easeout I mean what's a viewβ€”a data-to-apperance template, or a user interaction layer
This, this is really showing off that this must have been extracted from Basecamp where you can have arbitrary file attachments and they don't want to care about what those file attachments are and then somebody added on oh well let's have some features for images active storage will lazily transform no no i want all of that to happen upright so we can

...53This is a little scary, this next paragraph, actually. There's so much that scares me in this API. easeout I guess this is a pocket of model
So this next thing that scares me is active storage can use VIPs or mini magic. The default depends on some config. So what's the default for this? And is the default the insecure one that's more common?

03:59:23Depends on my target version. Oh, so Rails, as the version of Rails is updated. Boy, I hope it switched from MiniMagic to Vips. So here's one more for the to-do.

...53So the... Somebody who was a... paranoid about security was not involved but the config setting the default depends on the load defaults originally it just used magic and then after seven it used vips as opposed to oh god use vips be paranoid

04:00:40So I guess we'll just tuck in at the end here. And we'll say... And I care so much about this, even though we have the default that I want to specify it. And I'm actually considering... Is there somewhere that I could detect this value and raise if it's not vips? Because it just seems like if I was coding this, I would probably drop support for mini magic. Like, it has a long and storied history, and I've gotten a lot of use out of it in my career, and I think really highly of the project. And I would not put user input Anywhere near it.

04:01:49Beats nothing.

...59Going one step at a time.

04:02:20chamlis_ curious why "ci" is your alias for commit; is "c" taken already?
So I think max file size is not something that Active Storage is going to let me enforce. And I sort of understand it because the way that...

...39The way that HTTP uploads... Yeah, C is my alias for checkout. Or it used to be, and I've deleted my alias C because I'm trying to train myself to use SW to switch and restore to restore files because I have been bitten by using checkout incorrectly. And I don't love the UI. chamlis_ ahh that completely slipped my mind
The checkout does two very different things, even though I understand the data model for it. So that's why CI is commit.

04:03:19So I'll be able to enforce dimensions just by calling resize to fit. I don't actually care what they upload. I do care about limiting file size, and I'm not immediately seeing how to limit that. But that kind of makes sense because of the way the HTTP headers are. They were written in a different age where nobody considered, hey, what if the browser gives us 10 gigabytes. And so the browser isn't required, I don't think even now, I don't think it's required to give a file size and then gets cut off at exactly that byte count. easeout it's a bizarre name for what it does too. I don't think I've really checked out a file since CVS
This page doesn't have anything about limiting file size.

04:04:20easeout too familiar for its own good
Oh, yeah, check out. I have checked out files in Perforce. So when was that that I used Perforce? Like 2005? Asked six years ago, is active storage that old?

04:05:02Real six and you know you're seeing an old answer when it's telling you about. chamlis_ I was thinking that you could have the equivalent of a zip-bomb that's a tiny file size but decompresses to a million-by-a-million image, but I'm not sure if they're real
In the future, five years ago. I see your concern, but. I don't think it's possible with images to do that. They're not a container format. easeout I'm hoping an image header would state its dimensions up front and get rejected early
And I mean, ImageMagick, one of the security bugs it has was, you say the image is 100 by 100, and then you overrun that, and you provide 300 by 300, and then you could overrun a buffer.

04:06:12Are you kidding? I'm hoping that there is another discussion somewhere and that this was just closed six years ago in favor of form validation. We could consider it form validation. Until a successful save on the associated record means that if a form submission fails validation, any new attachments will be lost. That's good, since direct uploads. What do you think direct uploads are? Directly from the client to the cloud. OK, fine. So I just do an active record. chamlis_ yeah hopefully you can filter that before it does any decoding
validation to look at those things, that's really not great.

04:07:19Well, it's not even decoding. It's what happens if somebody uploads an avatar that's 10 gigabytes or whatever the free disk space on prod is, is it going to frici Yeah ideally you want to limit avatars to some very reasonable size
allocate a max file size and just chew up all of my disk space because even just filling all of the disk because and the answer to the obvious question of how does someone know how much disk you have is they binary search by first they upload one gigabyte then two four eight sixteen and they do a binary search on how much disk size you have and then they fill it chamlis_ sorry, that's for the image-bomb case where it has large dimensions but a small size
justinhhorner Have to head out. Great to meet you all and hope to make it to the next stream. Take care o/
like you know i've said that things like justin nice to see you take care you're not missing too much i'm winding down especially if i'm going to be griping about rails just continuously for 20 minutes i'll just call it it's

04:08:44track the progress. Oh, this is just JS.

04:09:04So I'm wondering, so Shamless, one of the reasons I want to use vips is it's hardened against that kind of stuff. It was made to be used against hostile input from the first release. My concern right now is the much simpler case of what happens if someone uploads a 10 gigabyte image. chamlis_ I see, thanks
easeout same πŸ‘‹
And it really looks like if they do, the first thing that's going to happen is Rails is going to take the incoming form and persist it to disk. And as soon as it's persisted to disk, well, the whole fucking box is in trouble.

04:10:14chamlis_ can you configure nginx with a max body size?
I don't understand how this is not a... Now I'm tempted to go to Basecamp and upload, I don't know, a Blu-ray movie. Can I configure Nginx with a max body size? pro_noi_ac depending on the web server, is there a max post data limit?
Yes, probably. pro_noi_ac uh, what they said
Yeah, you got there too, huh? By default, it's a limit of one meg. That's... That might be true. Except... Yeah, so like the cat image I've been using to test with is 3.6 megs. So I know I'm not using Nginx in development mode.

04:11:58And I don't, well, let's go.

04:12:09Yeah, we don't even mention it in our config. So I guess the answer is limited in the web server. I am making an unsatisfied voice because it feels brittle, because it's going to be so far away from my code.

...50All right, so here's our NNX config.

...59We have various headers. We have a location. Do I have to put it in a location block? No. See, this was the thing I was going to be thinking of touching for

04:13:24Let's put it right next to this. It's going to make a little strict.

...59I feel like if you're only going to have a 300 by 300 images at most, or 384 by 384, a meg is reasonably healthy. We can make it two. Two is fine. We'll resize down.

04:14:20The way this name, so the Nginx docs, say it adjusts the file upload size, but the way it says body size makes it sound like it applies to the entire request. Guess that'll do it.

...52And I'm going to... pro_noi_ac try it with your gif first?
add that but i'm not going to commit it just yet because i'm going to come back to the ansible repo for production config to download all right so we've got a max file size so pronori i can't pro_noi_ac πŸ‘
really try it with my gif because in development we're talking directly to puma i'm not locally running nginx and it's fine that we don't match i would rather not force developers to install and configure nginx and then try and maintain it for a development mode and a production It's only these couple of kind of things where like file uploads and caches. I mean, you saw it in the, here we have a handful of thing like slash assets that works a little different in dev and prod. Avatars work a little different in dev and prod.

04:16:13Yeah. All right. So we get that one. We get this one for free because when we enforce, when we generate the image variance, I think we're going to, now I need to see it. I think we're going to get the file size by default or the dimension limit, because we're saying whatever you give us, what was that? Underscore fill. resize to fill, if necessary, will crop the image in a larger dimension. So it's just going to smash it.

04:17:02Yeah.

...09So the question I have is, How do I force Rails to generate all these variants immediately?

...22And I'm not going to add active job. That's just not going to happen. I think I'm going to just in the settings controller at upload time do this loop over all the variant records. It's concern about N plus one queries are if your remote service is far away and there are a lot, well, there's a bunch of round trips happening synchronously. This is all on disk. Image resizing is cheap. These will be basically instant. So I'm okay with having the settings controller spend the extra handful of milliseconds to immediately do it rather than add a whole job service and worry about whether those first couple of links Will dog pile? Yeah. This works fine for most cases. I dislike this kind of sentence because I look at this sentence and I immediately go, well, what are the cases where it doesn't? And I know I'm in one now, but you didn't really say anything.

04:18:44chamlis_ mostly harmless
Okay, I'm getting tired and I can tell I'm getting tired because I'm getting gripey. So I'm going to go ahead and call it. I feel like this is a good amount of progress on avatars, which is a much nicer thing than waiting until they break in production. Alrighty, unless there are any final questions, I'm going to go ahead and wind up the stream. Thanks for hanging out with me. I especially appreciate the many folks who kibitzed on corner cases or did you means. Those were all very useful. chamlis_ thanks!
frici That was indeed very productive, have a good rest of the Monday and week.
Thank you all for playing the silly little don't say the proper name game. It means a lot less work for me on the stream archive page. And especially thank you to the couple of folks who submitted pull requests. I really appreciate the contributions to the site. Take care, folks. See you on Thursday.