-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Cybrarist/v2.1
V2.1
- Loading branch information
Showing
43 changed files
with
3,696 additions
and
2,382 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
class Product { | ||
name; | ||
image; | ||
price; | ||
rate; | ||
number_of_rates; | ||
seller; | ||
url; | ||
update_product; | ||
in_stock=true; | ||
#token; | ||
|
||
storage_promise; | ||
|
||
constructor() { | ||
this.storage_promise= this.get_storage_data() | ||
} | ||
|
||
/** | ||
* urls on the server api. | ||
* @returns {string} | ||
*/ | ||
|
||
update_url () { | ||
return `${this.url}/api/products/update` | ||
}; | ||
get_product () { | ||
return `${this.url}/api/products/get` | ||
}; | ||
create_product () { | ||
return `${this.url}/api/products/create` | ||
}; | ||
|
||
/** | ||
* get the data saved in the browser | ||
* @returns {Promise<void>} | ||
*/ | ||
|
||
async get_storage_data(){ | ||
var result= await browser.storage.sync.get() | ||
this.#token= result.token; | ||
this.url=result.url; | ||
this.update_product=result.update_product; | ||
} | ||
|
||
|
||
|
||
async update_server_product(){ | ||
await this.storage_promise | ||
|
||
if (!this.update_product) | ||
return | ||
|
||
fetch(this.update_url() ,{ | ||
method: 'POST', | ||
headers:{ | ||
'Content-Type': 'application/json', | ||
'Accept': 'application/json', | ||
'Authorization': `Bearer ${this.#token}`, | ||
}, | ||
body:JSON.stringify({ | ||
url : window.location.href, | ||
current_price: self.price | ||
}) | ||
}) | ||
.catch(error => { | ||
// Handle errors | ||
console.log("Error:", error); | ||
}); | ||
} | ||
|
||
async get_product_data(){ | ||
await this.storage_promise | ||
|
||
return fetch(this.get_product() ,{ | ||
method: 'POST', | ||
headers:{ | ||
'Content-Type': 'application/json', | ||
'Accept': 'application/json', | ||
'Authorization': `Bearer ${this.#token}`, | ||
}, | ||
body:JSON.stringify({ | ||
url : window.location.href | ||
}) | ||
|
||
}) | ||
.then((response) => { | ||
return response.json(); | ||
}) | ||
.catch(error => { | ||
// product doesn't exist in the system | ||
}); | ||
} | ||
|
||
submit_form(){ | ||
document.body.querySelector("#gray_layout").classList.add("show_flex") | ||
|
||
fetch(this.create_product(), { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'Accept': 'application/json', | ||
'Authorization': `Bearer ${this.#token}`, | ||
}, | ||
body: JSON.stringify({ | ||
url: window.location.href , | ||
name: this.name, | ||
image: this.image, | ||
notify_price: document.getElementById("notify_price").value, | ||
official_seller: document.getElementById("official_seller").checked, | ||
favourite: document.getElementById("favourite").checked, | ||
stock_available: document.getElementById("stock_available").checked, | ||
lowest_within: document.getElementById("lowest_within").value, | ||
number_of_rates:this.number_of_rates ?? 0, | ||
price:this?.price ?? 0, | ||
}) | ||
}) | ||
.then(response => { | ||
return response.json(); | ||
}) | ||
.then(data => { | ||
if (data.errors) | ||
add_notification_to_page('danger' , 'Something wrong Happened') | ||
else | ||
add_notification_to_page('success' , | ||
`<p> ${ data.message}</p> | ||
<p>You can check it from the following link </p> | ||
<p> | ||
<a href='${data.link} '> ${data.link} </a> | ||
</p>` | ||
) | ||
|
||
}) | ||
.catch(error => { | ||
add_notification_to_page('danger' , 'Something wrong Happened here') | ||
}); | ||
} | ||
|
||
get_dom_product_details(){} | ||
|
||
populate_dom_with_charts(){} | ||
|
||
|
||
refresh_dom_all(){ | ||
product.get_dom_product_details() | ||
product.update_server_product().then(response => { | ||
console.log("updated server") | ||
}) | ||
document | ||
.querySelectorAll("#gray_layout , #discount_bandit_show, #chart , #all_stores_cards") | ||
?.forEach((elem)=>{ | ||
elem.remove() | ||
}) | ||
|
||
product.populate_dom_with_charts() | ||
|
||
setTimeout(() => { | ||
document.getElementById("submit_discount_form") | ||
.addEventListener("click" , function (){ | ||
product.submit_form() | ||
}) | ||
}, 2000); | ||
|
||
product.get_product_data().then(response => { | ||
|
||
}) | ||
} | ||
|
||
} | ||
|
||
|
||
|
||
|
||
let previousUrl = null; | ||
const observer = new MutationObserver(function(mutations) { | ||
|
||
current_url=new URL(location.href) | ||
|
||
if (current_url.pathname !== previousUrl?.pathname) { | ||
previousUrl = new URL(location.href); | ||
product.refresh_dom_all() | ||
} | ||
}); | ||
|
||
const config = {subtree: true, childList: true}; | ||
observer.observe(document, config); | ||
|
||
|
||
|
||
|
||
//share the url across all classes | ||
var current_url = new URL(window.location.href); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
class Amazon extends Product { | ||
constructor() { | ||
|
||
|
||
super(); | ||
} | ||
|
||
get_dom_product_details(){ | ||
this.name= document.getElementById("productTitle").textContent.trim() | ||
this.price= document.getElementById("twister-plus-price-data-price")?.value ?? 0 | ||
this.image= document.querySelector(".imgTagWrapper img").src | ||
this.number_of_rates=document.getElementById("acrCustomerReviewText") | ||
?.textContent.split(" ")[0] | ||
.replaceAll(",","") | ||
.replaceAll("." , "") | ||
.replaceAll("(" , "") | ||
.replaceAll(")" , "") | ||
|
||
|
||
} | ||
|
||
populate_dom_with_charts() { | ||
|
||
document.body.insertAdjacentHTML("afterbegin" , `<div id='gray_layout' | ||
onclick="if (event.target === event.currentTarget) this.classList.remove('show_flex')">${get_global_form()}</div>`) | ||
|
||
document.body.querySelector("#title_feature_div") | ||
.insertAdjacentHTML('afterend', `<img id="discount_bandit_show" | ||
src="${browser.runtime.getURL(`resources/images/bandit.png`)}" | ||
onclick='document.body.querySelector("#gray_layout").classList.add("show_flex")'>`) | ||
|
||
//add the chart and stores | ||
var main_body=document.body.querySelector("#ppd") | ||
main_body.insertAdjacentHTML("afterend" , "<div id='chart'></div>") | ||
main_body.insertAdjacentHTML("afterend" , "<div id='all_stores_cards'></div>") | ||
} | ||
|
||
async get_product_data() { | ||
|
||
super.get_product_data().then(data => { | ||
if (!data) | ||
return; | ||
|
||
insert_chart_into_dom(data.series) | ||
|
||
//add highest and lowest prices | ||
document.getElementById("buybox") | ||
.insertAdjacentHTML("afterbegin" , | ||
`<div class="lowest_price" > Lowest Price ${data.prices[data.current_store_id].lowest_price.toLocaleString()}</div> | ||
<div class="highest_price" "> Highest Price ${data.prices[data.current_store_id].highest_price.toLocaleString()}</div>` | ||
) | ||
|
||
//add open in Discount Bandit | ||
document.getElementById("submit.buy-now").insertAdjacentHTML("afterend" , | ||
`<a class="discount_bandit_button" | ||
target="_blank" | ||
href="${this.url}/products/${data.product_id}"> | ||
<img src="${browser.runtime.getURL(`resources/images/bandit.png`)}" | ||
style="max-width: 20px" > | ||
Discount Bandit | ||
</a>`) | ||
|
||
//add other stores available. | ||
var stores_elements=document.getElementById("all_stores_cards"); | ||
|
||
for (const [store, value] of Object.entries(data.prices)) | ||
if (store != data.current_store_id) | ||
stores_elements.insertAdjacentHTML("afterbegin", product_per_store_price_template(store,value)) | ||
}) | ||
} | ||
|
||
} | ||
|
||
//todo make product call class name dynamically | ||
if ( current_url.host.includes('amazon.') && (current_url.pathname.includes("/dp/") || current_url.pathname.includes("/gp/product") ) ){ | ||
var product= new Amazon() | ||
product.get_storage_data().then(r => {}) | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
if (window.location.href.includes('argos.co.uk') ){ | ||
|
||
class Argos extends Product { | ||
constructor() { | ||
super(); | ||
} | ||
|
||
get_dom_product_details(){ | ||
this.name= document.querySelectorAll('[data-test="product-title"]')[0].textContent.trim() | ||
this.price= document.querySelectorAll('[data-test="product-price-primary"]')[0].getAttribute('content') | ||
this.image= document.querySelectorAll('[data-test="component-media-gallery-thumbnails_thumbnail-0"] img')[0].src | ||
this.number_of_rates= document.querySelectorAll('[itemProp="ratingCount"]')[0].textContent | ||
} | ||
|
||
populate_dom_with_charts() { | ||
|
||
document.body.insertAdjacentHTML("afterbegin" , `<div id='gray_layout' | ||
onclick="if (event.target === event.currentTarget) this.classList.remove('show_flex')">${get_global_form()}</div>`) | ||
|
||
|
||
|
||
//add the chart and stores | ||
setTimeout(() => { | ||
document.querySelectorAll('[data-test="product-name"]')[0] | ||
.insertAdjacentHTML('afterend', `<img id="discount_bandit_show" | ||
src="${browser.runtime.getURL(`resources/images/bandit.png`)}" | ||
onclick='document.body.querySelector("#gray_layout").classList.add("show_flex")'>`) | ||
|
||
|
||
var main_body=document.getElementById("pdp-description") | ||
main_body.insertAdjacentHTML("beforebegin" , "<div id='all_stores_cards'></div>") | ||
main_body.insertAdjacentHTML("beforebegin" , "<div id='chart'></div>") | ||
}, 2000); | ||
|
||
|
||
} | ||
|
||
async get_product_data() { | ||
|
||
super.get_product_data().then(data => { | ||
|
||
if (data){ | ||
//add highest and lowest prices | ||
document.querySelectorAll("[data-test='product-price-primary']")[0] | ||
.insertAdjacentHTML("afterbegin" , | ||
`<div class="lowest_price" > Lowest Price ${data.prices[data.current_store_id].lowest_price.toLocaleString()}</div> | ||
<div class="highest_price" "> Highest Price ${data.prices[data.current_store_id].highest_price.toLocaleString()}</div>` | ||
) | ||
|
||
|
||
//add open in Discount Bandit | ||
document.querySelectorAll("[data-test='add-trolley-button-wrapper']")[0] | ||
.insertAdjacentHTML("afterend" , | ||
`<a class="discount_bandit_button" | ||
target="_blank" | ||
href="${this.url}/products/${data.product_id}"> | ||
<img src="${browser.runtime.getURL(`resources/images/bandit.png`)}" | ||
style="max-width: 20px" | ||
> | ||
Discount Bandit</a>` | ||
) | ||
setTimeout(() => { | ||
|
||
if (!data) | ||
return; | ||
insert_chart_into_dom(data.series) | ||
|
||
var stores_elements=document.getElementById("all_stores_cards"); | ||
for (const [store, value] of Object.entries(data.prices)) | ||
if (store != data.current_store_id) | ||
stores_elements.insertAdjacentHTML("afterbegin", product_per_store_price_template(store,value)) | ||
|
||
}, 3000); | ||
|
||
} | ||
|
||
|
||
|
||
|
||
//add other stores available. | ||
}) | ||
} | ||
|
||
} | ||
|
||
var product= new Argos() | ||
|
||
product.get_storage_data().then(r => {}) | ||
} |
Oops, something went wrong.