mirror of
https://github.com/NohamR/Pocket-Bird.git
synced 2026-05-26 12:17:23 +00:00
Move sticky note path checking to context
This commit is contained in:
106
dist/birb.js
vendored
106
dist/birb.js
vendored
@@ -880,6 +880,40 @@
|
|||||||
resetSaveData() {
|
resetSaveData() {
|
||||||
throw new Error("Method not implemented");
|
throw new Error("Method not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} The current path of the active page in this context
|
||||||
|
*/
|
||||||
|
getPath() {
|
||||||
|
// Default to website URL
|
||||||
|
return window.location.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a path is applicable given the context
|
||||||
|
* @param {string} path Can be a site URL or another context-specific path
|
||||||
|
* @returns {boolean} Whether the path matches the current context state
|
||||||
|
*/
|
||||||
|
isPathApplicable(path) {
|
||||||
|
// Default to website URL matching
|
||||||
|
const currentUrl = window.location.href;
|
||||||
|
const stickyNoteWebsite = path.split("?")[0];
|
||||||
|
const currentWebsite = currentUrl.split("?")[0];
|
||||||
|
|
||||||
|
if (stickyNoteWebsite !== currentWebsite) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathParams = parseUrlParams(path);
|
||||||
|
const currentParams = parseUrlParams(currentUrl);
|
||||||
|
|
||||||
|
if (window.location.hostname === "www.youtube.com") {
|
||||||
|
if (currentParams.v !== undefined && currentParams.v !== pathParams.v) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocalContext extends Context {
|
class LocalContext extends Context {
|
||||||
@@ -1063,6 +1097,21 @@
|
|||||||
return new LocalContext();
|
return new LocalContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse URL parameters into a key-value map
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Record<string, string>}
|
||||||
|
*/
|
||||||
|
function parseUrlParams(url) {
|
||||||
|
const queryString = url.split("?")[1];
|
||||||
|
if (!queryString) return {};
|
||||||
|
|
||||||
|
return queryString.split("&").reduce((params, param) => {
|
||||||
|
const [key, value] = param.split("=");
|
||||||
|
return { ...params, [key]: value };
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SavedStickyNote
|
* @typedef {Object} SavedStickyNote
|
||||||
* @property {string} id
|
* @property {string} id
|
||||||
@@ -1089,46 +1138,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse URL parameters into a key-value map
|
|
||||||
* @param {string} url
|
|
||||||
* @returns {Record<string, string>}
|
|
||||||
*/
|
|
||||||
function parseUrlParams(url) {
|
|
||||||
const queryString = url.split("?")[1];
|
|
||||||
if (!queryString) return {};
|
|
||||||
|
|
||||||
return queryString.split("&").reduce((params, param) => {
|
|
||||||
const [key, value] = param.split("=");
|
|
||||||
return { ...params, [key]: value };
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {StickyNote} stickyNote
|
|
||||||
* @returns {boolean} Whether the given sticky note is applicable to the current site/page
|
|
||||||
*/
|
|
||||||
function isStickyNoteApplicable(stickyNote) {
|
|
||||||
const stickyNoteUrl = stickyNote.site;
|
|
||||||
const currentUrl = window.location.href;
|
|
||||||
const stickyNoteWebsite = stickyNoteUrl.split("?")[0];
|
|
||||||
const currentWebsite = currentUrl.split("?")[0];
|
|
||||||
|
|
||||||
if (stickyNoteWebsite !== currentWebsite) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stickyNoteParams = parseUrlParams(stickyNoteUrl);
|
|
||||||
const currentParams = parseUrlParams(currentUrl);
|
|
||||||
|
|
||||||
if (window.location.hostname === "www.youtube.com") {
|
|
||||||
if (currentParams.v !== undefined && currentParams.v !== stickyNoteParams.v) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {StickyNote} stickyNote
|
* @param {StickyNote} stickyNote
|
||||||
* @param {() => void} onSave
|
* @param {() => void} onSave
|
||||||
@@ -1211,8 +1220,9 @@
|
|||||||
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
||||||
existingNotes.forEach(note => note.remove());
|
existingNotes.forEach(note => note.remove());
|
||||||
// Render all sticky notes
|
// Render all sticky notes
|
||||||
|
const context = getContext();
|
||||||
for (let stickyNote of stickyNotes) {
|
for (let stickyNote of stickyNotes) {
|
||||||
if (isStickyNoteApplicable(stickyNote)) {
|
if (context.isPathApplicable(stickyNote.site)) {
|
||||||
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1225,7 +1235,7 @@
|
|||||||
*/
|
*/
|
||||||
function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
||||||
const id = Date.now().toString();
|
const id = Date.now().toString();
|
||||||
const site = window.location.href;
|
const site = getContext().getPath();
|
||||||
const stickyNote = new StickyNote(id, site, "");
|
const stickyNote = new StickyNote(id, site, "");
|
||||||
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
||||||
@@ -1902,7 +1912,7 @@
|
|||||||
insertModal(`${birdBirb()} Mode`, message);
|
insertModal(`${birdBirb()} Mode`, message);
|
||||||
}),
|
}),
|
||||||
new Separator(),
|
new Separator(),
|
||||||
new MenuItem("2025.11.13.2", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.2"); }, false),
|
new MenuItem("2025.11.13.6", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.6"); }, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
const styleElement = document.createElement("style");
|
const styleElement = document.createElement("style");
|
||||||
@@ -2097,12 +2107,12 @@
|
|||||||
|
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
|
|
||||||
let lastUrl = (window.location.href ?? "").split("?")[0];
|
let lastPath = getContext().getPath().split("?")[0];
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const currentUrl = (window.location.href ?? "").split("?")[0];
|
const currentPath = getContext().getPath().split("?")[0];
|
||||||
if (currentUrl !== lastUrl) {
|
if (currentPath !== lastPath) {
|
||||||
log("URL changed, updating sticky notes");
|
log("Path changed, updating sticky notes");
|
||||||
lastUrl = currentUrl;
|
lastPath = currentPath;
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
}
|
}
|
||||||
}, URL_CHECK_INTERVAL);
|
}, URL_CHECK_INTERVAL);
|
||||||
|
|||||||
BIN
dist/extension.zip
vendored
BIN
dist/extension.zip
vendored
Binary file not shown.
106
dist/extension/birb.js
vendored
106
dist/extension/birb.js
vendored
@@ -880,6 +880,40 @@
|
|||||||
resetSaveData() {
|
resetSaveData() {
|
||||||
throw new Error("Method not implemented");
|
throw new Error("Method not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} The current path of the active page in this context
|
||||||
|
*/
|
||||||
|
getPath() {
|
||||||
|
// Default to website URL
|
||||||
|
return window.location.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a path is applicable given the context
|
||||||
|
* @param {string} path Can be a site URL or another context-specific path
|
||||||
|
* @returns {boolean} Whether the path matches the current context state
|
||||||
|
*/
|
||||||
|
isPathApplicable(path) {
|
||||||
|
// Default to website URL matching
|
||||||
|
const currentUrl = window.location.href;
|
||||||
|
const stickyNoteWebsite = path.split("?")[0];
|
||||||
|
const currentWebsite = currentUrl.split("?")[0];
|
||||||
|
|
||||||
|
if (stickyNoteWebsite !== currentWebsite) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathParams = parseUrlParams(path);
|
||||||
|
const currentParams = parseUrlParams(currentUrl);
|
||||||
|
|
||||||
|
if (window.location.hostname === "www.youtube.com") {
|
||||||
|
if (currentParams.v !== undefined && currentParams.v !== pathParams.v) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocalContext extends Context {
|
class LocalContext extends Context {
|
||||||
@@ -1063,6 +1097,21 @@
|
|||||||
return new LocalContext();
|
return new LocalContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse URL parameters into a key-value map
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Record<string, string>}
|
||||||
|
*/
|
||||||
|
function parseUrlParams(url) {
|
||||||
|
const queryString = url.split("?")[1];
|
||||||
|
if (!queryString) return {};
|
||||||
|
|
||||||
|
return queryString.split("&").reduce((params, param) => {
|
||||||
|
const [key, value] = param.split("=");
|
||||||
|
return { ...params, [key]: value };
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SavedStickyNote
|
* @typedef {Object} SavedStickyNote
|
||||||
* @property {string} id
|
* @property {string} id
|
||||||
@@ -1089,46 +1138,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse URL parameters into a key-value map
|
|
||||||
* @param {string} url
|
|
||||||
* @returns {Record<string, string>}
|
|
||||||
*/
|
|
||||||
function parseUrlParams(url) {
|
|
||||||
const queryString = url.split("?")[1];
|
|
||||||
if (!queryString) return {};
|
|
||||||
|
|
||||||
return queryString.split("&").reduce((params, param) => {
|
|
||||||
const [key, value] = param.split("=");
|
|
||||||
return { ...params, [key]: value };
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {StickyNote} stickyNote
|
|
||||||
* @returns {boolean} Whether the given sticky note is applicable to the current site/page
|
|
||||||
*/
|
|
||||||
function isStickyNoteApplicable(stickyNote) {
|
|
||||||
const stickyNoteUrl = stickyNote.site;
|
|
||||||
const currentUrl = window.location.href;
|
|
||||||
const stickyNoteWebsite = stickyNoteUrl.split("?")[0];
|
|
||||||
const currentWebsite = currentUrl.split("?")[0];
|
|
||||||
|
|
||||||
if (stickyNoteWebsite !== currentWebsite) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stickyNoteParams = parseUrlParams(stickyNoteUrl);
|
|
||||||
const currentParams = parseUrlParams(currentUrl);
|
|
||||||
|
|
||||||
if (window.location.hostname === "www.youtube.com") {
|
|
||||||
if (currentParams.v !== undefined && currentParams.v !== stickyNoteParams.v) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {StickyNote} stickyNote
|
* @param {StickyNote} stickyNote
|
||||||
* @param {() => void} onSave
|
* @param {() => void} onSave
|
||||||
@@ -1211,8 +1220,9 @@
|
|||||||
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
||||||
existingNotes.forEach(note => note.remove());
|
existingNotes.forEach(note => note.remove());
|
||||||
// Render all sticky notes
|
// Render all sticky notes
|
||||||
|
const context = getContext();
|
||||||
for (let stickyNote of stickyNotes) {
|
for (let stickyNote of stickyNotes) {
|
||||||
if (isStickyNoteApplicable(stickyNote)) {
|
if (context.isPathApplicable(stickyNote.site)) {
|
||||||
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1225,7 +1235,7 @@
|
|||||||
*/
|
*/
|
||||||
function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
||||||
const id = Date.now().toString();
|
const id = Date.now().toString();
|
||||||
const site = window.location.href;
|
const site = getContext().getPath();
|
||||||
const stickyNote = new StickyNote(id, site, "");
|
const stickyNote = new StickyNote(id, site, "");
|
||||||
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
||||||
@@ -1902,7 +1912,7 @@
|
|||||||
insertModal(`${birdBirb()} Mode`, message);
|
insertModal(`${birdBirb()} Mode`, message);
|
||||||
}),
|
}),
|
||||||
new Separator(),
|
new Separator(),
|
||||||
new MenuItem("2025.11.13.2", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.2"); }, false),
|
new MenuItem("2025.11.13.6", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.6"); }, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
const styleElement = document.createElement("style");
|
const styleElement = document.createElement("style");
|
||||||
@@ -2097,12 +2107,12 @@
|
|||||||
|
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
|
|
||||||
let lastUrl = (window.location.href ?? "").split("?")[0];
|
let lastPath = getContext().getPath().split("?")[0];
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const currentUrl = (window.location.href ?? "").split("?")[0];
|
const currentPath = getContext().getPath().split("?")[0];
|
||||||
if (currentUrl !== lastUrl) {
|
if (currentPath !== lastPath) {
|
||||||
log("URL changed, updating sticky notes");
|
log("Path changed, updating sticky notes");
|
||||||
lastUrl = currentUrl;
|
lastPath = currentPath;
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
}
|
}
|
||||||
}, URL_CHECK_INTERVAL);
|
}, URL_CHECK_INTERVAL);
|
||||||
|
|||||||
2
dist/extension/manifest.json
vendored
2
dist/extension/manifest.json
vendored
@@ -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.2",
|
"version": "2025.11.13.6",
|
||||||
"homepage_url": "https://idreesinc.com",
|
"homepage_url": "https://idreesinc.com",
|
||||||
"icons": {
|
"icons": {
|
||||||
"48": "images/icons/transparent/48x48x1.png",
|
"48": "images/icons/transparent/48x48x1.png",
|
||||||
|
|||||||
106
dist/obsidian/main.js
vendored
106
dist/obsidian/main.js
vendored
@@ -884,6 +884,40 @@ module.exports = class MyPlugin extends Plugin {
|
|||||||
resetSaveData() {
|
resetSaveData() {
|
||||||
throw new Error("Method not implemented");
|
throw new Error("Method not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} The current path of the active page in this context
|
||||||
|
*/
|
||||||
|
getPath() {
|
||||||
|
// Default to website URL
|
||||||
|
return window.location.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a path is applicable given the context
|
||||||
|
* @param {string} path Can be a site URL or another context-specific path
|
||||||
|
* @returns {boolean} Whether the path matches the current context state
|
||||||
|
*/
|
||||||
|
isPathApplicable(path) {
|
||||||
|
// Default to website URL matching
|
||||||
|
const currentUrl = window.location.href;
|
||||||
|
const stickyNoteWebsite = path.split("?")[0];
|
||||||
|
const currentWebsite = currentUrl.split("?")[0];
|
||||||
|
|
||||||
|
if (stickyNoteWebsite !== currentWebsite) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathParams = parseUrlParams(path);
|
||||||
|
const currentParams = parseUrlParams(currentUrl);
|
||||||
|
|
||||||
|
if (window.location.hostname === "www.youtube.com") {
|
||||||
|
if (currentParams.v !== undefined && currentParams.v !== pathParams.v) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocalContext extends Context {
|
class LocalContext extends Context {
|
||||||
@@ -1067,6 +1101,21 @@ module.exports = class MyPlugin extends Plugin {
|
|||||||
return new LocalContext();
|
return new LocalContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse URL parameters into a key-value map
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Record<string, string>}
|
||||||
|
*/
|
||||||
|
function parseUrlParams(url) {
|
||||||
|
const queryString = url.split("?")[1];
|
||||||
|
if (!queryString) return {};
|
||||||
|
|
||||||
|
return queryString.split("&").reduce((params, param) => {
|
||||||
|
const [key, value] = param.split("=");
|
||||||
|
return { ...params, [key]: value };
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SavedStickyNote
|
* @typedef {Object} SavedStickyNote
|
||||||
* @property {string} id
|
* @property {string} id
|
||||||
@@ -1093,46 +1142,6 @@ module.exports = class MyPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse URL parameters into a key-value map
|
|
||||||
* @param {string} url
|
|
||||||
* @returns {Record<string, string>}
|
|
||||||
*/
|
|
||||||
function parseUrlParams(url) {
|
|
||||||
const queryString = url.split("?")[1];
|
|
||||||
if (!queryString) return {};
|
|
||||||
|
|
||||||
return queryString.split("&").reduce((params, param) => {
|
|
||||||
const [key, value] = param.split("=");
|
|
||||||
return { ...params, [key]: value };
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {StickyNote} stickyNote
|
|
||||||
* @returns {boolean} Whether the given sticky note is applicable to the current site/page
|
|
||||||
*/
|
|
||||||
function isStickyNoteApplicable(stickyNote) {
|
|
||||||
const stickyNoteUrl = stickyNote.site;
|
|
||||||
const currentUrl = window.location.href;
|
|
||||||
const stickyNoteWebsite = stickyNoteUrl.split("?")[0];
|
|
||||||
const currentWebsite = currentUrl.split("?")[0];
|
|
||||||
|
|
||||||
if (stickyNoteWebsite !== currentWebsite) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stickyNoteParams = parseUrlParams(stickyNoteUrl);
|
|
||||||
const currentParams = parseUrlParams(currentUrl);
|
|
||||||
|
|
||||||
if (window.location.hostname === "www.youtube.com") {
|
|
||||||
if (currentParams.v !== undefined && currentParams.v !== stickyNoteParams.v) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {StickyNote} stickyNote
|
* @param {StickyNote} stickyNote
|
||||||
* @param {() => void} onSave
|
* @param {() => void} onSave
|
||||||
@@ -1215,8 +1224,9 @@ module.exports = class MyPlugin extends Plugin {
|
|||||||
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
||||||
existingNotes.forEach(note => note.remove());
|
existingNotes.forEach(note => note.remove());
|
||||||
// Render all sticky notes
|
// Render all sticky notes
|
||||||
|
const context = getContext();
|
||||||
for (let stickyNote of stickyNotes) {
|
for (let stickyNote of stickyNotes) {
|
||||||
if (isStickyNoteApplicable(stickyNote)) {
|
if (context.isPathApplicable(stickyNote.site)) {
|
||||||
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1229,7 +1239,7 @@ module.exports = class MyPlugin extends Plugin {
|
|||||||
*/
|
*/
|
||||||
function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
||||||
const id = Date.now().toString();
|
const id = Date.now().toString();
|
||||||
const site = window.location.href;
|
const site = getContext().getPath();
|
||||||
const stickyNote = new StickyNote(id, site, "");
|
const stickyNote = new StickyNote(id, site, "");
|
||||||
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
||||||
@@ -1906,7 +1916,7 @@ module.exports = class MyPlugin extends Plugin {
|
|||||||
insertModal(`${birdBirb()} Mode`, message);
|
insertModal(`${birdBirb()} Mode`, message);
|
||||||
}),
|
}),
|
||||||
new Separator(),
|
new Separator(),
|
||||||
new MenuItem("2025.11.13.2", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.2"); }, false),
|
new MenuItem("2025.11.13.6", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.6"); }, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
const styleElement = document.createElement("style");
|
const styleElement = document.createElement("style");
|
||||||
@@ -2101,12 +2111,12 @@ module.exports = class MyPlugin extends Plugin {
|
|||||||
|
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
|
|
||||||
let lastUrl = (window.location.href ?? "").split("?")[0];
|
let lastPath = getContext().getPath().split("?")[0];
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const currentUrl = (window.location.href ?? "").split("?")[0];
|
const currentPath = getContext().getPath().split("?")[0];
|
||||||
if (currentUrl !== lastUrl) {
|
if (currentPath !== lastPath) {
|
||||||
log("URL changed, updating sticky notes");
|
log("Path changed, updating sticky notes");
|
||||||
lastUrl = currentUrl;
|
lastPath = currentPath;
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
}
|
}
|
||||||
}, URL_CHECK_INTERVAL);
|
}, URL_CHECK_INTERVAL);
|
||||||
|
|||||||
2
dist/obsidian/manifest.json
vendored
2
dist/obsidian/manifest.json
vendored
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "pocket-bird",
|
"id": "pocket-bird",
|
||||||
"name": "Pocket Bird",
|
"name": "Pocket Bird",
|
||||||
"version": "2025.11.13.2",
|
"version": "2025.11.13.6",
|
||||||
"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",
|
||||||
|
|||||||
108
dist/userscript/birb.user.js
vendored
108
dist/userscript/birb.user.js
vendored
@@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Pocket Bird
|
// @name Pocket Bird
|
||||||
// @namespace https://idreesinc.com
|
// @namespace https://idreesinc.com
|
||||||
// @version 2025.11.13.2
|
// @version 2025.11.13.6
|
||||||
// @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
|
||||||
@@ -894,6 +894,40 @@
|
|||||||
resetSaveData() {
|
resetSaveData() {
|
||||||
throw new Error("Method not implemented");
|
throw new Error("Method not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} The current path of the active page in this context
|
||||||
|
*/
|
||||||
|
getPath() {
|
||||||
|
// Default to website URL
|
||||||
|
return window.location.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a path is applicable given the context
|
||||||
|
* @param {string} path Can be a site URL or another context-specific path
|
||||||
|
* @returns {boolean} Whether the path matches the current context state
|
||||||
|
*/
|
||||||
|
isPathApplicable(path) {
|
||||||
|
// Default to website URL matching
|
||||||
|
const currentUrl = window.location.href;
|
||||||
|
const stickyNoteWebsite = path.split("?")[0];
|
||||||
|
const currentWebsite = currentUrl.split("?")[0];
|
||||||
|
|
||||||
|
if (stickyNoteWebsite !== currentWebsite) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathParams = parseUrlParams(path);
|
||||||
|
const currentParams = parseUrlParams(currentUrl);
|
||||||
|
|
||||||
|
if (window.location.hostname === "www.youtube.com") {
|
||||||
|
if (currentParams.v !== undefined && currentParams.v !== pathParams.v) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocalContext extends Context {
|
class LocalContext extends Context {
|
||||||
@@ -1077,6 +1111,21 @@
|
|||||||
return new LocalContext();
|
return new LocalContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse URL parameters into a key-value map
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Record<string, string>}
|
||||||
|
*/
|
||||||
|
function parseUrlParams(url) {
|
||||||
|
const queryString = url.split("?")[1];
|
||||||
|
if (!queryString) return {};
|
||||||
|
|
||||||
|
return queryString.split("&").reduce((params, param) => {
|
||||||
|
const [key, value] = param.split("=");
|
||||||
|
return { ...params, [key]: value };
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SavedStickyNote
|
* @typedef {Object} SavedStickyNote
|
||||||
* @property {string} id
|
* @property {string} id
|
||||||
@@ -1103,46 +1152,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse URL parameters into a key-value map
|
|
||||||
* @param {string} url
|
|
||||||
* @returns {Record<string, string>}
|
|
||||||
*/
|
|
||||||
function parseUrlParams(url) {
|
|
||||||
const queryString = url.split("?")[1];
|
|
||||||
if (!queryString) return {};
|
|
||||||
|
|
||||||
return queryString.split("&").reduce((params, param) => {
|
|
||||||
const [key, value] = param.split("=");
|
|
||||||
return { ...params, [key]: value };
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {StickyNote} stickyNote
|
|
||||||
* @returns {boolean} Whether the given sticky note is applicable to the current site/page
|
|
||||||
*/
|
|
||||||
function isStickyNoteApplicable(stickyNote) {
|
|
||||||
const stickyNoteUrl = stickyNote.site;
|
|
||||||
const currentUrl = window.location.href;
|
|
||||||
const stickyNoteWebsite = stickyNoteUrl.split("?")[0];
|
|
||||||
const currentWebsite = currentUrl.split("?")[0];
|
|
||||||
|
|
||||||
if (stickyNoteWebsite !== currentWebsite) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stickyNoteParams = parseUrlParams(stickyNoteUrl);
|
|
||||||
const currentParams = parseUrlParams(currentUrl);
|
|
||||||
|
|
||||||
if (window.location.hostname === "www.youtube.com") {
|
|
||||||
if (currentParams.v !== undefined && currentParams.v !== stickyNoteParams.v) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {StickyNote} stickyNote
|
* @param {StickyNote} stickyNote
|
||||||
* @param {() => void} onSave
|
* @param {() => void} onSave
|
||||||
@@ -1225,8 +1234,9 @@
|
|||||||
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
||||||
existingNotes.forEach(note => note.remove());
|
existingNotes.forEach(note => note.remove());
|
||||||
// Render all sticky notes
|
// Render all sticky notes
|
||||||
|
const context = getContext();
|
||||||
for (let stickyNote of stickyNotes) {
|
for (let stickyNote of stickyNotes) {
|
||||||
if (isStickyNoteApplicable(stickyNote)) {
|
if (context.isPathApplicable(stickyNote.site)) {
|
||||||
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1239,7 +1249,7 @@
|
|||||||
*/
|
*/
|
||||||
function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
||||||
const id = Date.now().toString();
|
const id = Date.now().toString();
|
||||||
const site = window.location.href;
|
const site = getContext().getPath();
|
||||||
const stickyNote = new StickyNote(id, site, "");
|
const stickyNote = new StickyNote(id, site, "");
|
||||||
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
||||||
@@ -1916,7 +1926,7 @@
|
|||||||
insertModal(`${birdBirb()} Mode`, message);
|
insertModal(`${birdBirb()} Mode`, message);
|
||||||
}),
|
}),
|
||||||
new Separator(),
|
new Separator(),
|
||||||
new MenuItem("2025.11.13.2", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.2"); }, false),
|
new MenuItem("2025.11.13.6", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.6"); }, false),
|
||||||
];
|
];
|
||||||
|
|
||||||
const styleElement = document.createElement("style");
|
const styleElement = document.createElement("style");
|
||||||
@@ -2111,12 +2121,12 @@
|
|||||||
|
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
|
|
||||||
let lastUrl = (window.location.href ?? "").split("?")[0];
|
let lastPath = getContext().getPath().split("?")[0];
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const currentUrl = (window.location.href ?? "").split("?")[0];
|
const currentPath = getContext().getPath().split("?")[0];
|
||||||
if (currentUrl !== lastUrl) {
|
if (currentPath !== lastPath) {
|
||||||
log("URL changed, updating sticky notes");
|
log("Path changed, updating sticky notes");
|
||||||
lastUrl = currentUrl;
|
lastPath = currentPath;
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
}
|
}
|
||||||
}, URL_CHECK_INTERVAL);
|
}, URL_CHECK_INTERVAL);
|
||||||
|
|||||||
@@ -426,12 +426,12 @@ Promise.all([
|
|||||||
|
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
|
|
||||||
let lastUrl = (window.location.href ?? "").split("?")[0];
|
let lastPath = getContext().getPath().split("?")[0];
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const currentUrl = (window.location.href ?? "").split("?")[0];
|
const currentPath = getContext().getPath().split("?")[0];
|
||||||
if (currentUrl !== lastUrl) {
|
if (currentPath !== lastPath) {
|
||||||
log("URL changed, updating sticky notes");
|
log("Path changed, updating sticky notes");
|
||||||
lastUrl = currentUrl;
|
lastPath = currentPath;
|
||||||
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
drawStickyNotes(stickyNotes, save, deleteStickyNote);
|
||||||
}
|
}
|
||||||
}, URL_CHECK_INTERVAL);
|
}, URL_CHECK_INTERVAL);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import { debug, log, error } from "./shared.js";
|
import { debug, log, error } from "./shared.js";
|
||||||
|
|
||||||
const SAVE_KEY = "birbSaveData";
|
const SAVE_KEY = "birbSaveData";
|
||||||
@@ -42,6 +41,40 @@ export class Context {
|
|||||||
resetSaveData() {
|
resetSaveData() {
|
||||||
throw new Error("Method not implemented");
|
throw new Error("Method not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} The current path of the active page in this context
|
||||||
|
*/
|
||||||
|
getPath() {
|
||||||
|
// Default to website URL
|
||||||
|
return window.location.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a path is applicable given the context
|
||||||
|
* @param {string} path Can be a site URL or another context-specific path
|
||||||
|
* @returns {boolean} Whether the path matches the current context state
|
||||||
|
*/
|
||||||
|
isPathApplicable(path) {
|
||||||
|
// Default to website URL matching
|
||||||
|
const currentUrl = window.location.href;
|
||||||
|
const stickyNoteWebsite = path.split("?")[0];
|
||||||
|
const currentWebsite = currentUrl.split("?")[0];
|
||||||
|
|
||||||
|
if (stickyNoteWebsite !== currentWebsite) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathParams = parseUrlParams(path);
|
||||||
|
const currentParams = parseUrlParams(currentUrl);
|
||||||
|
|
||||||
|
if (window.location.hostname === "www.youtube.com") {
|
||||||
|
if (currentParams.v !== undefined && currentParams.v !== pathParams.v) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LocalContext extends Context {
|
export class LocalContext extends Context {
|
||||||
@@ -224,3 +257,18 @@ export function getContext() {
|
|||||||
error("No applicable context found, defaulting to LocalContext");
|
error("No applicable context found, defaulting to LocalContext");
|
||||||
return new LocalContext();
|
return new LocalContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse URL parameters into a key-value map
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Record<string, string>}
|
||||||
|
*/
|
||||||
|
function parseUrlParams(url) {
|
||||||
|
const queryString = url.split("?")[1];
|
||||||
|
if (!queryString) return {};
|
||||||
|
|
||||||
|
return queryString.split("&").reduce((params, param) => {
|
||||||
|
const [key, value] = param.split("=");
|
||||||
|
return { ...params, [key]: value };
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
makeDraggable,
|
makeDraggable,
|
||||||
makeClosable
|
makeClosable
|
||||||
} from './shared.js';
|
} from './shared.js';
|
||||||
|
import { getContext } from './context.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SavedStickyNote
|
* @typedef {Object} SavedStickyNote
|
||||||
@@ -30,46 +31,6 @@ export class StickyNote {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse URL parameters into a key-value map
|
|
||||||
* @param {string} url
|
|
||||||
* @returns {Record<string, string>}
|
|
||||||
*/
|
|
||||||
export function parseUrlParams(url) {
|
|
||||||
const queryString = url.split("?")[1];
|
|
||||||
if (!queryString) return {};
|
|
||||||
|
|
||||||
return queryString.split("&").reduce((params, param) => {
|
|
||||||
const [key, value] = param.split("=");
|
|
||||||
return { ...params, [key]: value };
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {StickyNote} stickyNote
|
|
||||||
* @returns {boolean} Whether the given sticky note is applicable to the current site/page
|
|
||||||
*/
|
|
||||||
export function isStickyNoteApplicable(stickyNote) {
|
|
||||||
const stickyNoteUrl = stickyNote.site;
|
|
||||||
const currentUrl = window.location.href;
|
|
||||||
const stickyNoteWebsite = stickyNoteUrl.split("?")[0];
|
|
||||||
const currentWebsite = currentUrl.split("?")[0];
|
|
||||||
|
|
||||||
if (stickyNoteWebsite !== currentWebsite) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stickyNoteParams = parseUrlParams(stickyNoteUrl);
|
|
||||||
const currentParams = parseUrlParams(currentUrl);
|
|
||||||
|
|
||||||
if (window.location.hostname === "www.youtube.com") {
|
|
||||||
if (currentParams.v !== undefined && currentParams.v !== stickyNoteParams.v) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {StickyNote} stickyNote
|
* @param {StickyNote} stickyNote
|
||||||
* @param {() => void} onSave
|
* @param {() => void} onSave
|
||||||
@@ -152,8 +113,9 @@ export function drawStickyNotes(stickyNotes, onSave, onDelete) {
|
|||||||
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
const existingNotes = document.querySelectorAll(".birb-sticky-note");
|
||||||
existingNotes.forEach(note => note.remove());
|
existingNotes.forEach(note => note.remove());
|
||||||
// Render all sticky notes
|
// Render all sticky notes
|
||||||
|
const context = getContext();
|
||||||
for (let stickyNote of stickyNotes) {
|
for (let stickyNote of stickyNotes) {
|
||||||
if (isStickyNoteApplicable(stickyNote)) {
|
if (context.isPathApplicable(stickyNote.site)) {
|
||||||
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +128,7 @@ export function drawStickyNotes(stickyNotes, onSave, onDelete) {
|
|||||||
*/
|
*/
|
||||||
export function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
export function createNewStickyNote(stickyNotes, onSave, onDelete) {
|
||||||
const id = Date.now().toString();
|
const id = Date.now().toString();
|
||||||
const site = window.location.href;
|
const site = getContext().getPath();
|
||||||
const stickyNote = new StickyNote(id, site, "");
|
const stickyNote = new StickyNote(id, site, "");
|
||||||
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
const element = renderStickyNote(stickyNote, onSave, () => onDelete(stickyNote));
|
||||||
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
element.style.left = `${window.innerWidth / 2 - element.offsetWidth / 2}px`;
|
||||||
|
|||||||
Reference in New Issue
Block a user