|
| 1 | +{ |
| 2 | + stdenv, |
| 3 | + lib, |
| 4 | + nodejs_20, |
| 5 | + pnpm_10, |
| 6 | + electron_34, |
| 7 | + python3, |
| 8 | + makeWrapper, |
| 9 | + callPackage, |
| 10 | + libpulseaudio, |
| 11 | + fetchFromGitHub, |
| 12 | + runCommand, |
| 13 | + fetchzip, |
| 14 | + autoPatchelfHook, |
| 15 | + makeDesktopItem, |
| 16 | + copyDesktopItems, |
| 17 | + replaceVars, |
| 18 | + noto-fonts-color-emoji, |
| 19 | + nixosTests, |
| 20 | + withAppleEmojis ? false, |
| 21 | +}: |
| 22 | +let |
| 23 | + nodejs = nodejs_20; |
| 24 | + pnpm = pnpm_10; |
| 25 | + electron = electron_34; |
| 26 | + |
| 27 | + electron-headers = runCommand "electron-headers" { } '' |
| 28 | + mkdir -p $out |
| 29 | + tar -C $out --strip-components=1 -xvf ${electron.headers} |
| 30 | + ''; |
| 31 | + |
| 32 | + sqlcipher-signal-extension = callPackage ./sqlcipher-signal-extension.nix { }; |
| 33 | + libsignal-node = callPackage ./libsignal-node.nix { inherit nodejs; }; |
| 34 | + |
| 35 | + ringrtc = stdenv.mkDerivation (finalAttrs: { |
| 36 | + pname = "ringrtc-bin"; |
| 37 | + version = "2.50.1"; |
| 38 | + src = fetchzip { |
| 39 | + url = "https://build-artifacts.signal.org/libraries/ringrtc-desktop-build-v${finalAttrs.version}.tar.gz"; |
| 40 | + hash = "sha256-KHNTw5ScBdYAAyKFdJ6PTmFr+7GYHqgnb4mmNUJZvzM="; |
| 41 | + }; |
| 42 | + |
| 43 | + installPhase = '' |
| 44 | + cp -r . $out |
| 45 | + ''; |
| 46 | + |
| 47 | + nativeBuildInputs = [ autoPatchelfHook ]; |
| 48 | + buildInputs = [ libpulseaudio ]; |
| 49 | + meta = { |
| 50 | + homepage = "https://github.com/signalapp/ringrtc"; |
| 51 | + license = lib.licenses.agpl3Only; |
| 52 | + sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; |
| 53 | + }; |
| 54 | + }); |
| 55 | + |
| 56 | + # Noto Color Emoji PNG files for emoji replacement; see below. |
| 57 | + noto-fonts-color-emoji-png = noto-fonts-color-emoji.overrideAttrs (prevAttrs: { |
| 58 | + pname = "noto-fonts-color-emoji-png"; |
| 59 | + |
| 60 | + # The build produces 136×128 PNGs by default for arcane font |
| 61 | + # reasons, but we want square PNGs. |
| 62 | + buildFlags = prevAttrs.buildFlags or [ ] ++ [ "BODY_DIMENSIONS=128x128" ]; |
| 63 | + |
| 64 | + makeTargets = [ "compressed" ]; |
| 65 | + |
| 66 | + installPhase = '' |
| 67 | + runHook preInstall |
| 68 | +
|
| 69 | + mkdir -p $out/share |
| 70 | + mv build/compressed_pngs $out/share/noto-fonts-color-emoji-png |
| 71 | + python3 add_aliases.py --srcdir=$out/share/noto-fonts-color-emoji-png |
| 72 | +
|
| 73 | + runHook postInstall |
| 74 | + ''; |
| 75 | + }); |
| 76 | + |
| 77 | +in |
| 78 | +stdenv.mkDerivation (finalAttrs: { |
| 79 | + pname = "signal-desktop-source"; |
| 80 | + version = "7.46.0"; |
| 81 | + |
| 82 | + src = fetchFromGitHub { |
| 83 | + owner = "signalapp"; |
| 84 | + repo = "Signal-Desktop"; |
| 85 | + tag = "v${finalAttrs.version}"; |
| 86 | + hash = "sha256-pV28jcIQcPjyZL8q+gisnlfAGf0SOKDQ7OxacTM3B0M="; |
| 87 | + }; |
| 88 | + |
| 89 | + nativeBuildInputs = [ |
| 90 | + nodejs |
| 91 | + (pnpm.override { inherit nodejs; }).configHook |
| 92 | + makeWrapper |
| 93 | + copyDesktopItems |
| 94 | + python3 |
| 95 | + ]; |
| 96 | + buildInputs = (lib.optional (!withAppleEmojis) noto-fonts-color-emoji-png); |
| 97 | + |
| 98 | + patches = lib.optional (!withAppleEmojis) ( |
| 99 | + replaceVars ./replace-apple-emoji-with-noto-emoji.patch { |
| 100 | + noto-emoji-pngs = "${noto-fonts-color-emoji-png}/share/noto-fonts-color-emoji-png"; |
| 101 | + } |
| 102 | + ); |
| 103 | + |
| 104 | + pnpmDeps = pnpm.fetchDeps { |
| 105 | + inherit (finalAttrs) |
| 106 | + pname |
| 107 | + version |
| 108 | + src |
| 109 | + patches |
| 110 | + ; |
| 111 | + hash = |
| 112 | + if withAppleEmojis then |
| 113 | + "sha256-keG+ymMD4ma0dt6N4Fai9u0+rh9VzkQD6tClPKoQXkM=" |
| 114 | + else |
| 115 | + "sha256-qImY0s8UQmuKGf8dvgO3YrJlrqqdoZtvbtLgvgMVnnE="; |
| 116 | + }; |
| 117 | + |
| 118 | + env = { |
| 119 | + ELECTRON_SKIP_BINARY_DOWNLOAD = "1"; |
| 120 | + SIGNAL_ENV = "production"; |
| 121 | + SOURCE_DATE_EPOCH = 1741810629; |
| 122 | + }; |
| 123 | + |
| 124 | + preBuild = '' |
| 125 | + cp ${sqlcipher-signal-extension}/share/sqlite3.gyp node_modules/@signalapp/better-sqlite3/deps/sqlite3.gyp |
| 126 | +
|
| 127 | + cp -r ${ringrtc} node_modules/@signalapp/ringrtc/build |
| 128 | +
|
| 129 | + rm -fr node_modules/@signalapp/libsignal-client/prebuilds |
| 130 | + cp -r ${libsignal-node}/lib node_modules/@signalapp/libsignal-client/prebuilds |
| 131 | + ''; |
| 132 | + |
| 133 | + buildPhase = '' |
| 134 | + runHook preBuild |
| 135 | +
|
| 136 | + export npm_config_nodedir=${electron-headers} |
| 137 | + cp -r ${electron.dist} electron-dist |
| 138 | + chmod -R u+w electron-dist |
| 139 | +
|
| 140 | + pnpm run generate |
| 141 | + pnpm exec electron-builder \ |
| 142 | + --dir \ |
| 143 | + --config.extraMetadata.environment=$SIGNAL_ENV \ |
| 144 | + -c.electronDist=electron-dist \ |
| 145 | + -c.electronVersion=${electron.version} |
| 146 | +
|
| 147 | + runHook postBuild |
| 148 | + ''; |
| 149 | + |
| 150 | + installPhase = '' |
| 151 | + runHook preInstall |
| 152 | +
|
| 153 | + mkdir -p $out/share/ |
| 154 | + cp -r dist/*-unpacked/resources $out/share/signal-desktop |
| 155 | +
|
| 156 | + for icon in build/icons/png/* |
| 157 | + do |
| 158 | + install -Dm644 $icon $out/share/icons/hicolor/`basename ''${icon%.png}`/apps/signal-desktop.png |
| 159 | + done |
| 160 | +
|
| 161 | + makeWrapper '${lib.getExe electron}' "$out/bin/signal-desktop" \ |
| 162 | + --add-flags "$out/share/signal-desktop/app.asar" \ |
| 163 | + --set-default ELECTRON_FORCE_IS_PACKAGED 1 \ |
| 164 | + --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}" |
| 165 | +
|
| 166 | + runHook postInstall |
| 167 | + ''; |
| 168 | + |
| 169 | + desktopItems = [ |
| 170 | + (makeDesktopItem { |
| 171 | + name = finalAttrs.pname; |
| 172 | + desktopName = "Signal"; |
| 173 | + exec = "${finalAttrs.meta.mainProgram} %U"; |
| 174 | + type = "Application"; |
| 175 | + terminal = false; |
| 176 | + icon = "signal-desktop"; |
| 177 | + comment = "Private messaging from your desktop"; |
| 178 | + startupWMClass = "signal"; |
| 179 | + mimeTypes = [ |
| 180 | + "x-scheme-handler/sgnl" |
| 181 | + "x-scheme-handler/signalcaptcha" |
| 182 | + ]; |
| 183 | + categories = [ |
| 184 | + "Network" |
| 185 | + "InstantMessaging" |
| 186 | + "Chat" |
| 187 | + ]; |
| 188 | + }) |
| 189 | + ]; |
| 190 | + |
| 191 | + passthru = { |
| 192 | + inherit sqlcipher-signal-extension libsignal-node; |
| 193 | + tests.application-launch = nixosTests.signal-desktop; |
| 194 | + }; |
| 195 | + |
| 196 | + meta = { |
| 197 | + description = "Private, simple, and secure messenger (nixpkgs build)"; |
| 198 | + longDescription = '' |
| 199 | + Signal Desktop is an Electron application that links with your |
| 200 | + "Signal Android" or "Signal iOS" app. |
| 201 | + ''; |
| 202 | + homepage = "https://signal.org/"; |
| 203 | + changelog = "https://github.com/signalapp/Signal-Desktop/releases/tag/v${finalAttrs.version}"; |
| 204 | + license = |
| 205 | + with lib.licenses; |
| 206 | + [ |
| 207 | + agpl3Only |
| 208 | + |
| 209 | + # Various npm packages |
| 210 | + free |
| 211 | + ] |
| 212 | + ++ lib.optional withAppleEmojis unfree; |
| 213 | + maintainers = with lib.maintainers; [ |
| 214 | + marcin-serwin |
| 215 | + ]; |
| 216 | + mainProgram = "signal-desktop"; |
| 217 | + platforms = [ |
| 218 | + "x86_64-linux" |
| 219 | + "aarch64-linux" |
| 220 | + ]; |
| 221 | + sourceProvenance = with lib.sourceTypes; [ |
| 222 | + fromSource |
| 223 | + |
| 224 | + # ringrtc |
| 225 | + binaryNativeCode |
| 226 | + ]; |
| 227 | + }; |
| 228 | +}) |
0 commit comments