Add chirping when pet

This commit is contained in:
Idrees Hassan
2026-01-04 17:34:34 -05:00
parent b8de14bb94
commit 5a82ba858f
10 changed files with 285 additions and 9 deletions

BIN
dist/extension.zip vendored

Binary file not shown.

View File

@@ -857,6 +857,49 @@
}
}
// @ts-check
class Birdsong {
/**
* @type {AudioContext}
*/
audioContext;
chirp() {
if (!this.audioContext) {
this.audioContext = new AudioContext();
}
const TIMES = [0, 0.06, 0.16];
const FREQUENCIES = [2200,
3500 + Math.random() * 700,
1600 + Math.random() * 400];
const VOLUMES = [0.0001, 0.3, 0.0001];
const oscillator = this.audioContext.createOscillator();
oscillator.type = "sine";
const gain = this.audioContext.createGain();
oscillator.connect(gain);
gain.connect(this.audioContext.destination);
const now = this.audioContext.currentTime;
for (let i = 0; i < TIMES.length; i++) {
const time = TIMES[i] + now;
if (i === 0) {
oscillator.frequency.setValueAtTime(FREQUENCIES[i], time);
gain.gain.setValueAtTime(VOLUMES[i], time);
} else {
oscillator.frequency.exponentialRampToValueAtTime(FREQUENCIES[i], time);
gain.gain.exponentialRampToValueAtTime(VOLUMES[i], time);
}
}
oscillator.start(now);
oscillator.stop(now + TIMES[TIMES.length - 1]);
}
}
const SAVE_KEY = "birbSaveData";
/**
@@ -1819,7 +1862,7 @@
insertModal(`${birdBirb()} Mode`, message);
}),
new Separator(),
new MenuItem("2026.1.1", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.1"); }, false),
new MenuItem("2026.1.4", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.4"); }, false),
];
const styleElement = document.createElement("style");
@@ -1833,6 +1876,8 @@
FLYING: "flying",
};
const birdsong = new Birdsong();
let frozen = false;
let stateStart = Date.now();
let currentState = States.IDLE;
@@ -2513,6 +2558,7 @@
function pet() {
if (currentState === States.IDLE && birb.getCurrentAnimation() !== Animations.HEART) {
birdsong.chirp();
birb.setAnimation(Animations.HEART);
lastPetTimestamp = Date.now();
}

View File

@@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "Pocket Bird",
"description": "It's a pet bird in your browser, what more could you want?",
"version": "2026.1.1",
"version": "2026.1.4",
"homepage_url": "https://idreesinc.com",
"icons": {
"48": "images/icons/transparent/48x48x1.png",

50
dist/obsidian/main.js vendored
View File

@@ -1,7 +1,7 @@
const { Plugin, Notice } = require('obsidian');
module.exports = class PocketBird extends Plugin {
onload() {
console.log("Loading Pocket Bird version 2026.1.1...");
console.log("Loading Pocket Bird version 2026.1.4...");
const OBSIDIAN_PLUGIN = this;
(function () {
'use strict';
@@ -862,6 +862,49 @@ module.exports = class PocketBird extends Plugin {
}
}
// @ts-check
class Birdsong {
/**
* @type {AudioContext}
*/
audioContext;
chirp() {
if (!this.audioContext) {
this.audioContext = new AudioContext();
}
const TIMES = [0, 0.06, 0.16];
const FREQUENCIES = [2200,
3500 + Math.random() * 700,
1600 + Math.random() * 400];
const VOLUMES = [0.0001, 0.3, 0.0001];
const oscillator = this.audioContext.createOscillator();
oscillator.type = "sine";
const gain = this.audioContext.createGain();
oscillator.connect(gain);
gain.connect(this.audioContext.destination);
const now = this.audioContext.currentTime;
for (let i = 0; i < TIMES.length; i++) {
const time = TIMES[i] + now;
if (i === 0) {
oscillator.frequency.setValueAtTime(FREQUENCIES[i], time);
gain.gain.setValueAtTime(VOLUMES[i], time);
} else {
oscillator.frequency.exponentialRampToValueAtTime(FREQUENCIES[i], time);
gain.gain.exponentialRampToValueAtTime(VOLUMES[i], time);
}
}
oscillator.start(now);
oscillator.stop(now + TIMES[TIMES.length - 1]);
}
}
const ROOT_PATH = "";
/**
@@ -1862,7 +1905,7 @@ module.exports = class PocketBird extends Plugin {
insertModal(`${birdBirb()} Mode`, message);
}),
new Separator(),
new MenuItem("2026.1.1", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.1"); }, false),
new MenuItem("2026.1.4", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.4"); }, false),
];
const styleElement = document.createElement("style");
@@ -1876,6 +1919,8 @@ module.exports = class PocketBird extends Plugin {
FLYING: "flying",
};
const birdsong = new Birdsong();
let frozen = false;
let stateStart = Date.now();
let currentState = States.IDLE;
@@ -2556,6 +2601,7 @@ module.exports = class PocketBird extends Plugin {
function pet() {
if (currentState === States.IDLE && birb.getCurrentAnimation() !== Animations.HEART) {
birdsong.chirp();
birb.setAnimation(Animations.HEART);
lastPetTimestamp = Date.now();
}

View File

@@ -1,7 +1,7 @@
{
"id": "pocket-bird",
"name": "Pocket Bird",
"version": "2026.1.1",
"version": "2026.1.4",
"minAppVersion": "0.15.0",
"description": "Add a pet bird to fly around your notes and keep you company!",
"author": "Idrees Hassan",

View File

@@ -1,7 +1,7 @@
// ==UserScript==
// @name Pocket Bird
// @namespace https://idreesinc.com
// @version 2026.1.1
// @version 2026.1.4
// @description It's a pet bird in your browser, what more could you want?
// @author Idrees
// @downloadURL https://github.com/IdreesInc/Pocket-Bird/raw/refs/heads/main/dist/userscript/birb.user.js
@@ -871,6 +871,49 @@
}
}
// @ts-check
class Birdsong {
/**
* @type {AudioContext}
*/
audioContext;
chirp() {
if (!this.audioContext) {
this.audioContext = new AudioContext();
}
const TIMES = [0, 0.06, 0.16];
const FREQUENCIES = [2200,
3500 + Math.random() * 700,
1600 + Math.random() * 400];
const VOLUMES = [0.0001, 0.3, 0.0001];
const oscillator = this.audioContext.createOscillator();
oscillator.type = "sine";
const gain = this.audioContext.createGain();
oscillator.connect(gain);
gain.connect(this.audioContext.destination);
const now = this.audioContext.currentTime;
for (let i = 0; i < TIMES.length; i++) {
const time = TIMES[i] + now;
if (i === 0) {
oscillator.frequency.setValueAtTime(FREQUENCIES[i], time);
gain.gain.setValueAtTime(VOLUMES[i], time);
} else {
oscillator.frequency.exponentialRampToValueAtTime(FREQUENCIES[i], time);
gain.gain.exponentialRampToValueAtTime(VOLUMES[i], time);
}
}
oscillator.start(now);
oscillator.stop(now + TIMES[TIMES.length - 1]);
}
}
const SAVE_KEY = "birbSaveData";
/**
@@ -1824,7 +1867,7 @@
insertModal(`${birdBirb()} Mode`, message);
}),
new Separator(),
new MenuItem("2026.1.1", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.1"); }, false),
new MenuItem("2026.1.4", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.4"); }, false),
];
const styleElement = document.createElement("style");
@@ -1838,6 +1881,8 @@
FLYING: "flying",
};
const birdsong = new Birdsong();
let frozen = false;
let stateStart = Date.now();
let currentState = States.IDLE;
@@ -2518,6 +2563,7 @@
function pet() {
if (currentState === States.IDLE && birb.getCurrentAnimation() !== Animations.HEART) {
birdsong.chirp();
birb.setAnimation(Animations.HEART);
lastPetTimestamp = Date.now();
}

View File

@@ -857,6 +857,49 @@
}
}
// @ts-check
class Birdsong {
/**
* @type {AudioContext}
*/
audioContext;
chirp() {
if (!this.audioContext) {
this.audioContext = new AudioContext();
}
const TIMES = [0, 0.06, 0.16];
const FREQUENCIES = [2200,
3500 + Math.random() * 700,
1600 + Math.random() * 400];
const VOLUMES = [0.0001, 0.3, 0.0001];
const oscillator = this.audioContext.createOscillator();
oscillator.type = "sine";
const gain = this.audioContext.createGain();
oscillator.connect(gain);
gain.connect(this.audioContext.destination);
const now = this.audioContext.currentTime;
for (let i = 0; i < TIMES.length; i++) {
const time = TIMES[i] + now;
if (i === 0) {
oscillator.frequency.setValueAtTime(FREQUENCIES[i], time);
gain.gain.setValueAtTime(VOLUMES[i], time);
} else {
oscillator.frequency.exponentialRampToValueAtTime(FREQUENCIES[i], time);
gain.gain.exponentialRampToValueAtTime(VOLUMES[i], time);
}
}
oscillator.start(now);
oscillator.stop(now + TIMES[TIMES.length - 1]);
}
}
const SAVE_KEY = "birbSaveData";
/**
@@ -1804,7 +1847,7 @@
insertModal(`${birdBirb()} Mode`, message);
}),
new Separator(),
new MenuItem("2026.1.1", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.1"); }, false),
new MenuItem("2026.1.4", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.4"); }, false),
];
const styleElement = document.createElement("style");
@@ -1818,6 +1861,8 @@
FLYING: "flying",
};
const birdsong = new Birdsong();
let frozen = false;
let stateStart = Date.now();
let currentState = States.IDLE;
@@ -2498,6 +2543,7 @@
function pet() {
if (currentState === States.IDLE && birb.getCurrentAnimation() !== Animations.HEART) {
birdsong.chirp();
birb.setAnimation(Animations.HEART);
lastPetTimestamp = Date.now();
}

48
dist/web/birb.js vendored
View File

@@ -857,6 +857,49 @@
}
}
// @ts-check
class Birdsong {
/**
* @type {AudioContext}
*/
audioContext;
chirp() {
if (!this.audioContext) {
this.audioContext = new AudioContext();
}
const TIMES = [0, 0.06, 0.16];
const FREQUENCIES = [2200,
3500 + Math.random() * 700,
1600 + Math.random() * 400];
const VOLUMES = [0.0001, 0.3, 0.0001];
const oscillator = this.audioContext.createOscillator();
oscillator.type = "sine";
const gain = this.audioContext.createGain();
oscillator.connect(gain);
gain.connect(this.audioContext.destination);
const now = this.audioContext.currentTime;
for (let i = 0; i < TIMES.length; i++) {
const time = TIMES[i] + now;
if (i === 0) {
oscillator.frequency.setValueAtTime(FREQUENCIES[i], time);
gain.gain.setValueAtTime(VOLUMES[i], time);
} else {
oscillator.frequency.exponentialRampToValueAtTime(FREQUENCIES[i], time);
gain.gain.exponentialRampToValueAtTime(VOLUMES[i], time);
}
}
oscillator.start(now);
oscillator.stop(now + TIMES[TIMES.length - 1]);
}
}
const SAVE_KEY = "birbSaveData";
/**
@@ -1804,7 +1847,7 @@
insertModal(`${birdBirb()} Mode`, message);
}),
new Separator(),
new MenuItem("2026.1.1", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.1"); }, false),
new MenuItem("2026.1.4", () => { alert("Thank you for using Pocket Bird! You are on version: 2026.1.4"); }, false),
];
const styleElement = document.createElement("style");
@@ -1818,6 +1861,8 @@
FLYING: "flying",
};
const birdsong = new Birdsong();
let frozen = false;
let stateStart = Date.now();
let currentState = States.IDLE;
@@ -2498,6 +2543,7 @@
function pet() {
if (currentState === States.IDLE && birb.getCurrentAnimation() !== Animations.HEART) {
birdsong.chirp();
birb.setAnimation(Animations.HEART);
lastPetTimestamp = Date.now();
}