Add sticky note support to obsidian

This commit is contained in:
Idrees Hassan
2025-11-14 00:06:49 -05:00
parent 3ec124a1b3
commit 7639c7c36a
12 changed files with 253 additions and 68 deletions

63
dist/birb.js vendored
View File

@@ -70,8 +70,9 @@
* @param {HTMLElement|null} element The element to detect drag events on * @param {HTMLElement|null} element The element to detect drag events on
* @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {boolean} [parent] Whether to move the parent element when the child is dragged
* @param {(top: number, left: number) => void} [callback] Callback for when element is moved * @param {(top: number, left: number) => void} [callback] Callback for when element is moved
* @param {HTMLElement} [pageElement] The page element to constrain movement within
*/ */
function makeDraggable(element, parent = true, callback = () => { }) { function makeDraggable(element, parent = true, callback = () => { }, pageElement) {
if (!element) { if (!element) {
return; return;
} }
@@ -117,9 +118,12 @@
}); });
document.addEventListener("mousemove", (e) => { document.addEventListener("mousemove", (e) => {
const page = pageElement || document.documentElement;
const maxX = page.scrollWidth - elementToMove.clientWidth;
const maxY = page.scrollHeight - elementToMove.clientHeight;
if (isMouseDown) { if (isMouseDown) {
elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`;
elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`;
} }
}); });
@@ -840,6 +844,7 @@
} }
const SAVE_KEY = "birbSaveData"; const SAVE_KEY = "birbSaveData";
const ROOT_PATH = "";
/** /**
* @typedef {import('./application.js').BirbSaveData} BirbSaveData * @typedef {import('./application.js').BirbSaveData} BirbSaveData
@@ -1070,7 +1075,6 @@
} }
class ObsidianContext extends Context { class ObsidianContext extends Context {
/** /**
* @override * @override
* @returns {boolean} * @returns {boolean}
@@ -1085,8 +1089,12 @@
* @returns {Promise<BirbSaveData|{}>} * @returns {Promise<BirbSaveData|{}>}
*/ */
async getSaveData() { async getSaveData() {
// @ts-expect-error return new Promise((resolve) => {
return await OBSIDIAN_PLUGIN.loadData() ?? {}; // @ts-expect-error
OBSIDIAN_PLUGIN.loadData().then((data) => {
resolve(data ?? {});
});
});
} }
/** /**
@@ -1095,7 +1103,7 @@
*/ */
async putSaveData(saveData) { async putSaveData(saveData) {
// @ts-expect-error // @ts-expect-error
return await OBSIDIAN_PLUGIN.saveData(saveData); await OBSIDIAN_PLUGIN.saveData(saveData);
} }
/** @override */ /** @override */
@@ -1116,8 +1124,36 @@
} }
/** @override */ /** @override */
areStickyNotesEnabled() { getPath() {
return false; // @ts-expect-error
const file = app.workspace.getActiveFile();
if (file && this.getActiveEditorElement()) {
return file.path;
} else {
return ROOT_PATH;
}
}
/** @override */
getActivePage() {
if (this.getPath() === ROOT_PATH) {
// Root page, use document element
return document.documentElement
}
return this.getActiveEditorElement() ?? document.documentElement;
}
/** @override */
isPathApplicable(path) {
return path === this.getPath();
}
/** @returns {HTMLElement|null} */
getActiveEditorElement() {
// @ts-expect-error
const activeLeaf = app.workspace.activeLeaf;
const leafElement = activeLeaf?.view?.containerEl;
return leafElement?.querySelector(".cm-scroller") ?? null;
} }
} }
@@ -1217,7 +1253,7 @@
stickyNote.top = top; stickyNote.top = top;
stickyNote.left = left; stickyNote.left = left;
onSave(); onSave();
}); }, page);
if (closeButton) { if (closeButton) {
makeClosable(() => { makeClosable(() => {
@@ -1574,6 +1610,7 @@
flex-grow: 1; flex-grow: 1;
user-select: none; user-select: none;
color: var(--birb-background-color); color: var(--birb-background-color);
white-space: nowrap;
} }
.birb-window-close { .birb-window-close {
@@ -1815,7 +1852,7 @@
const AFK_TIME = isDebug() ? 0 : 1000 * 5; const AFK_TIME = isDebug() ? 0 : 1000 * 5;
const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5;
const PET_MENU_COOLDOWN = 1000; const PET_MENU_COOLDOWN = 1000;
const URL_CHECK_INTERVAL = 500; const URL_CHECK_INTERVAL = 250;
const HOP_DELAY = 500; const HOP_DELAY = 500;
// Random event chances per tick // Random event chances per tick
@@ -1957,7 +1994,7 @@
insertModal(`${birdBirb()} Mode`, message); insertModal(`${birdBirb()} Mode`, message);
}), }),
new Separator(), new Separator(),
new MenuItem("2025.11.13.80", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.80"); }, false), new MenuItem("2025.11.14.16", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.14.16"); }, false),
]; ];
const styleElement = document.createElement("style"); const styleElement = document.createElement("style");
@@ -2156,7 +2193,7 @@
setInterval(() => { setInterval(() => {
const currentPath = getContext().getPath().split("?")[0]; const currentPath = getContext().getPath().split("?")[0];
if (currentPath !== lastPath) { if (currentPath !== lastPath) {
log("Path changed, updating sticky notes"); log("Path changed, updating sticky notes: " + currentPath);
lastPath = currentPath; lastPath = currentPath;
drawStickyNotes(stickyNotes, save, deleteStickyNote); drawStickyNotes(stickyNotes, save, deleteStickyNote);
} }

BIN
dist/extension.zip vendored

Binary file not shown.

View File

@@ -70,8 +70,9 @@
* @param {HTMLElement|null} element The element to detect drag events on * @param {HTMLElement|null} element The element to detect drag events on
* @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {boolean} [parent] Whether to move the parent element when the child is dragged
* @param {(top: number, left: number) => void} [callback] Callback for when element is moved * @param {(top: number, left: number) => void} [callback] Callback for when element is moved
* @param {HTMLElement} [pageElement] The page element to constrain movement within
*/ */
function makeDraggable(element, parent = true, callback = () => { }) { function makeDraggable(element, parent = true, callback = () => { }, pageElement) {
if (!element) { if (!element) {
return; return;
} }
@@ -117,9 +118,12 @@
}); });
document.addEventListener("mousemove", (e) => { document.addEventListener("mousemove", (e) => {
const page = pageElement || document.documentElement;
const maxX = page.scrollWidth - elementToMove.clientWidth;
const maxY = page.scrollHeight - elementToMove.clientHeight;
if (isMouseDown) { if (isMouseDown) {
elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`;
elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`;
} }
}); });
@@ -840,6 +844,7 @@
} }
const SAVE_KEY = "birbSaveData"; const SAVE_KEY = "birbSaveData";
const ROOT_PATH = "";
/** /**
* @typedef {import('./application.js').BirbSaveData} BirbSaveData * @typedef {import('./application.js').BirbSaveData} BirbSaveData
@@ -1070,7 +1075,6 @@
} }
class ObsidianContext extends Context { class ObsidianContext extends Context {
/** /**
* @override * @override
* @returns {boolean} * @returns {boolean}
@@ -1085,8 +1089,12 @@
* @returns {Promise<BirbSaveData|{}>} * @returns {Promise<BirbSaveData|{}>}
*/ */
async getSaveData() { async getSaveData() {
// @ts-expect-error return new Promise((resolve) => {
return await OBSIDIAN_PLUGIN.loadData() ?? {}; // @ts-expect-error
OBSIDIAN_PLUGIN.loadData().then((data) => {
resolve(data ?? {});
});
});
} }
/** /**
@@ -1095,7 +1103,7 @@
*/ */
async putSaveData(saveData) { async putSaveData(saveData) {
// @ts-expect-error // @ts-expect-error
return await OBSIDIAN_PLUGIN.saveData(saveData); await OBSIDIAN_PLUGIN.saveData(saveData);
} }
/** @override */ /** @override */
@@ -1116,8 +1124,36 @@
} }
/** @override */ /** @override */
areStickyNotesEnabled() { getPath() {
return false; // @ts-expect-error
const file = app.workspace.getActiveFile();
if (file && this.getActiveEditorElement()) {
return file.path;
} else {
return ROOT_PATH;
}
}
/** @override */
getActivePage() {
if (this.getPath() === ROOT_PATH) {
// Root page, use document element
return document.documentElement
}
return this.getActiveEditorElement() ?? document.documentElement;
}
/** @override */
isPathApplicable(path) {
return path === this.getPath();
}
/** @returns {HTMLElement|null} */
getActiveEditorElement() {
// @ts-expect-error
const activeLeaf = app.workspace.activeLeaf;
const leafElement = activeLeaf?.view?.containerEl;
return leafElement?.querySelector(".cm-scroller") ?? null;
} }
} }
@@ -1217,7 +1253,7 @@
stickyNote.top = top; stickyNote.top = top;
stickyNote.left = left; stickyNote.left = left;
onSave(); onSave();
}); }, page);
if (closeButton) { if (closeButton) {
makeClosable(() => { makeClosable(() => {
@@ -1574,6 +1610,7 @@
flex-grow: 1; flex-grow: 1;
user-select: none; user-select: none;
color: var(--birb-background-color); color: var(--birb-background-color);
white-space: nowrap;
} }
.birb-window-close { .birb-window-close {
@@ -1815,7 +1852,7 @@
const AFK_TIME = isDebug() ? 0 : 1000 * 5; const AFK_TIME = isDebug() ? 0 : 1000 * 5;
const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5;
const PET_MENU_COOLDOWN = 1000; const PET_MENU_COOLDOWN = 1000;
const URL_CHECK_INTERVAL = 500; const URL_CHECK_INTERVAL = 250;
const HOP_DELAY = 500; const HOP_DELAY = 500;
// Random event chances per tick // Random event chances per tick
@@ -1957,7 +1994,7 @@
insertModal(`${birdBirb()} Mode`, message); insertModal(`${birdBirb()} Mode`, message);
}), }),
new Separator(), new Separator(),
new MenuItem("2025.11.13.80", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.80"); }, false), new MenuItem("2025.11.14.16", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.14.16"); }, false),
]; ];
const styleElement = document.createElement("style"); const styleElement = document.createElement("style");
@@ -2156,7 +2193,7 @@
setInterval(() => { setInterval(() => {
const currentPath = getContext().getPath().split("?")[0]; const currentPath = getContext().getPath().split("?")[0];
if (currentPath !== lastPath) { if (currentPath !== lastPath) {
log("Path changed, updating sticky notes"); log("Path changed, updating sticky notes: " + currentPath);
lastPath = currentPath; lastPath = currentPath;
drawStickyNotes(stickyNotes, save, deleteStickyNote); drawStickyNotes(stickyNotes, save, deleteStickyNote);
} }

View File

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

65
dist/obsidian/main.js vendored
View File

@@ -2,7 +2,7 @@
const { Plugin, Notice } = require('obsidian'); const { Plugin, Notice } = require('obsidian');
module.exports = class PocketBird extends Plugin { module.exports = class PocketBird extends Plugin {
onload() { onload() {
console.log("Loading Pocket Bird version 2025.11.13.80..."); console.log("Loading Pocket Bird version 2025.11.14.16...");
const OBSIDIAN_PLUGIN = this; const OBSIDIAN_PLUGIN = this;
(function () { (function () {
'use strict'; 'use strict';
@@ -76,8 +76,9 @@ module.exports = class PocketBird extends Plugin {
* @param {HTMLElement|null} element The element to detect drag events on * @param {HTMLElement|null} element The element to detect drag events on
* @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {boolean} [parent] Whether to move the parent element when the child is dragged
* @param {(top: number, left: number) => void} [callback] Callback for when element is moved * @param {(top: number, left: number) => void} [callback] Callback for when element is moved
* @param {HTMLElement} [pageElement] The page element to constrain movement within
*/ */
function makeDraggable(element, parent = true, callback = () => { }) { function makeDraggable(element, parent = true, callback = () => { }, pageElement) {
if (!element) { if (!element) {
return; return;
} }
@@ -123,9 +124,12 @@ module.exports = class PocketBird extends Plugin {
}); });
document.addEventListener("mousemove", (e) => { document.addEventListener("mousemove", (e) => {
const page = pageElement || document.documentElement;
const maxX = page.scrollWidth - elementToMove.clientWidth;
const maxY = page.scrollHeight - elementToMove.clientHeight;
if (isMouseDown) { if (isMouseDown) {
elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`;
elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`;
} }
}); });
@@ -846,6 +850,7 @@ module.exports = class PocketBird extends Plugin {
} }
const SAVE_KEY = "birbSaveData"; const SAVE_KEY = "birbSaveData";
const ROOT_PATH = "";
/** /**
* @typedef {import('./application.js').BirbSaveData} BirbSaveData * @typedef {import('./application.js').BirbSaveData} BirbSaveData
@@ -1076,7 +1081,6 @@ module.exports = class PocketBird extends Plugin {
} }
class ObsidianContext extends Context { class ObsidianContext extends Context {
/** /**
* @override * @override
* @returns {boolean} * @returns {boolean}
@@ -1091,8 +1095,12 @@ module.exports = class PocketBird extends Plugin {
* @returns {Promise<BirbSaveData|{}>} * @returns {Promise<BirbSaveData|{}>}
*/ */
async getSaveData() { async getSaveData() {
// @ts-expect-error return new Promise((resolve) => {
return await OBSIDIAN_PLUGIN.loadData() ?? {}; // @ts-expect-error
OBSIDIAN_PLUGIN.loadData().then((data) => {
resolve(data ?? {});
});
});
} }
/** /**
@@ -1101,7 +1109,7 @@ module.exports = class PocketBird extends Plugin {
*/ */
async putSaveData(saveData) { async putSaveData(saveData) {
// @ts-expect-error // @ts-expect-error
return await OBSIDIAN_PLUGIN.saveData(saveData); await OBSIDIAN_PLUGIN.saveData(saveData);
} }
/** @override */ /** @override */
@@ -1122,8 +1130,36 @@ module.exports = class PocketBird extends Plugin {
} }
/** @override */ /** @override */
areStickyNotesEnabled() { getPath() {
return false; // @ts-expect-error
const file = app.workspace.getActiveFile();
if (file && this.getActiveEditorElement()) {
return file.path;
} else {
return ROOT_PATH;
}
}
/** @override */
getActivePage() {
if (this.getPath() === ROOT_PATH) {
// Root page, use document element
return document.documentElement
}
return this.getActiveEditorElement() ?? document.documentElement;
}
/** @override */
isPathApplicable(path) {
return path === this.getPath();
}
/** @returns {HTMLElement|null} */
getActiveEditorElement() {
// @ts-expect-error
const activeLeaf = app.workspace.activeLeaf;
const leafElement = activeLeaf?.view?.containerEl;
return leafElement?.querySelector(".cm-scroller") ?? null;
} }
} }
@@ -1223,7 +1259,7 @@ module.exports = class PocketBird extends Plugin {
stickyNote.top = top; stickyNote.top = top;
stickyNote.left = left; stickyNote.left = left;
onSave(); onSave();
}); }, page);
if (closeButton) { if (closeButton) {
makeClosable(() => { makeClosable(() => {
@@ -1580,6 +1616,7 @@ module.exports = class PocketBird extends Plugin {
flex-grow: 1; flex-grow: 1;
user-select: none; user-select: none;
color: var(--birb-background-color); color: var(--birb-background-color);
white-space: nowrap;
} }
.birb-window-close { .birb-window-close {
@@ -1821,7 +1858,7 @@ module.exports = class PocketBird extends Plugin {
const AFK_TIME = isDebug() ? 0 : 1000 * 5; const AFK_TIME = isDebug() ? 0 : 1000 * 5;
const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5;
const PET_MENU_COOLDOWN = 1000; const PET_MENU_COOLDOWN = 1000;
const URL_CHECK_INTERVAL = 500; const URL_CHECK_INTERVAL = 250;
const HOP_DELAY = 500; const HOP_DELAY = 500;
// Random event chances per tick // Random event chances per tick
@@ -1963,7 +2000,7 @@ module.exports = class PocketBird extends Plugin {
insertModal(`${birdBirb()} Mode`, message); insertModal(`${birdBirb()} Mode`, message);
}), }),
new Separator(), new Separator(),
new MenuItem("2025.11.13.80", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.80"); }, false), new MenuItem("2025.11.14.16", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.14.16"); }, false),
]; ];
const styleElement = document.createElement("style"); const styleElement = document.createElement("style");
@@ -2162,7 +2199,7 @@ module.exports = class PocketBird extends Plugin {
setInterval(() => { setInterval(() => {
const currentPath = getContext().getPath().split("?")[0]; const currentPath = getContext().getPath().split("?")[0];
if (currentPath !== lastPath) { if (currentPath !== lastPath) {
log("Path changed, updating sticky notes"); log("Path changed, updating sticky notes: " + currentPath);
lastPath = currentPath; lastPath = currentPath;
drawStickyNotes(stickyNotes, save, deleteStickyNote); drawStickyNotes(stickyNotes, save, deleteStickyNote);
} }

View File

@@ -1,7 +1,7 @@
{ {
"id": "pocket-bird", "id": "pocket-bird",
"name": "Pocket Bird", "name": "Pocket Bird",
"version": "2025.11.13.80", "version": "2025.11.14.16",
"minAppVersion": "0.15.0", "minAppVersion": "0.15.0",
"description": "It's a pet bird in your Obsidian, what more could you want?", "description": "It's a pet bird in your Obsidian, what more could you want?",
"author": "Idrees Hassan", "author": "Idrees Hassan",

View File

@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name Pocket Bird // @name Pocket Bird
// @namespace https://idreesinc.com // @namespace https://idreesinc.com
// @version 2025.11.13.80 // @version 2025.11.14.16
// @description It's a bird that hops around your web browser, the future is here // @description It's a bird that hops around your web browser, the future is here
// @author Idrees // @author Idrees
// @downloadURL https://github.com/IdreesInc/Pocket-Bird/raw/refs/heads/main/dist/userscript/birb.user.js // @downloadURL https://github.com/IdreesInc/Pocket-Bird/raw/refs/heads/main/dist/userscript/birb.user.js
@@ -84,8 +84,9 @@
* @param {HTMLElement|null} element The element to detect drag events on * @param {HTMLElement|null} element The element to detect drag events on
* @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {boolean} [parent] Whether to move the parent element when the child is dragged
* @param {(top: number, left: number) => void} [callback] Callback for when element is moved * @param {(top: number, left: number) => void} [callback] Callback for when element is moved
* @param {HTMLElement} [pageElement] The page element to constrain movement within
*/ */
function makeDraggable(element, parent = true, callback = () => { }) { function makeDraggable(element, parent = true, callback = () => { }, pageElement) {
if (!element) { if (!element) {
return; return;
} }
@@ -131,9 +132,12 @@
}); });
document.addEventListener("mousemove", (e) => { document.addEventListener("mousemove", (e) => {
const page = pageElement || document.documentElement;
const maxX = page.scrollWidth - elementToMove.clientWidth;
const maxY = page.scrollHeight - elementToMove.clientHeight;
if (isMouseDown) { if (isMouseDown) {
elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`;
elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`;
} }
}); });
@@ -854,6 +858,7 @@
} }
const SAVE_KEY = "birbSaveData"; const SAVE_KEY = "birbSaveData";
const ROOT_PATH = "";
/** /**
* @typedef {import('./application.js').BirbSaveData} BirbSaveData * @typedef {import('./application.js').BirbSaveData} BirbSaveData
@@ -1084,7 +1089,6 @@
} }
class ObsidianContext extends Context { class ObsidianContext extends Context {
/** /**
* @override * @override
* @returns {boolean} * @returns {boolean}
@@ -1099,8 +1103,12 @@
* @returns {Promise<BirbSaveData|{}>} * @returns {Promise<BirbSaveData|{}>}
*/ */
async getSaveData() { async getSaveData() {
// @ts-expect-error return new Promise((resolve) => {
return await OBSIDIAN_PLUGIN.loadData() ?? {}; // @ts-expect-error
OBSIDIAN_PLUGIN.loadData().then((data) => {
resolve(data ?? {});
});
});
} }
/** /**
@@ -1109,7 +1117,7 @@
*/ */
async putSaveData(saveData) { async putSaveData(saveData) {
// @ts-expect-error // @ts-expect-error
return await OBSIDIAN_PLUGIN.saveData(saveData); await OBSIDIAN_PLUGIN.saveData(saveData);
} }
/** @override */ /** @override */
@@ -1130,8 +1138,36 @@
} }
/** @override */ /** @override */
areStickyNotesEnabled() { getPath() {
return false; // @ts-expect-error
const file = app.workspace.getActiveFile();
if (file && this.getActiveEditorElement()) {
return file.path;
} else {
return ROOT_PATH;
}
}
/** @override */
getActivePage() {
if (this.getPath() === ROOT_PATH) {
// Root page, use document element
return document.documentElement
}
return this.getActiveEditorElement() ?? document.documentElement;
}
/** @override */
isPathApplicable(path) {
return path === this.getPath();
}
/** @returns {HTMLElement|null} */
getActiveEditorElement() {
// @ts-expect-error
const activeLeaf = app.workspace.activeLeaf;
const leafElement = activeLeaf?.view?.containerEl;
return leafElement?.querySelector(".cm-scroller") ?? null;
} }
} }
@@ -1231,7 +1267,7 @@
stickyNote.top = top; stickyNote.top = top;
stickyNote.left = left; stickyNote.left = left;
onSave(); onSave();
}); }, page);
if (closeButton) { if (closeButton) {
makeClosable(() => { makeClosable(() => {
@@ -1588,6 +1624,7 @@
flex-grow: 1; flex-grow: 1;
user-select: none; user-select: none;
color: var(--birb-background-color); color: var(--birb-background-color);
white-space: nowrap;
} }
.birb-window-close { .birb-window-close {
@@ -1829,7 +1866,7 @@
const AFK_TIME = isDebug() ? 0 : 1000 * 5; const AFK_TIME = isDebug() ? 0 : 1000 * 5;
const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5;
const PET_MENU_COOLDOWN = 1000; const PET_MENU_COOLDOWN = 1000;
const URL_CHECK_INTERVAL = 500; const URL_CHECK_INTERVAL = 250;
const HOP_DELAY = 500; const HOP_DELAY = 500;
// Random event chances per tick // Random event chances per tick
@@ -1971,7 +2008,7 @@
insertModal(`${birdBirb()} Mode`, message); insertModal(`${birdBirb()} Mode`, message);
}), }),
new Separator(), new Separator(),
new MenuItem("2025.11.13.80", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.80"); }, false), new MenuItem("2025.11.14.16", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.14.16"); }, false),
]; ];
const styleElement = document.createElement("style"); const styleElement = document.createElement("style");
@@ -2170,7 +2207,7 @@
setInterval(() => { setInterval(() => {
const currentPath = getContext().getPath().split("?")[0]; const currentPath = getContext().getPath().split("?")[0];
if (currentPath !== lastPath) { if (currentPath !== lastPath) {
log("Path changed, updating sticky notes"); log("Path changed, updating sticky notes: " + currentPath);
lastPath = currentPath; lastPath = currentPath;
drawStickyNotes(stickyNotes, save, deleteStickyNote); drawStickyNotes(stickyNotes, save, deleteStickyNote);
} }

View File

@@ -90,7 +90,7 @@ const UPDATE_INTERVAL = 1000 / 60; // 60 FPS
const AFK_TIME = isDebug() ? 0 : 1000 * 5; const AFK_TIME = isDebug() ? 0 : 1000 * 5;
const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5;
const PET_MENU_COOLDOWN = 1000; const PET_MENU_COOLDOWN = 1000;
const URL_CHECK_INTERVAL = 500; const URL_CHECK_INTERVAL = 250;
const HOP_DELAY = 500; const HOP_DELAY = 500;
// Random event chances per tick // Random event chances per tick
@@ -431,7 +431,7 @@ Promise.all([
setInterval(() => { setInterval(() => {
const currentPath = getContext().getPath().split("?")[0]; const currentPath = getContext().getPath().split("?")[0];
if (currentPath !== lastPath) { if (currentPath !== lastPath) {
log("Path changed, updating sticky notes"); log("Path changed, updating sticky notes: " + currentPath);
lastPath = currentPath; lastPath = currentPath;
drawStickyNotes(stickyNotes, save, deleteStickyNote); drawStickyNotes(stickyNotes, save, deleteStickyNote);
} }

View File

@@ -1,6 +1,7 @@
import { debug, log, error } from "./shared.js"; import { debug, log, error } from "./shared.js";
const SAVE_KEY = "birbSaveData"; const SAVE_KEY = "birbSaveData";
const ROOT_PATH = "";
/** /**
* @typedef {import('./application.js').BirbSaveData} BirbSaveData * @typedef {import('./application.js').BirbSaveData} BirbSaveData
@@ -231,7 +232,6 @@ class BrowserExtensionContext extends Context {
} }
export class ObsidianContext extends Context { export class ObsidianContext extends Context {
/** /**
* @override * @override
* @returns {boolean} * @returns {boolean}
@@ -246,8 +246,12 @@ export class ObsidianContext extends Context {
* @returns {Promise<BirbSaveData|{}>} * @returns {Promise<BirbSaveData|{}>}
*/ */
async getSaveData() { async getSaveData() {
// @ts-expect-error return new Promise((resolve) => {
return await OBSIDIAN_PLUGIN.loadData() ?? {}; // @ts-expect-error
OBSIDIAN_PLUGIN.loadData().then((data) => {
resolve(data ?? {});
});
});
} }
/** /**
@@ -256,7 +260,7 @@ export class ObsidianContext extends Context {
*/ */
async putSaveData(saveData) { async putSaveData(saveData) {
// @ts-expect-error // @ts-expect-error
return await OBSIDIAN_PLUGIN.saveData(saveData); await OBSIDIAN_PLUGIN.saveData(saveData);
} }
/** @override */ /** @override */
@@ -277,8 +281,36 @@ export class ObsidianContext extends Context {
} }
/** @override */ /** @override */
areStickyNotesEnabled() { getPath() {
return false; // @ts-expect-error
const file = app.workspace.getActiveFile();
if (file && this.getActiveEditorElement()) {
return file.path;
} else {
return ROOT_PATH;
}
}
/** @override */
getActivePage() {
if (this.getPath() === ROOT_PATH) {
// Root page, use document element
return document.documentElement
}
return this.getActiveEditorElement() ?? document.documentElement;
}
/** @override */
isPathApplicable(path) {
return path === this.getPath();
}
/** @returns {HTMLElement|null} */
getActiveEditorElement() {
// @ts-expect-error
const activeLeaf = app.workspace.activeLeaf;
const leafElement = activeLeaf?.view?.containerEl;
return leafElement?.querySelector(".cm-scroller") ?? null;
} }
} }

View File

@@ -67,8 +67,9 @@ export function onClick(element, action) {
* @param {HTMLElement|null} element The element to detect drag events on * @param {HTMLElement|null} element The element to detect drag events on
* @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {boolean} [parent] Whether to move the parent element when the child is dragged
* @param {(top: number, left: number) => void} [callback] Callback for when element is moved * @param {(top: number, left: number) => void} [callback] Callback for when element is moved
* @param {HTMLElement} [pageElement] The page element to constrain movement within
*/ */
export function makeDraggable(element, parent = true, callback = () => { }) { export function makeDraggable(element, parent = true, callback = () => { }, pageElement) {
if (!element) { if (!element) {
return; return;
} }
@@ -114,9 +115,12 @@ export function makeDraggable(element, parent = true, callback = () => { }) {
}); });
document.addEventListener("mousemove", (e) => { document.addEventListener("mousemove", (e) => {
const page = pageElement || document.documentElement;
const maxX = page.scrollWidth - elementToMove.clientWidth;
const maxY = page.scrollHeight - elementToMove.clientHeight;
if (isMouseDown) { if (isMouseDown) {
elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`;
elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`;
} }
}); });

View File

@@ -69,7 +69,7 @@ export function renderStickyNote(stickyNote, page, onSave, onDelete) {
stickyNote.top = top; stickyNote.top = top;
stickyNote.left = left; stickyNote.left = left;
onSave(); onSave();
}); }, page);
if (closeButton) { if (closeButton) {
makeClosable(() => { makeClosable(() => {

View File

@@ -119,6 +119,7 @@
flex-grow: 1; flex-grow: 1;
user-select: none; user-select: none;
color: var(--birb-background-color); color: var(--birb-background-color);
white-space: nowrap;
} }
.birb-window-close { .birb-window-close {