Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Release

on:
push:
branches:
- main

jobs:
release:
runs-on: ubuntu-latest

permissions:
contents: write

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: yarn install

- name: Install vsce
run: npm install -g @vscode/vsce

- name: Compile extension
run: yarn compile

- name: Package extension
run: vsce package

- name: Get version and package name
id: meta
run: |
VERSION=$(node -p "require('./package.json').version")
NAME=$(node -p "require('./package.json').name")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "vsix=${NAME}-${VERSION}.vsix" >> $GITHUB_OUTPUT

- name: Create or update release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.meta.outputs.version }}
name: v${{ steps.meta.outputs.version }}
files: ${{ steps.meta.outputs.vsix }}
make_latest: true
8 changes: 8 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
"npm: watch-tests"
],
"problemMatcher": []
},
{
"type": "npm",
"script": "compile",
"group": "build",
"problemMatcher": [],
"label": "npm: compile",
"detail": "webpack"
}
]
}
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "FAAA",
"description": "Plays FAAA when a command fails. You deserve it.",
"version": "0.0.4",
"publisher": "AviSharma",
"publisher": "kierandrewett",
"icon": "images/icon.png",
"engines": {
"vscode": "^1.93.0"
Expand All @@ -17,9 +17,16 @@
"main": "./dist/extension.js",
"repository": {
"type": "git",
"url": "https://github.com/AviSharmaaa/faaa"
"url": "https://github.com/kierandrewett/faaa"
},
"contributes": {
"commands": [
{
"command": "faaa.setVolume",
"title": "FAAA: Set Volume"
}
]
},
"contributes": {},
"scripts": {
"compile": "webpack",
"watch": "webpack --watch"
Expand Down
Binary file added sounds/faaa-0.mp3
Binary file not shown.
Binary file added sounds/faaa-1.mp3
Binary file not shown.
Binary file added sounds/faaa-2.mp3
Binary file not shown.
Binary file added sounds/faaa-3.mp3
Binary file not shown.
Binary file added sounds/faaa-4.mp3
Binary file not shown.
Binary file removed sounds/faaa.mp3
Binary file not shown.
110 changes: 88 additions & 22 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,104 @@
import * as vscode from "vscode";
import * as path from "path";
import * as cp from "child_process";
import * as crypto from "crypto";

const sounds = [
"faaa-0.mp3",
"faaa-1.mp3",
"faaa-2.mp3",
"faaa-3.mp3",
"faaa-4.mp3",
];

const VOLUME_KEY = "faaa.volume";

const VOLUME_OPTIONS = [
{ label: "🔇 Mute", value: 0 },
{ label: "🔈 25%", value: 0.25 },
{ label: "🔉 50%", value: 0.5 },
{ label: "🔊 75%", value: 0.75 },
{ label: "🔊 100%", value: 1.0 },
];

function volumeLabel(volume: number): string {
if (volume === 0) return "🔇 FAAA";
if (volume <= 0.25) return "🔈 FAAA 25%";
if (volume <= 0.5) return "🔉 FAAA 50%";
if (volume <= 0.75) return "🔊 FAAA 75%";
return "🔊 FAAA 100%";
}

export function activate(context: vscode.ExtensionContext) {
console.log("FAAA is watching your failures 👀");

const soundPath = path.join(context.extensionPath, "sounds", "faaa.mp3");
let volume: number = context.globalState.get<number>(VOLUME_KEY) ?? 1.0;

// Status bar item
const statusBarItem = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Right,
100,
);
statusBarItem.command = "faaa.setVolume";
statusBarItem.tooltip = "FAAA: Click to change volume";
statusBarItem.text = volumeLabel(volume);
statusBarItem.show();
context.subscriptions.push(statusBarItem);

// Command to pick volume
context.subscriptions.push(
vscode.commands.registerCommand("faaa.setVolume", async () => {
const picked = await vscode.window.showQuickPick(
VOLUME_OPTIONS.map((o) => ({
...o,
description: o.value === volume ? "current" : undefined,
})),
{ title: "FAAA Volume", placeHolder: "Select volume level" },
);
if (!picked) return;
volume = picked.value;
context.globalState.update(VOLUME_KEY, volume);
statusBarItem.text = volumeLabel(volume);
}),
);

function playSound() {
if (volume === 0) return;

const soundName = sounds[crypto.randomInt(0, sounds.length)];
const soundPath = path.join(context.extensionPath, "sounds", soundName);
const platform = process.platform;
let cmd: string;

if (platform === "darwin") {
// afplay -v: 0.0–1.0 (and beyond), default 1.0
cmd = `afplay -v ${volume} "${soundPath}"`;
} else if (platform === "linux") {
// mpg123 -f: scale factor 0–32768 (32768 = 100%)
const mpgScale = Math.round(volume * 32768);
// ffplay -volume: 0–100
const ffVolume = Math.round(volume * 100);
// paplay --volume: 0–65536
const paVolume = Math.round(volume * 65536);
cmd = `mpg123 -q -f ${mpgScale} "${soundPath}" 2>/dev/null || ffplay -nodisp -autoexit -volume ${ffVolume} "${soundPath}" 2>/dev/null || paplay --volume=${paVolume} "${soundPath}" 2>/dev/null || aplay "${soundPath}" 2>/dev/null`;
} else if (platform === "win32") {
cmd = `powershell -c "$p = New-Object System.Windows.Media.MediaPlayer; $p.Open('${soundPath}'); $p.Volume = ${volume}; $p.Play(); Start-Sleep 3"`;
} else {
return;
}

cp.exec(cmd, (err) => {
if (err) console.error("FAAA failed to FAAA:", err.message);
});
}

// Method 1: VS Code Task failures
context.subscriptions.push(
vscode.tasks.onDidEndTaskProcess((e) => {
if (e.exitCode === undefined || e.exitCode === 0) return;
if (e.exitCode === 130) return;

playSound(soundPath);
playSound();
}),
);

Expand Down Expand Up @@ -50,28 +135,9 @@ export function activate(context: vscode.ExtensionContext) {
];
if (ignore.some((c) => cmd.startsWith(c))) return;

playSound(soundPath);
playSound();
}),
);
}

function playSound(filePath: string) {
const platform = process.platform;
let cmd: string;

if (platform === "darwin") {
cmd = `afplay "${filePath}"`;
} else if (platform === "linux") {
cmd = `mpg123 -q "${filePath}" 2>/dev/null || aplay "${filePath}"`;
} else if (platform === "win32") {
cmd = `powershell -c "$p = New-Object System.Windows.Media.MediaPlayer; $p.Open('${filePath}'); $p.Play(); Start-Sleep 3"`;
} else {
return;
}

cp.exec(cmd, (err) => {
if (err) console.error("FAAA failed to FAAA:", err.message);
});
}

export function deactivate() {}
Loading