Spyke

Replies

Comment on

New video: "What pisses me off about the failed Reddit protest..."

Reply in thread

While I do agree with you that spez fucking up like this was, in a way, an excellent thing for the internet, by "failed," he was referring to the mods who went back to Reddit. And it appears that there were lots of them. It's more about giving up so quickly and protesting in a weird way rather than some people starting to migrate to open platforms.


This is still a success for me! I've been a local Armenian Mastodon user for a long time. Then Elon took over Twitter, and many folks I was interested in following migrated to Mastodon, finally making me open up an international/English account there. And now this allowed me to replace Reddit with a federated FOSS, which is super-cool! I'm grateful for that, actually!

Comment on

Dart script managers

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

Comment on

what would you do as a beginner?

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.

Comment on

Using pattern matching feels great!

Reply in thread

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,
    };
  }