I build Flutter apps & packages, Neovim plugins, and a bunch of other stuff. I love good software, and I love the internet.
☮️ 🛸 💾
🇦🇲 Based in Yerevan, Armenia
Hi! This may sound weird but consider watching the “Halt and Catch Fire” show. It does an excellent job of showing the thing’s passionate, emotional, and personal parts. And it could lead to some ideas. It could help with the drive. It definitely made me realize how software, the idea of software is inherently essential to me.
Oh, yeah, this is a good one!
Why are these bot operators going through the hassle of joining existing instances
I wonder if there’s already a “the bots are from Reddit” conspiracy :D
I really see no point in these actions. I mean, seriously, why would you want to just harm something open?
There’s an open-source and privacy-oriented userscript manager for Chrome(ium) called ViolentMonkey. Highly recommended using that!
Replied above for a better comment hierarchy. Feel free to comment there if you have any questions/thoughts!
It’s also worth noting that freezed is switching to the Dart 3 pattern matching, too (see https://pub.dev/packages/freezed#legacy-union-types-and-sealed-classes).
Anyways, I think this is a matter of preference, and I’ve been historically avoiding codegen as much as possible. I’m glad it’s now easier to do that, but freezed is still cool and could be really helpful for certain people/scenarios!
Since there are too many examples on the freezed README and the one at the top isn’t a good use case to begin with (I like to keep my data models (DTOs) separate from entities, and DTOs are good enough with plain json_serializable
), I’ll provide an example from one of the projects I’m currently working on. It is still more verbose than it would usually be with freezed, however, I’m pretty fine with that. Also, it’s worth noting that whenever I need a copyWith
, I still use codegen with copy_with_extension. It has a nicer copyWith
API and only handles that instead of a bunch of other stuff I don’t necessarily need.
part of 'simply_browser_bloc.dart';
sealed class SimplyBrowserState with EquatableMixin {
const SimplyBrowserState();
}
class SimplyBrowserInitial extends SimplyBrowserState {
const SimplyBrowserInitial();
@override
List<Object?> get props => const [];
}
class SimplyBrowserLoading extends SimplyBrowserState {
const SimplyBrowserLoading({this.loadedSimplies});
final List<Simply>? loadedSimplies;
@override
List<Object?> get props => const [];
}
class SimplyBrowserFailed extends SimplyBrowserState {
const SimplyBrowserFailed(this.failure);
final ApiFailure failure;
@override
List<Object?> get props => [failure];
}
class SimplyBrowserLoaded extends SimplyBrowserState {
const SimplyBrowserLoaded({
required this.canLoadMore,
required this.simplies,
});
final bool canLoadMore;
final List<Simply> simplies;
@override
List<Object?> get props => [simplies];
}
And then using the sealed class itself becomes super-nice, like the following snippet (only wrapped in a function to state clearly where the variable is coming from):
List<Simply>? getSimplies(SimplyBrowserState state) {
return switch (state) {
SimplyBrowserLoading(:final loadedSimplies) => loadedSimplies,
SimplyBrowserLoaded(:final simplies) => simplies,
_ => null,
};
}
Love the “aa-aa-a” so much!
I wonder if it provides better completions than Copilot currently does
It’s also funny how the boys were resisting singing & dancing to the end in Elementary School Musical but had the whole fingerbang thingie earlier :)
I’ve been using makefiles for a while and find them pretty good. The only downside is adding any arguments to recipes (passed when executing them) is tricky. On the other hand, there was only one scenario where that could be useful (release-staging
from below), but I managed to get what I wanted without arguments.
I like makefiles for portability and automatic shell completion for fish.
Here’s a Makefile from one of the projects I’m working on to give a better idea of my usage:
QA_TARGET := "lib/main_qa.dart"
PROD_TARGET := "lib/main_prod.dart"
get-packages:
flutter pub get
code-generation:
dart run build_runner build --delete-conflicting-outputs
localizations:
dart run intl_utils:generate
apk-qa:
flutter build apk --target $(QA_TARGET)
appbundle-prod:
flutter build appbundle --target $(PROD_TARGET)
ipa-qa:
flutter build ipa --target $(QA_TARGET)
ipa-prod:
flutter build ipa --target $(PROD_TARGET)
launcher-icons:
dart run flutter_launcher_icons
release-staging:
$(eval DIFF := $(shell git diff -- pubspec.yaml | grep '^+version'))
@if [ -z "$(DIFF)" ]; then \
echo "Error: No changes in version. Aborting."; \
exit 1; \
fi
@OTHER_DIFF=$$(git diff -- './*' ':!pubspec.yaml'); \
if [ -n "$$OTHER_DIFF" ]; then \
echo "Error: Changes found outside of pubspec.yaml. Aborting."; \
exit 1; \
fi;
$(eval VERSION := $(shell awk '/^version: / {print $$2}' pubspec.yaml))
$(eval LAST_RELEASE_HASH := $(shell git log --pretty=format:'%H %s' | grep 'chore(build): Bump build number to' | awk 'NR==1{print $$1}'))
$(eval CHANGES := $(shell git log --pretty=format:'\n- %s' $(LAST_RELEASE_HASH)...HEAD))
@echo "chore(build): Bump build number to $(VERSION)\n\nChanges:$(CHANGES)" > commit_msg.txt
@echo "Releasing version $(VERSION) to STAGING"
git add pubspec.yaml
git commit -F commit_msg.txt
rm commit_msg.txt
git tag v$(VERSION)
git push
git push --tags