Hello, cyberpals.
In the last video, we did some IMAP parser fixes and
I was hoping to get to showing a list of messages but we ran into
a weird bug at the end of the video.
So I guess we'll try and fix that today and hopefully
again, try and get the list of messages showing.
So let's dive right in.
So I think it was generating the list of--
of messages. So I guess we will break
in browser_sync_messages and see what's here.
Oh, and I want to move this mailbox
status checking. Well, we can just disable it for now because we
don't really care what mailboxes have new mail.
And I think I said that in the last video so before we even get anywhere,
let's just disable that.
Now, that would be in the IMAP and I think I was
putting it on like a timer. So as it runs through the state
handler, if it hasn't checked the statuses in quite a while,
we will do that.
Something like that?
So I'm going to say...
Okay let's try that.
Seems like it's taking longer than normal, like it was previously.
I don't know what that's about.
Okay. So...
That comment is wrong.
So this is hard coded to show 7 messages in the list.
I probably need to make that based
on the height of this, because you could theoretically resize that window
and show fewer, messages and mailboxes.
So we will step
through this and see what the first message is.
imap_mailbox_open
And see what is imap_mailbox_open
Should be a struct.
And message_count is 3, new_mail is 0.
This is a static array
of pointers to structs.
So we will say...
That should be a struct message.
Yep, and we get uid, date, which we're
not parsing yet, from, these should be strings.
Yep, and we need to strip out that those newlines.
Okay, so this should at least show
something, I guess.
And it did not-- I see-- no wait.
We had from, right?
from was a C string
That's weird. Why didn't it...
So if we do...
Okay that's weird, I don't know why the first one didn't--
what is this?
See, that is what I was saying earlier about our previous
video about jumping weird. There's no way that it could have
jumped to this line from here because
this is in the else. So, is it actually executing this? I don't know.
So this should actually,
since we only have three messages in the mailbox, that should break before
it gets to 7.
But, I wonder if I'm not zeroing.
Hi, Patrick.
Was there 3 messages or 2? Or 4? 3 or 4. There's 3.
Well, okay, I'm confused.
Yeah, see I don't think this is valid.
Yeah, it's all garbage, okay. So we should probably
just stop doing
anything when the message count is when
we reach the message count in here.
No, it was in...
If you hold down Option and click on the title bar,
you get all the includes that that C file does.
Okay, so if message_count
Right?
Okay, let's try that.
So this is just sticking the from, the sender in the list.
But we're eventually going to need to replace it with an LProc
function that will dynamically-- that will
call some compiled code that we stick in the resource fork
in the resource file that will actually
draw the message cell, so rather than
just handing it some text.
What?
Value has no members? Why?
Wrong variable name, stein.
imap_open_mailbox a function.
No, imap_open_mailbox is a function,
imap_mailbox_open is the mailbox that is open.
Kind of confusing.
Alright let's go.
I think we can just skip ahead to here and
if we get here, we probably are good.
And we are.
Okay, so that's good. We got our messages in
our list. There's only three messages in the mailbox.
Do I dare try and open another mailbox?
Hurrah. Okay, so it's
actually like working like an IMAP client now.
Oh, sad.
Alright, so we have some kind of error somewhere.
So that could be--
So it opened the mailbox, closed it, opened
another one, closed it and then got an error
when it opened a mailbox.
Let's check that imap_close_mailbox looks right.
[ mumbling ]
So that would be a browser_mouse_down.
This is from mailboxes_list. And then we do the same for messages_list.
Okay, LClick clicks on
something in the list which calls--
which just sets like the
LGetSelect changes what that function returns.
Er, we don't care about the message list, we care about the mailbox list.
Okay, so in mailbox, we highlight the
new cell and then try
and find the new mailbox to open.
And then that's it.
Because I guess in
the IMAP--
IMAP event loop, we--
yeah.
I don't know why that doesn't always work.
Okay, so we open if the mailbox is already-- if there's
already a mailbox open, we close it.
And we purge.
This should be a message count, correct?
Because messages is not dynamically--
[ mumbling ]
So this frees the strings that
we allocated and that
frees the message list.
And then this mallocs
a struct.
Oh right, because it's an array of pointers.
We did reuse that mailbox. I wonder if it's--
[ mumbling ]
[ more mumbling ]
This data thing has this context, so i is not there.
We want this, but a different context.
In the current context, I should say.
Oh I didn't know you could reset-- okay that's cool.
Where were we...
And then if we go back to the...
go to open a mailbox,
and then reopen a mailbox,
Oh,
when we close the mailbox,
the count is high.
because this has, like, 400 messages in it.
All right, so, when we
go to open another mailbox,
right.
I think I know
what it-- nope, I don't.
So this should only run like-- there's
only 7 messages that we loaded.
That we loaded envelope information for because that's
all we are showing here.
So this should only complete 7 times.
I don't know how
this Trace button is supposed to work.
I'll have to look that up. I thought it would just show
you each line as it's executing but I guess that's not what it does.
Where are we at here?
That should be zero.
Maybe that's why. Because we're trying to,
yeah, maybe we should check that messages[i] is not zero
first. What do you think?
Not sure why this is like vibrating
the camera now.
So ideally,
I want the list on the
right hand side to show from
subject, and maybe date, from
and subject. But the way that lists work
on the Mac toolbox,
you can do multi-column
lists, but only like if you think of
them like a spreadsheet. So you can only select one cell at
a time. If you want a row of
like you want like three columns,
but you want each one to act like its own row. So you click anywhere
in the cell in the first column,
it should highlight the entire row, if you want to do something
like that, and then you basically need to write your
own list definition procedure, which is
what I started working on for the mailbox list because I wanted
to show the name--
Okay? That's obviously goofed.
I wanted to show the mailbox name and then
the number of new messages in the mailbox.
And I had actually done that with just text. Like saying, you
know the width to cell and then
doing, like, trying to figure
out how many pixels a space is in the dynamic
width font and then moving over until you
get enough space to show like parentheses two, or something like
that. But it didn't look like how
I wanted. So I started doing the custom list
definition,
which you can-- I guess I will introduce that now. There's
actually two projects now, one is the mailbox
list definition and the main project.
And if you look in the resource file for
my application,
there is a LDEF resource and
it's just code-- executable code
and I saw that a long time ago. And I thought,
well, that seems kind of weird, how do you get executable code into a resource
file? Like you have to somehow copy
and paste it? Or is there like another utility that you use to stick
some kind of compiled thing in there.
But as it turns out, THINK C can
do all this for you. So you basically make a new project and
you set the project type
to a code resource. You set the type
to LDEF, which is what I'm using for a list definition.
And then the name, I
don't think matters and then the ID-- the ID has to match.
So I think how I did it is you go into the resident into
your resource file create a new list definition and get the
ID, but leave the actual like code thing empty.
And then you can create your new project set
the project type, set the ID, defaults to 128
and then set code resource. And now instead of
having Project -> Run, because it's that it's a code
resource, you just Build Code Resource.
And then that will compile it. And then it will ask where you want--
what resource value you want to put it into. And then you
just tell it your existing one, which is
the resource file. And then the Smart Link, Merge, just
to have those on. And then it will compile
it and then stick it all the code that it compiled
into your resource file. And so rather than
just, a, like main function,
that does your loop or whatever,
you just have the main.
And then the arguments that are passed from the toolbox
function that calls your list, that
calls this function, to draw the cell and it passes these parameters.
So it's kind of confusing. But once you get it, like all synced
up, it makes more sense. The only thing is it's like,
impossible to debug this because you can't just run a list
definition function. You have to--
you would have to open
your main project and then run it, and then see
your list definition function executed to see if it
draws your list. So you kind of have to keep switching back and forth between
the two projects as you're debugging and
so you kind of have to get creative with like,
in your list definition function,
if you want to print some debugging, thing like
set the title of the window to your little
debug string. That's something that I tried because,
like creating a little window and trying to draw text into it can get
kind of weird.
Here, I have this commented out so that it was doing the old
method of showing the mailbox list,
which is, you pass zero to the
LNew function, so the ID is zero.
And that uses the default list handler, which it
just draws whatever text you give it in the cell. So here
I'm just doing LSetCell mailbox name and then the built-in
list generation function
just takes that string and draws it in the cell.
So if we're using my custom one I'm setting the cell content
to just a pointer to the mailbox. And then in my
list definition function, I know that the data that is being passed to
that function is not string, it's the whole
struct. Then I can pull the the name and
the new count and whatever else I need out. So that
is how I was doing the list definition for
the mailboxes. And I think it was like
in a weird state when I first started these videos,
so it wasn't actually drawing anything. But I need to
make another one of those for the mail--
the message list so that I can show from, subject,
and the date.
So I just want to test that the previous fix to iterating
over the list of messages works when we open,
close, and then reopen a mailbox.
Because I think it was trying to dereference a pointer
to zero.
Or a null pointer.
Alright, so let's keep going.
So that works.
We don't need these anymore.
That works.
I'm like scared every time I see the debugger pop back up.
Okay, so that worked. But it didn't clear out these
other cells, which is weird.
Why did it do that? But it won't let me select them.
That's weird.
Well at least we are not like crashing anymore,
but it should be clearing that list when it switches
between mailboxes.
That was in... sync_messages
[ mumbling ]
Nope.
Hello? What are you doing here? What's going on?
Did we lock up? What's going on here.
That's weird, we're waiting for DNS to timeout.
Okay.
We should probably show that before we actually start doing anything.
Is my PPP session bogus?
That's weird, why didn't it do that on its own.
Something that I took away from Andreas' Serenity
development videos is like, if you encounter a bug and
it's not a serious bug, but it's not related to what you're
actually doing, like, just make a note of it and keep moving on.
Because I think normally I would have saw
that bug and think, oh, yeah, I need to change that string. And then you
go down that rabbit hole and soon, or like,
doing all these other things. And then it's
like yak shaving, you never get back to what you actually wanted
to do. Or at least I wouldn't in the time frame
that I have for lease videos. So I
guess I'm going to keep trying to do that and not get
sidetracked. Alright, so sync messages
that's going to go the first time.
And then we will open another mailbox and
go again.
This also needs to--
I'm only giving it 7 things because that's the only messages
that we got the envelopes for. But the list needs to know
about the full number of messages.
So that it can show the scroll bar. And then as you scroll,
I guess it would have to dynamically load those envelopes,
but I'm still not sure how best to do that,
because it's going to be slow.
We are in open mailbox.
Okay, so is clear set?
Should be.
So this delete should clear every--
clear all 7 of those from the previous mailbox.
It's kind of weird that it's not.
I wonder-- no,
that's invalidating the entire window.
I wonder if it's just a painting thing.
Okay,
And it is. That's weird.
So it did invalidate that. But when it repainted the
list, it didn't clear that out. I wonder if I am supposed
to do that.
Probably.
So that would be...
EraseRect I think.
I just want to hit Escape on the keyboard, there is no Escaping.
Okay, so when we,
I guess, either way,
we need to clear this
and that is the messages list.
No, that's...
I don't know why, some of this code I'm
getting from a book, so that's
why it's kind of formatted weird I'm just copying what they're
doing and not fully understanding
it until I reread it.
What? messages list rView right
and rView left.
Oh, because messages_list is a Handle,
so that's the double pointer thing.
So you have to dereference it. And then it's also
a pointer which
probably wants a
pointer.
Is that what we just...
Yeah that's what I just erased.
Am I crazy? Is that not what I pasted it the first time and
it balked at it? Whatever.
Alright let's see erasing the rectangle before
we redraw it works.
Okay, so now we're going to change mailboxes.
I want to see how this looks without interruptions.
There. Some kind of weird flashing, but we'll
need to figure out how to properly-- the proper like sequence
of redrawing this. But that was the error, we just needed to clear
this rectangle ourselves before redrawing it.
Okay, I guess I'm going to leave it there. So we're
actually showing stuff now. I guess in the next one, I'll try and
make a new list definition for this and start
showing like from, the subject, and the date. So that
will be the next video. So thanks for watching, bye.