add automated screenshots, fastlane metadata, and appstream metainfo

Fixes #174, fixes #173, fixes #172
This commit is contained in:
Henry Hiles 2026-11-12 12:48:30 -05:00
commit c93004f060
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
4 changed files with 870 additions and 103 deletions

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>nexus.federated.nexus</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0-only</project_license>
<name>Nexus</name>
<summary>A simple and user-friendly Matrix client</summary>
<developer id="nexus.federated">
<name>QuadRadical</name>
</developer>
<description>
<p>
Nexus is a simple and user-friendly client for Matrix, the open and
decentralized chat network. It's made with Flutter, with gomuks handling
the Matrix side.
</p>
<p>Features include:</p>
<ul>
<li>Spaces, threads, replies and reactions</li>
<li>End-to-end encryption, with verification and recovery keys</li>
<li>Polls, location sharing, and custom emoji and sticker packs</li>
<li>Multiple accounts</li>
<li>Notifications through UnifiedPush</li>
<li>Layouts for phones and desktops, including Linux phones</li>
</ul>
</description>
<launchable type="desktop-id">nexus.federated.nexus.desktop</launchable>
<url type="homepage">https://git.federated.nexus/Nexus/nexus</url>
<url type="bugtracker">https://git.federated.nexus/Nexus/nexus/issues</url>
<url type="vcs-browser">https://git.federated.nexus/Nexus/nexus</url>
<!-- Generated by `nix run .#screenshots` -->
<screenshots>
<screenshot type="default">
<caption>Chatting in a room, with its members</caption>
<image>https://git.federated.nexus/Nexus/nexus/raw/branch/main/assets/screenshots/desktop-light.png</image>
</screenshot>
<screenshot>
<caption>The same, in dark mode</caption>
<image>https://git.federated.nexus/Nexus/nexus/raw/branch/main/assets/screenshots/desktop-dark.png</image>
</screenshot>
<screenshot>
<caption>Chatting on a phone</caption>
<image>https://git.federated.nexus/Nexus/nexus/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png</image>
</screenshot>
<screenshot>
<caption>Spaces and rooms on a phone</caption>
<image>https://git.federated.nexus/Nexus/nexus/raw/branch/main/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png</image>
</screenshot>
</screenshots>
<requires>
<display_length compare="ge">360</display_length>
</requires>
<supports>
<control>keyboard</control>
<control>pointing</control>
<control>touch</control>
</supports>
<content_rating type="oars-1.1">
<content_attribute id="social-chat">intense</content_attribute>
<content_attribute id="social-location">intense</content_attribute>
</content_rating>
<releases>
<release version="1.1.0" date="2026-11-11"/>
<release version="1.0.1" date="2026-10-25"/>
<release version="1.0.0" date="2026-10-22"/>
</releases>
</component>

View file

@ -71,6 +71,39 @@
runtimeEnv = buildEnv.env;
text = builtins.readFile ./e2e.sh;
};
screenshots = pkgs.writeShellApplication {
name = "nexus-screenshots";
runtimeInputs =
buildEnv.packages
++ (with pkgs; [
dbus
oxipng
pngquant
]);
runtimeEnv = buildEnv.env;
text = builtins.readFile ./screenshots.sh;
};
headless =
program:
lib.getExe (
pkgs.writeShellApplication {
name = "${lib.getName program}-headless";
runtimeInputs = [ pkgs.cage ];
runtimeEnv = {
WLR_BACKENDS = "headless";
__EGL_VENDOR_LIBRARY_FILENAMES = "${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json";
};
text = ''
unset DISPLAY WAYLAND_DISPLAY
# Wayland needs one, which CI may not have
XDG_RUNTIME_DIR="''${XDG_RUNTIME_DIR:-$(mktemp -d)}"
export XDG_RUNTIME_DIR
exec cage -- ${lib.getExe program} "$@"
'';
}
);
in
{
e2e = {
@ -98,24 +131,12 @@
e2e-headless = {
type = "app";
program = lib.getExe (
pkgs.writeShellApplication {
name = "nexus-e2e-headless";
runtimeInputs = [ pkgs.cage ];
runtimeEnv = {
WLR_BACKENDS = "headless";
__EGL_VENDOR_LIBRARY_FILENAMES = "${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json";
};
text = ''
unset DISPLAY WAYLAND_DISPLAY
# Wayland needs one, which CI may not have
XDG_RUNTIME_DIR="''${XDG_RUNTIME_DIR:-$(mktemp -d)}"
export XDG_RUNTIME_DIR
program = headless e2e;
};
exec cage -- ${lib.getExe e2e} "$@"
'';
}
);
screenshots = {
type = "app";
program = headless screenshots;
};
};
};

View file

@ -70,6 +70,7 @@ flutter.buildFlutterApplication {
postInstall = ''
install -D assets/bundled/icon.svg $out/share/icons/hicolor/scalable/apps/nexus.svg
install -Dm755 linux/*.desktop -t $out/share/applications
install -Dm644 linux/*.metainfo.xml -t $out/share/metainfo
install -Dm644 linux/*.service -t $out/share/dbus-1/services
# better_player loads libmpv at runtime to play videos, and audioplayers
# needs GStreamer's plugins to decode audio
@ -93,6 +94,7 @@ flutter.buildFlutterApplication {
meta = {
description = "A simple and user-friendly Matrix client";
license = lib.licenses.gpl3Only;
mainProgram = "nexus";
platforms = lib.platforms.unix;

30
linux/nix/screenshots.sh Normal file
View file

@ -0,0 +1,30 @@
# shellcheck shell=bash
# Regenerates the README, AppStream and Fastlane screenshots, from
# integration_test/screenshots. Run it from the repo root.
work="$(mktemp -d)"
# shellcheck disable=SC2329 # Run by the trap
cleanup() { rm -rf "$work"; }
trap cleanup EXIT
GOCACHE="$(go env GOCACHE)"
export GOCACHE
XDG_DATA_HOME="$work/data" XDG_CACHE_HOME="$work/cache" \
dbus-run-session -- \
flutter test integration_test/screenshots/screenshots_test.dart -d linux \
--dart-define="SCREENSHOTS_DIR=$work/out" "$@"
for shot in "$work"/out/*.png; do
pngquant --quality 65-95 --speed 1 --strip --force --ext .png "$shot"
oxipng --quiet --opt 4 --strip safe "$shot"
done
install -Dm644 "$work"/out/desktop-*.png -t assets/screenshots
phone=fastlane/metadata/android/en-US/images/phoneScreenshots
install -Dm644 "$work/out/phone-chat-light.png" "$phone/1.png"
install -Dm644 "$work/out/phone-chat-dark.png" "$phone/2.png"
install -Dm644 "$work/out/phone-rooms-light.png" "$phone/3.png"
install -Dm644 "$work/out/phone-rooms-dark.png" "$phone/4.png"