From f45eb0ce61cdca280ced6a0c25344507ced8db9b Mon Sep 17 00:00:00 2001 From: Idrees Hassan Date: Sat, 25 Oct 2025 20:40:25 -0400 Subject: [PATCH] Fix petting on mobile --- birb.js | 32 +++++++++++++++++++++--- build.js | 28 ++++++++++++++++++--- dist/birb.js | 32 +++++++++++++++++++++--- dist/birb.user.js | 34 +++++++++++++++++++++---- manifest.json | 63 ++++++++++++++++++++++++++--------------------- package.json | 2 +- 6 files changed, 146 insertions(+), 45 deletions(-) diff --git a/birb.js b/birb.js index 3e5de3b..831bf0a 100644 --- a/birb.js +++ b/birb.js @@ -943,6 +943,10 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI }); onClick(canvas, () => { + if (currentAnimation === Animations.HEART) { + // Currently being pet, don't open menu + return; + } insertMenu(); }); @@ -955,13 +959,17 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI } const pets = petStack.filter((time) => Date.now() - time < 1000).length; if (pets >= 3) { - setAnimation(Animations.HEART); + pet(); // Clear the stack petStack = []; } } }); + canvas.addEventListener("touchmove", (e) => { + pet(); + }); + drawStickyNotes(); let lastUrl = (window.location.href ?? "").split("?")[0]; @@ -1448,7 +1456,23 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI */ function onClick(element, action) { 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() { return document.documentElement.clientHeight; } - + function focusOnGround() { console.log("Focusing on ground"); focusedElement = null; @@ -1678,7 +1702,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI } function pet() { - if (currentState === States.IDLE) { + if (currentState === States.IDLE && currentAnimation !== Animations.HEART) { setAnimation(Animations.HEART); lastPetTimestamp = Date.now(); } diff --git a/build.js b/build.js index d40d8b5..3b95188 100644 --- a/build.js +++ b/build.js @@ -20,18 +20,40 @@ const spriteSheets = [ const STYLESHEET_PATH = "./stylesheet.css"; const STYLESHEET_KEY = "___STYLESHEET___"; -let version = "0.0.0"; -// Try to read version from manifest.json +const now = new Date(); +const versionDate = `${now.getFullYear()}.${now.getMonth() + 1}.${now.getDate()}`; +let buildNumber = 1; + +// Get build number from manifest.json try { const manifest = JSON.parse(readFileSync('manifest.json', 'utf8')); 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) { console.error("Could not read version from manifest.json"); 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 = `// ==UserScript== // @name Pocket Bird diff --git a/dist/birb.js b/dist/birb.js index 4c2d2ed..f38dca4 100644 --- a/dist/birb.js +++ b/dist/birb.js @@ -1286,6 +1286,10 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI }); onClick(canvas, () => { + if (currentAnimation === Animations.HEART) { + // Currently being pet, don't open menu + return; + } insertMenu(); }); @@ -1298,13 +1302,17 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI } const pets = petStack.filter((time) => Date.now() - time < 1000).length; if (pets >= 3) { - setAnimation(Animations.HEART); + pet(); // Clear the stack petStack = []; } } }); + canvas.addEventListener("touchmove", (e) => { + pet(); + }); + drawStickyNotes(); let lastUrl = (window.location.href ?? "").split("?")[0]; @@ -1791,7 +1799,23 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI */ function onClick(element, action) { 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() { return document.documentElement.clientHeight; } - + function focusOnGround() { console.log("Focusing on ground"); focusedElement = null; @@ -2021,7 +2045,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI } function pet() { - if (currentState === States.IDLE) { + if (currentState === States.IDLE && currentAnimation !== Animations.HEART) { setAnimation(Animations.HEART); lastPetTimestamp = Date.now(); } diff --git a/dist/birb.user.js b/dist/birb.user.js index 8666b1c..7eb5a87 100644 --- a/dist/birb.user.js +++ b/dist/birb.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Pocket Bird // @namespace https://idreesinc.com -// @version 2025.9.16.1 +// @version 2025.10.25.1 // @description birb // @author Idrees // @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, () => { + if (currentAnimation === Animations.HEART) { + // Currently being pet, don't open menu + return; + } insertMenu(); }); @@ -1312,13 +1316,17 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI } const pets = petStack.filter((time) => Date.now() - time < 1000).length; if (pets >= 3) { - setAnimation(Animations.HEART); + pet(); // Clear the stack petStack = []; } } }); + canvas.addEventListener("touchmove", (e) => { + pet(); + }); + drawStickyNotes(); let lastUrl = (window.location.href ?? "").split("?")[0]; @@ -1805,7 +1813,23 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI */ function onClick(element, action) { 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() { return document.documentElement.clientHeight; } - + function focusOnGround() { console.log("Focusing on ground"); focusedElement = null; @@ -2035,7 +2059,7 @@ Promise.all([loadSpriteSheetPixels(SPRITE_SHEET), loadSpriteSheetPixels(DECORATI } function pet() { - if (currentState === States.IDLE) { + if (currentState === States.IDLE && currentAnimation !== Animations.HEART) { setAnimation(Animations.HEART); lastPetTimestamp = Date.now(); } diff --git a/manifest.json b/manifest.json index cd3e701..4383718 100644 --- a/manifest.json +++ b/manifest.json @@ -1,29 +1,36 @@ { - "manifest_version": 3, - "name": "Pocket Bird", - "description": "It's a bird, in your browser. What more could you want?", - "version": "2025.9.16.1", - "homepage_url": "https://idreesinc.com", - "content_scripts": [ - { - "matches": [""], - "js": ["./dist/birb.js"] - } - ], - "permissions": [ - "storage", - "activeTab" - ], - "web_accessible_resources": [ - { - "resources": ["images/*"], - "matches": [""] - } - ], - "browser_specific_settings": { - "gecko": { - "id": "birb@idreesinc.com" - } - } -} - \ No newline at end of file + "manifest_version": 3, + "name": "Pocket Bird", + "description": "It's a bird, in your browser. What more could you want?", + "version": "2025.10.25.1", + "homepage_url": "https://idreesinc.com", + "content_scripts": [ + { + "matches": [ + "" + ], + "js": [ + "./dist/birb.js" + ] + } + ], + "permissions": [ + "storage", + "activeTab" + ], + "web_accessible_resources": [ + { + "resources": [ + "images/*" + ], + "matches": [ + "" + ] + } + ], + "browser_specific_settings": { + "gecko": { + "id": "birb@idreesinc.com" + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index 2e7ed7a..4b4f18e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "type": "module", "scripts": { "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": { "nodemon": "^3.1.10"