Compare commits

...

No commits in common. "main" and "master" have entirely different histories.
main ... master

8 changed files with 175 additions and 1 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.zip

View file

@ -1,3 +1,13 @@
# mealie-extension
A Firefox extension to easily add recipes to a personal Mealie instance.
**Note: This is currently in alpha. Please use at your own risk**
*How to use*
Install through Firefox marketplace (pending approval) or use extension debug to install manually as a temp extension.
Once installed, go to preferences and your Mealie URL and the API token you will be using (this needs to be generated from your account on Mealie).
After that, either right-click a page or use shortcut "Ctrl+Alt+M".

96
extension/background.js Normal file
View file

@ -0,0 +1,96 @@
async function Clicked() {
// Grabs our Token and URL from the Preferences page
const { token, url } = await browser.storage.local.get(['token', 'url']);
// Pull current site's URL
let [tab] = await browser.tabs.query({active: true, currentWindow: true});
// removes a traling forward slash
let site_url = tab.url.endsWith('/') ?
tab.url.slice(0, -1) :
tab.url;
let mealie_url = url;
/***
* NO LONGER USED
* Was originally designed based off of the bookmarklet example on Mealie's GitHub
*
*
let site_url = document.URL.endsWith('/') ?
document.URL.slice(0, -1) :
document.URL;
// let group_slug = "" // Change this to your group slug. You can obtain this from your URL after logging-in to Mealie
// let use_keywords= "&use_keywords=0" // Optional - use keywords from recipe - update to "" if you don't want that
// let edity = "&edit=0" // Optional - keep in edit mode - update to "" if you don't want that
if (mealie.slice(-1) === "/") {
mealie = mealie.slice(0, -1)
}
let dest = mealie + "/recipe/create/url?recipe_import_url=" + site_url;
// Send a message to the content script
browser.tabs.query({active: true, currentWindow: true}, (tabs) => {
console.log("Sending message to content script");
browser.tabs.sendMessage(tabs[0].id, `Token: ${token}, URL: ${url}`).then(() => {
console.log("Message sent to content script");
}).catch((error) => {
console.error("Error sending message to content script:", error);
});
});
// Open a new tab with the destination URL
browser.tabs.create({ url: dest }).then(() => {
console.log(`New tab opened with URL: ${dest}`);
}).catch((error) => {
console.error("Error opening new tab:", error);
});
*
*/
// Submit POST request to your Mealie server
const postUrl = `${mealie_url}/api/recipes/create/url`;
const requestBody = {
includeTags: false,
url: site_url
};
const response = await fetch(postUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify(requestBody)
});
if (response.ok) {
const responseData = await response.json();
console.log("POST request successful:", responseData);
} else {
const errorText = await response.text();
console.error("POST request failed:", response.statusTextm, errorText);
}
}
// background.js
// Create a context menu item
browser.contextMenus.create({
id: "clickHere",
title: "Add to Mealie",
contexts: ["all"],
});
// Add a listener for the context menu item
browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "clickHere") {
Clicked();
}
});
// Add a listener for the keyboard shortcut
browser.commands.onCommand.addListener((command) => {
if (command === "activateClick") {
Clicked();
}
});

BIN
extension/icons/48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

34
extension/manifest.json Normal file
View file

@ -0,0 +1,34 @@
{
"manifest_version": 2,
"name": "Mealie",
"version": "1.0.1",
"description": "Connects with a local Mealie instance.",
"icons": {
"48": "icons/48.png"
},
"background": {
"scripts": ["background.js"]
},
"permissions": [
"webRequest",
"*://*/*",
"contextMenus",
"storage",
"activeTab"
],
"commands": {
"activateClick": {
"suggested_key": {
"default": "Ctrl+Alt+M"
},
"description": "Activates 'Clicked' function"
}
},
"options_ui": {
"page": "options.html",
"open_in_tab": true
}
}

17
extension/options.html Normal file
View file

@ -0,0 +1,17 @@
<!-- options.html -->
<!DOCTYPE html>
<html>
<head>
<title>Mealie Extension Options</title>
</head>
<body>
<h1>Extension Options</h1>
<label for="token">Token:</label>
<input type="text" id="token" name="token"><br>
<label for="url">URL:</label>
<input type="text" id="url" name="url"><br>
<button id="save">Save</button>
<script src="options.js"></script>
</body>
</html>

16
extension/options.js Normal file
View file

@ -0,0 +1,16 @@
// options.js
document.getElementById('save').addEventListener("click", async () => {
const token = document.getElementById('token').value;
const url = document.getElementById('url').value;
await browser.storage.local.set({ token, url });
alert('Options saved!');
});
// Load saved settings if they exist
(async () => {
const { token, url } = await browser.storage.local.get(['token', 'url']);
if (token) document.getElementById('token').value = token;
if (url) document.getElementById('url').value = url;
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB