Coding with Claude

I tried using cursor-ai for some time, basically for HTML, CSS, a bit of vanilla JavaScript, and Tailwind, not bad at all with the above, but later, after two weeks, the limit became unusable, turns out the “Free” comes with a 2 week free trial

Without it, you are switched from Claude to “Cursor-small” in the CTRL+L menu, and the autocomplete stops working

In any case, I think subscribing to cursor-ai is a good idea, the time it saves you writing things that are not core to your work is well worth it, but I wanted to experiment with something new, so….

Cursor-AI is basically a modified VS Code, and since Claude 3.5 Sonnet seems to be my favorite coding AI, i researched a bit and found that there is a plugin for VS-Code that does the same if I subscribe to Anthropic API !

So, after getting my API key from anthropic (the people behind Claude), all i needed to do was install a plugin (Tried more than one plugin, CodeGPT, and Cline by Saoud Rizwan), once installed, I need to enter my API key into the settings, and that is it.

Cline suits my needs better than CodeGPT for the time being, but i did not use them extensively yet, so it is too early to declare a winner

Moving from gmail to cpanel

Like thousands of people online… when google decided that my domain’s email is no longer hosted for free, I spent a good year or two paying for the email accounts I have, and if like me, you only need gmail for the sake of email, paying this much for email, a technology from 1971 is a crazy !

If you are the domain admin on google workspaces, you probably know that google will allow you to “Take Out” all the data from all accounts on that domain, I will assume you already did that and you have the file (All mail Including Spam and Trash.mbox).

In a different post, I showed you how to do this with dovecot’s own tools to simply copy the files, but that assumes you run your own server ! this post is for the average user, this is the for dummies of moving email from google gmail (Takout for example) to ANY email account on any platform using a nail clipper and some old socks, just kidding, you only need the socks

So, I decided to move all accounts to a server with cpanel, which is a solid solution.

So i started with my email account, it was very straight forward with mutt (apt install mutt), configure my account, then mount the mbox file and push it all to the server

mutt -f ~/takeout.mbox (T to select all messages)

But you are probably on Windows, so for your sake, I did the second account with software that works on windows, so start by downloading and installing thunderbird, once installed, setup your account, with cpanel and most other providers, all you need to know is your name, email address, and password, thunderbird should be able to find the config for your server automatically πŸ˜‰ (If you are wondering, Your server publishes it’s own config and thunderbird finds it through the email’s domain)

So, now you can see all the new emails that arrived to the new server, once that happens, close thunderbird, then navigate to your thunderbird profile folder, in my case it is at

~/.thunderbird/RANDOMLETTERS.default-default/Mail/Local Folders

But since you are on windows, it would probably be somewhere inside “roaming/thunderbird/profiles”, shouldn’t be hard to find, once inside your profile, go to /Mail/Local Folders and paste the mbox file you have, start thunderbird and it should display the MBOX file on the left panel under “Local Folders”

Once that happens, you can select the messages you want to move (If you are moving thousands of messages, i would recommend you move them in batches, not all at once), right click, then go to the moveto menu that appears, and select the account/mailbox you want them moved to, and watch them move…

Done ?

Now, you can use FTP to see your mail which should be in the devicot folders, (They are not called devicot folders, it is called maildir, but because you are running devicot, I don’t like to add jargon too quickly)

new, cur, and tmp

other files reference devicot, so we know what we have

Notes

If you need to create a new thundirbird profile, under linux you need to start thunderbird with the following command

thunderbird -ProfileManager

Under windows, the profiles page is on the Help -> Troubleshooting information menu !

Audio breaking and noisy on debian 12

I am not sure that this problem is specific to my setup, where my audio comes from an nvidia 1650 passed through to a KVM virtual machine, but it seems that many people on bare metal are having this problem too

The problem occures randomly, and when it does, pipewire would be consuming a lot of CPU even though no audio is running

pipewire for those of you who don’t know is the new pulse audio, it comes with most modern distributions !

The solution when this happens for now sems to be to restart pipewire !

systemctl --user restart pipewire.service

Flutter “no ScrollPosition attached” SOLVED

════════════ Exception caught by animation library ════════════════
The Scrollbar's ScrollController has no ScrollPosition attached.

The solution to this problem turned out to be, to assign the same scroll controller that I have assigned to the ListView.builder to the Scrollbar !

This problem didn’t exist not long ago, but since the solution is simple, here is a sample code snippet !

So the code to fix was simply this

Widget _buildParticipantDisplay() {
return Scrollbar(
interactive: true,
controller: scrollController,
child: ListView.builder(
itemCount: participants.length,
controller: scrollController,
itemExtent: 60,
itemBuilder: (context, index) {
return ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 50),
title: Text('participant: ${index + 1}'),
trailing: Text(participants[index]),
);
},
),
);
}

Button types in flutter

It should be button shapes or designs, since buttons in flutter all basically work the same way, except for DropDownButton, it is a bit different !

  • ElevatedButton
  • TextButton
  • IconButton: An icon is added to your text button !
  • FloatingActionButton: a circular icon button that hovers over content to promote a primary action in the application. (official Youtube)
  • OutlinedButton: a TextButton with an outlined border
  • DropDownButton: Allow the user to select from a list of values ! (Official Youtube)
  • CupertinoButton: A button in iOS style !

