Fix petting on mobile

This commit is contained in:
Idrees Hassan
2025-10-25 20:40:25 -04:00
parent e55f0e7412
commit f45eb0ce61
6 changed files with 146 additions and 45 deletions

32
birb.js
View File

@@ -943,6 +943,10 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
}); });
onClick(canvas, () => { onClick(canvas, () => {
if (currentAnimation === Animations.HEART) {
// Currently being pet, don't open menu
return;
}
insertMenu(); insertMenu();
}); });
@@ -955,13 +959,17 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
} }
const pets = petStack.filter((time) => Date.now() - time < 1000).length; const pets = petStack.filter((time) => Date.now() - time < 1000).length;
if (pets >= 3) { if (pets >= 3) {
setAnimation(Animations.HEART); pet();
// Clear the stack // Clear the stack
petStack = []; petStack = [];
} }
} }
}); });
canvas.addEventListener("touchmove", (e) => {
pet();
});
drawStickyNotes(); drawStickyNotes();
let lastUrl = (window.location.href ?? "").split("?")[0]; let lastUrl = (window.location.href ?? "").split("?")[0];
@@ -1448,7 +1456,23 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
*/ */
function onClick(element, action) { function onClick(element, action) {
element.addEventListener("click", (e) => action(e)); element.addEventListener("click", (e) => action(e));
element.addEventListener("touchstart", (e) => action(e)); element.addEventListener("touchend", (e) => {
if (e instanceof TouchEvent === false) {
return;
} else if (element instanceof HTMLElement === false) {
return;
}
const touch = e.changedTouches[0];
const rect = element.getBoundingClientRect();
if (
touch.clientX >= rect.left &&
touch.clientX <= rect.right &&
touch.clientY >= rect.top &&
touch.clientY <= rect.bottom
) {
action(e);
}
});
} }
/** /**
@@ -1608,7 +1632,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
function getFullWindowHeight() { function getFullWindowHeight() {
return document.documentElement.clientHeight; return document.documentElement.clientHeight;
} }
function focusOnGround() { function focusOnGround() {
console.log("Focusing on ground"); console.log("Focusing on ground");
focusedElement = null; focusedElement = null;
@@ -1678,7 +1702,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
} }
function pet() { function pet() {
if (currentState === States.IDLE) { if (currentState === States.IDLE && currentAnimation !== Animations.HEART) {
setAnimation(Animations.HEART); setAnimation(Animations.HEART);
lastPetTimestamp = Date.now(); lastPetTimestamp = Date.now();
} }

View File

@@ -20,18 +20,40 @@ const spriteSheets = [
const STYLESHEET_PATH = "./stylesheet.css"; const STYLESHEET_PATH = "./stylesheet.css";
const STYLESHEET_KEY = "___STYLESHEET___"; const STYLESHEET_KEY = "___STYLESHEET___";
let version = "0.0.0"; const now = new Date();
// Try to read version from manifest.json const versionDate = `${now.getFullYear()}.${now.getMonth() + 1}.${now.getDate()}`;
let buildNumber = 1;
// Get build number from manifest.json
try { try {
const manifest = JSON.parse(readFileSync('manifest.json', 'utf8')); const manifest = JSON.parse(readFileSync('manifest.json', 'utf8'));
if (manifest.version) { if (manifest.version) {
version = manifest.version; if (manifest.version.startsWith(versionDate)) {
// Same day, increment build number
const parts = manifest.version.split('.');
if (parts.length === 4) {
buildNumber = parseInt(parts[3], 10) + 1;
}
}
} }
} catch (e) { } catch (e) {
console.error("Could not read version from manifest.json"); console.error("Could not read version from manifest.json");
throw e; throw e;
} }
const version = `${versionDate}.${buildNumber}`;
// Update manifest.json with new version
try {
const manifest = JSON.parse(readFileSync('manifest.json', 'utf8'));
manifest.version = version;
writeFileSync('manifest.json', JSON.stringify(manifest, null, 4), 'utf8');
} catch (e) {
console.error("Could not update version in manifest.json");
throw e;
}
const userScriptHeader = const userScriptHeader =
`// ==UserScript== `// ==UserScript==
// @name Pocket Bird // @name Pocket Bird

32
dist/birb.js vendored
View File

@@ -1286,6 +1286,10 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
}); });
onClick(canvas, () => { onClick(canvas, () => {
if (currentAnimation === Animations.HEART) {
// Currently being pet, don't open menu
return;
}
insertMenu(); insertMenu();
}); });
@@ -1298,13 +1302,17 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
} }
const pets = petStack.filter((time) => Date.now() - time < 1000).length; const pets = petStack.filter((time) => Date.now() - time < 1000).length;
if (pets >= 3) { if (pets >= 3) {
setAnimation(Animations.HEART); pet();
// Clear the stack // Clear the stack
petStack = []; petStack = [];
} }
} }
}); });
canvas.addEventListener("touchmove", (e) => {
pet();
});
drawStickyNotes(); drawStickyNotes();
let lastUrl = (window.location.href ?? "").split("?")[0]; let lastUrl = (window.location.href ?? "").split("?")[0];
@@ -1791,7 +1799,23 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
*/ */
function onClick(element, action) { function onClick(element, action) {
element.addEventListener("click", (e) => action(e)); element.addEventListener("click", (e) => action(e));
element.addEventListener("touchstart", (e) => action(e)); element.addEventListener("touchend", (e) => {
if (e instanceof TouchEvent === false) {
return;
} else if (element instanceof HTMLElement === false) {
return;
}
const touch = e.changedTouches[0];
const rect = element.getBoundingClientRect();
if (
touch.clientX >= rect.left &&
touch.clientX <= rect.right &&
touch.clientY >= rect.top &&
touch.clientY <= rect.bottom
) {
action(e);
}
});
} }
/** /**
@@ -1951,7 +1975,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
function getFullWindowHeight() { function getFullWindowHeight() {
return document.documentElement.clientHeight; return document.documentElement.clientHeight;
} }
function focusOnGround() { function focusOnGround() {
console.log("Focusing on ground"); console.log("Focusing on ground");
focusedElement = null; focusedElement = null;
@@ -2021,7 +2045,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
} }
function pet() { function pet() {
if (currentState === States.IDLE) { if (currentState === States.IDLE && currentAnimation !== Animations.HEART) {
setAnimation(Animations.HEART); setAnimation(Animations.HEART);
lastPetTimestamp = Date.now(); lastPetTimestamp = Date.now();
} }

34
dist/birb.user.js vendored
View File

@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name Pocket Bird // @name Pocket Bird
// @namespace https://idreesinc.com // @namespace https://idreesinc.com
// @version 2025.9.16.1 // @version 2025.10.25.1
// @description birb // @description birb
// @author Idrees // @author Idrees
// @downloadURL https://github.com/IdreesInc/Pocket-Bird/raw/refs/heads/main/dist/birb.user.js // @downloadURL https://github.com/IdreesInc/Pocket-Bird/raw/refs/heads/main/dist/birb.user.js
@@ -1300,6 +1300,10 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
}); });
onClick(canvas, () => { onClick(canvas, () => {
if (currentAnimation === Animations.HEART) {
// Currently being pet, don't open menu
return;
}
insertMenu(); insertMenu();
}); });
@@ -1312,13 +1316,17 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
} }
const pets = petStack.filter((time) => Date.now() - time < 1000).length; const pets = petStack.filter((time) => Date.now() - time < 1000).length;
if (pets >= 3) { if (pets >= 3) {
setAnimation(Animations.HEART); pet();
// Clear the stack // Clear the stack
petStack = []; petStack = [];
} }
} }
}); });
canvas.addEventListener("touchmove", (e) => {
pet();
});
drawStickyNotes(); drawStickyNotes();
let lastUrl = (window.location.href ?? "").split("?")[0]; let lastUrl = (window.location.href ?? "").split("?")[0];
@@ -1805,7 +1813,23 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
*/ */
function onClick(element, action) { function onClick(element, action) {
element.addEventListener("click", (e) => action(e)); element.addEventListener("click", (e) => action(e));
element.addEventListener("touchstart", (e) => action(e)); element.addEventListener("touchend", (e) => {
if (e instanceof TouchEvent === false) {
return;
} else if (element instanceof HTMLElement === false) {
return;
}
const touch = e.changedTouches[0];
const rect = element.getBoundingClientRect();
if (
touch.clientX >= rect.left &&
touch.clientX <= rect.right &&
touch.clientY >= rect.top &&
touch.clientY <= rect.bottom
) {
action(e);
}
});
} }
/** /**
@@ -1965,7 +1989,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
function getFullWindowHeight() { function getFullWindowHeight() {
return document.documentElement.clientHeight; return document.documentElement.clientHeight;
} }
function focusOnGround() { function focusOnGround() {
console.log("Focusing on ground"); console.log("Focusing on ground");
focusedElement = null; focusedElement = null;
@@ -2035,7 +2059,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI
} }
function pet() { function pet() {
if (currentState === States.IDLE) { if (currentState === States.IDLE && currentAnimation !== Animations.HEART) {
setAnimation(Animations.HEART); setAnimation(Animations.HEART);
lastPetTimestamp = Date.now(); lastPetTimestamp = Date.now();
} }

View File

@@ -1,29 +1,36 @@
{ {
"manifest_version": 3, "manifest_version": 3,
"name": "Pocket Bird", "name": "Pocket Bird",
"description": "It's a bird, in your browser. What more could you want?", "description": "It's a bird, in your browser. What more could you want?",
"version": "2025.9.16.1", "version": "2025.10.25.1",
"homepage_url": "https://idreesinc.com", "homepage_url": "https://idreesinc.com",
"content_scripts": [ "content_scripts": [
{ {
"matches": ["<all_urls>"], "matches": [
"js": ["./dist/birb.js"] "<all_urls>"
} ],
], "js": [
"permissions": [ "./dist/birb.js"
"storage", ]
"activeTab" }
], ],
"web_accessible_resources": [ "permissions": [
{ "storage",
"resources": ["images/*"], "activeTab"
"matches": ["<all_urls>"] ],
} "web_accessible_resources": [
], {
"browser_specific_settings": { "resources": [
"gecko": { "images/*"
"id": "birb@idreesinc.com" ],
} "matches": [
} "<all_urls>"
} ]
}
],
"browser_specific_settings": {
"gecko": {
"id": "birb@idreesinc.com"
}
}
}

View File

@@ -7,7 +7,7 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "node build.js", "build": "node build.js",
"dev": "nodemon --watch birb.js --watch stylesheet.css --watch build.js --watch manifest.json --exec \"npm run build\"" "dev": "nodemon --watch birb.js --watch stylesheet.css --watch build.js --exec \"npm run build\""
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^3.1.10" "nodemon": "^3.1.10"