ButtonStyle IS DEPRECATED !, use WidgetStateProperty (Just replace this class name with that) to set (backgroundColor and foregroundColor) , everything else is identical….

ButtonStyle Class

style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.green),
foregroundColor:
MaterialStateProperty.all<Color>(Colors.white),
),

Instead, use

style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all<Color>(Colors.green),
foregroundColor:
WidgetStateProperty.all<Color>(Colors.white),
),

styleFrom() method

ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
textStyle:
TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
),
)

Server backends in Dart

  • Shelf: Dart library that gives you a simple web server and framework, almost official (pub.dev is built upon it), and very similar to express.js is you come from JavaScript
  • Dart Frog: A fast minimalistic backend for Dart (Built on shelf)
  • ServerPod: Probably the most elaborate one, A base ready to deploy (Registration for example)
    Existing peices work with Postgres and Redis
    Terraform google cloud engine for serverpod
  • Serveme:
  • Alfred:

I don’t really use Dart for backend, even though it was part of google’s original plan, Here I am listing the popular frameworks just in case, but the echosystem is small, and that is the problem with using Dart for backend !

I am moving towards RUST for backend (Yes, as weird as it sounds), Rust has quite a few backends, And i think rocket is going to be the one,

As a C developer, I never used Dragon, So why use RUST, well, as it turns out, RUST is different

5 PORT, 4K hdmi switch

The only way i got this 5 port, 4K HDMI switch to behave is by combining it with dummy HDMI adapters (here), In my setup, they are limited to 30FPS (Not sure if this switch can handle more, but the dummy HDMI adapter itself is limited to 30FPS at 4K)

Once the adapters are at the endings of all 5 input cables, the switch works perfectly, but what happens without them

Without them, there are a couple of problems, the PCs switch the video output off, and there is a delay before it comes back once it detects a screen has been connected again, so you keep clicking till you get lucky with the monitor you are looking for, not to mention that in the case of multiple monitors, the operating system keeps changing the monitor setup assuming that screens are coming and going !

the switch comes with a handy remote control (That i don’t use because the button is right here in front of me), but it will be handy in case you are using a PC that is relatively far

Also worth noting is that it can identify which screen are connected, so you do not need to go through all 5 inputs if only 2 are connected, it will only switch between those two

in any case, let me know in the comments if you have any questions

Bottom Sheets

Bottom sheets are like toasts in the sense that they allow the user to keep doing what they are doing, but different, they are the notifications that appear at the bottom of the screen that a user can dismiss, they (like toasts) also don’t block the current screen

The global function (showBottomSheet or modalBottomSheet) expects a BuildContext and a WidgetBuilder. The modal displays over UI elements, so keep that in mind

the WidgetBuilder (That closure you should be familiar with from alerts for example, or a full fledged function definition, your choice) and the build context (you should have been passing around already by now) are straight forward, what is not is that a bottom sheet must be called with a context that contains a Scaffold. in other words, you’ll have to be β€œunder” a scaffold widget… so to rephrase, it shows a Material Design bottom sheet in the nearest [Scaffold] ancestor

Now, to understand the problem, the context we are passing around as we put it in the last paragraph, belongs to the top-level widget, that widget has a scaffold obviously, but the scaffold is under it, when our bottom sheet wants to attach to a widget, using the of-context pattern to find the scaffold will fail as we are looking up the tree not down where the scaffold is !

Detect platform in flutter

Sometimes, you need to know what operating system your flutter app is running on, most times for theming purposes, but sometimes for functionalities !

There are basically 2 popular ways to do this (3 popular methods if you are willing to use a package specifically to simplify theme issues !), let us assume we will be calling a certain method called _iosMethod if we are on iOS, and a _genericMethod if we are on any other platform

The most common use case is to determine whether to use Material or Cupertino, to give the application that native look the users are used to… in any case… here are the two methods

In both methods, we have a function called doStuff

Method 1

In the first method, we get the platform using the Theme (We must pass context to function) !
The ThemeData object has an enum called TargetPlatform… we will use that here

  void doStuff(BuildContext context) {
final platform = Theme.of(context).platform;
if (platform == TargetPlatform.iOS) {
_iosMethod(context);
} else {
_genericMethod(context);
}
}

The possible options that can come out of this enum are (android, iOS, linux, macOS, windows, fuchsia)

Method 2

Here, we can simply start by importing (import ‘dart:io’ show Platform;), then use it directly

import 'dart:io' show Platform;
...
...
void doStuff(BuildContext context) {
if (Platform.isIOS) {
_iosMethod(context);
} else {
_genericMethod(context);
}
}

Method 3

This time, we will be using the package (flutter_platform_widgets), this package is very useful for theming your application to have the look and feel of the default theme of the OS…

things become very simple with this package, all you need is the line

return PlatformElevatedButton(onPressed: onPressed, child: child);