Skip to content

Commit 51d59c6

Browse files
committed
reverting
1 parent 057e91a commit 51d59c6

3 files changed

Lines changed: 179 additions & 4 deletions

File tree

FO2/MarketTracker/FO2MarketTrack.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ <h1>Fantasy Online 2 Market Tracker</h1>
5151
</button>
5252
</div>
5353
<div class="update-info">
54-
<!-- <span id="last-updated-timestamp">Last Updated: Never</span> -->
54+
<span id="last-updated-timestamp">Last Updated: Never</span>
5555
<button id="refresh-button" title="Fetch latest data from API">Refresh</button>
5656
</div>
5757
</div>

FO2/MarketTracker/market-track-style.css

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ h1 { margin: 0; font-size: 2rem; }
3939
select { padding: 8px; border-radius: 4px; border: 1px solid #ddd; }
4040

4141
/* Last Updated and Refresh Button Styles */
42-
.update-info { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; justify-content: flex-start; overflow: hidden; margin-left: auto; font-size: 0.9rem; color: #555; }
43-
/* #last-updated-timestamp { white-space: nowrap; } */
42+
.update-info { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; justify-content: flex-start; margin-left: auto; font-size: 0.9rem; color: #555; }
43+
#last-updated-timestamp { white-space: nowrap; }
4444
#refresh-button { padding: 6px 12px; flex-shrink: 0; white-space: nowrap; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; transition: background-color 0.3s; }
4545
#refresh-button:hover { background-color: #45a049; }
4646
#refresh-button:disabled { background-color: #cccccc; color: #666666; cursor: not-allowed; }
@@ -117,7 +117,6 @@ footer { margin-top: 40px; text-align: center; color: #757575; font-size: 0.9rem
117117
.update-info { margin-left: 0; margin-top: 10px; justify-content: space-between; }
118118
}
119119
@media (max-width: 768px) {
120-
.update-info { justify-content: space-between; }
121120
.search-container, #search-form { flex-direction: column; }
122121
#search-input { border-radius: 4px; margin-bottom: 10px; }
123122
#search-button { border-radius: 4px; }

FO2/MarketTracker/market-track.js

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,114 @@ const API_BASE_URL = 'https://fantasyonline2.com/api/public';
22
const API_KEY = process.env.API_KEY; // Replace with your actual key if needed
33
let embeddedItemData = null; // Initialize as null
44

5+
<<<<<<< HEAD
56
// Mock data for demonstration (replace with your actual data loading)
67
async function loadEmbeddedItemData() {
8+
=======
9+
// Load the JSON file and assign its contents to embeddedItemData
10+
async function loadEmbeddedItemData() {
11+
try {
12+
console.log('Attempting to load item-data.json...');
13+
const response = await fetch('item-data.json'); // Ensure the path is correct
14+
console.log('Fetch response status:', response.status);
15+
16+
if (!response.ok) {
17+
throw new Error(`Failed to load JSON file: ${response.statusText}`);
18+
}
19+
const jsonData = await response.json();
20+
console.log('Raw JSON data:', jsonData);
21+
22+
embeddedItemData = jsonData;
23+
console.log('Embedded item data loaded:', embeddedItemData);
24+
} catch (error) {
25+
console.error('Error loading embedded item data:', error);
26+
}
27+
}
28+
29+
// Call the function to load the JSON file
30+
loadEmbeddedItemData();
31+
32+
let currentPage = 1;
33+
let totalPages = 1;
34+
let currentSort = 'TimeLeft';
35+
let currentDirection = 'DESC';
36+
let lastApiSearchTerm = ''; // Store term used for last API call
37+
let isLoading = false;
38+
let itemDatabase = null;
39+
let currentMarketListings = []; // Stores full data for the current page from API
40+
let currentlyDisplayedListings = []; // Stores the listings currently shown (after filtering)
41+
let abortController = null;
42+
let lastUpdateTime = null;
43+
let showProfitableOnlyState = false; // Tracks if the profitable filter *should* be active
44+
let isComprehensiveSearchActive = false; // Tracks if we are *currently showing* comprehensive results
45+
let comprehensiveSearchResults = [];
46+
let searchedPages = 0;
47+
let totalSearchPages = 0;
48+
let comprehensiveSearchAborted = false;
49+
let personalPrices = {}; // Holds user-defined prices {itemId: price}
50+
let selectedItemId = null; // Track the currently selected item ID for the details panel
51+
52+
// DOM Elements
53+
const searchForm = document.getElementById('search-form');
54+
const searchInput = document.getElementById('search-input');
55+
const searchButton = document.getElementById('search-button');
56+
const sortBySelect = document.getElementById('sort-by');
57+
const sortDirectionSelect = document.getElementById('sort-direction');
58+
const messageContainer = document.getElementById('message-container');
59+
const databaseStatus = document.getElementById('database-status');
60+
const resultsContainer = document.getElementById('results-container');
61+
const resultsTable = document.getElementById('results-table');
62+
const resultsBody = document.getElementById('results-body');
63+
const prevPageButton = document.getElementById('prev-page');
64+
const nextPageButton = document.getElementById('next-page');
65+
const currentPageSpan = document.getElementById('current-page');
66+
const totalPagesSpan = document.getElementById('total-pages');
67+
const itemDetailsColumn = document.getElementById('item-details-column');
68+
const detailsIcon = document.getElementById('details-icon');
69+
const detailsName = document.getElementById('details-name');
70+
const detailsRecentlyListedPrice = document.getElementById('details-recently-listed-price');
71+
const detailsBuyPrice = document.getElementById('details-buy-price');
72+
const detailsSellPrice = document.getElementById('details-sell-price');
73+
const detailsError = document.getElementById('details-error');
74+
const lastUpdatedTimestampSpan = document.getElementById('last-updated-timestamp');
75+
const refreshButton = document.getElementById('refresh-button');
76+
const detailsPotentialProfit = document.getElementById('details-potential-profit');
77+
const detailsPersonalProfit = document.getElementById('details-personal-profit');
78+
const showProfitableButton = document.getElementById('show-profitable-only');
79+
const personalPriceInput = document.getElementById('details-personal-price');
80+
const searchProgressModal = document.getElementById('search-progress-modal');
81+
const searchProgressContent = document.getElementById('search-progress-content');
82+
const searchProgressMessage = document.getElementById('search-progress-message');
83+
const searchProgressBarContainer = document.getElementById('search-progress-bar-container');
84+
const searchProgressBar = document.getElementById('search-progress-bar');
85+
const cancelSearchButton = document.getElementById('cancel-search-button');
86+
87+
88+
// --- Local Storage Functions ---
89+
function loadPersonalPrices() {
90+
try {
91+
const storedPrices = localStorage.getItem('fo2PersonalPrices');
92+
personalPrices = storedPrices ? JSON.parse(storedPrices) : {};
93+
console.log("Loaded personal prices:", Object.keys(personalPrices).length);
94+
} catch (error) {
95+
console.error("Failed to load personal prices:", error);
96+
personalPrices = {}; // Reset on error
97+
}
98+
}
99+
100+
function savePersonalPrice(itemId, price) {
101+
if (itemId == null) return;
102+
const stringItemId = String(itemId);
103+
104+
const priceValue = price === '' ? null : parseFloat(price);
105+
106+
if (priceValue === null || (!isNaN(priceValue) && priceValue >= 0)) {
107+
if (priceValue === null || price === '') {
108+
delete personalPrices[stringItemId];
109+
} else {
110+
personalPrices[stringItemId] = priceValue;
111+
}
112+
>>>>>>> parent of 4d7103b (removing last update timestamp)
7113
try {
8114
console.log('Loading mock item data...');
9115
// Mock data structure - replace with your actual JSON loading
@@ -109,6 +215,57 @@ const API_BASE_URL = 'https://fantasyonline2.com/api/public';
109215
displayItemDetails(itemId);
110216
}
111217
}
218+
<<<<<<< HEAD
219+
=======
220+
});
221+
console.log('Database load successfully:', (validItems));
222+
// databaseStatus.innerHTML = `<div class="database-status"><span>Item database loaded successfully (${validItems} items)</span></div>`;
223+
return true;
224+
} catch (error) {
225+
console.error('Database load error:', error);
226+
// databaseStatus.innerHTML = `<div class="database-status error"><span>Failed to load item database: ${error.message}</span><button onclick="location.reload()">Retry</button></div>`;
227+
return false;
228+
}
229+
}
230+
231+
function findItemById(itemId) { return itemDatabase?.[String(itemId)] || null; }
232+
function formatNumber(num) { return (num == null || isNaN(num)) ? 'N/A' : num.toLocaleString(); }
233+
function formatPrice(price) { return (price == null || price === "" || isNaN(price)) ? 'N/A' : `${formatNumber(price)} Coins`; }
234+
function setTableLoading(loading) { if (loading) { resultsBody.innerHTML = `<tr><td colspan="3" style="text-align:center; padding: 30px;"><div class="loading-spinner"></div></td></tr>`; } }
235+
function updateTimestampDisplay() { lastUpdatedTimestampSpan.textContent = lastUpdateTime ? `Last Updated: ${lastUpdateTime.toLocaleTimeString()}` : 'Last Updated: Never'; }
236+
237+
async function searchMarket(page = currentPage, term = searchInput.value.trim(), sort = currentSort, direction = currentDirection) {
238+
const isForComprehensive = isComprehensiveSearchActive; // Snapshot state
239+
if (isLoading && !isForComprehensive) return { error: "Already loading" };
240+
241+
isLoading = true;
242+
disableControls(true, isForComprehensive); // Disable controls
243+
if (!isForComprehensive) {
244+
setTableLoading(true);
245+
messageContainer.innerHTML = '';
246+
}
247+
lastApiSearchTerm = term;
248+
249+
if (abortController) { abortController.abort("New search started"); }
250+
abortController = new AbortController();
251+
const signal = abortController.signal;
252+
253+
try {
254+
const response = await fetch(`${API_BASE_URL}/market/search`, {
255+
method: 'POST',
256+
headers: { 'Content-Type': 'application/json', 'x-api-key': API_KEY },
257+
body: JSON.stringify({ search_term: term, sort_by: sort, sort_direction: direction, page: page }),
258+
signal: signal
259+
});
260+
261+
if (!response.ok) {
262+
let errorData;
263+
try { errorData = await response.json(); } catch { errorData = null; }
264+
let errorMsg = `API Error: ${response.status} ${response.statusText}. ${errorData?.message || ''}`;
265+
if (response.status === 429) errorMsg = `API Rate Limit Hit. Please wait. ${errorData?.message || ''}`;
266+
else if (response.status === 401) errorMsg = `API Authentication Error (Invalid Key?). ${errorData?.message || ''}`;
267+
throw new Error(errorMsg);
268+
>>>>>>> parent of 4d7103b (removing last update timestamp)
112269
}
113270

114271
async function loadItemDatabase() {
@@ -132,6 +289,15 @@ const API_BASE_URL = 'https://fantasyonline2.com/api/public';
132289
return false;
133290
}
134291
}
292+
<<<<<<< HEAD
293+
=======
294+
updatePagination();
295+
applyClientSideFilter(); // Filter and display the new data
296+
resultsContainer.style.display = 'flex';
297+
lastUpdateTime = new Date();
298+
updateTimestampDisplay();
299+
return data; // Return data
300+
>>>>>>> parent of 4d7103b (removing last update timestamp)
135301

136302
function findItemById(itemId) {
137303
return itemDatabase?.[String(itemId)] || null;
@@ -600,11 +766,21 @@ const API_BASE_URL = 'https://fantasyonline2.com/api/public';
600766
}
601767
});
602768

769+
<<<<<<< HEAD
603770
personalPriceInput.addEventListener('change', () => {
604771
if (selectedItemId) {
605772
savePersonalPrice(selectedItemId, personalPriceInput.value);
606773
}
607774
});
775+
=======
776+
// --- Initial Load ---
777+
async function initializeApp() {
778+
try {
779+
loadPersonalPrices(); // Load personal prices (if applicable)
780+
await loadEmbeddedItemData(); // Ensure JSON data is loaded before proceeding
781+
const dbLoaded = await loadItemDatabase(); // Load the item database after JSON is loaded
782+
updateTimestampDisplay(); // Update timestamp display
783+
>>>>>>> parent of 4d7103b (removing last update timestamp)
608784

609785
showProfitableButton.addEventListener('click', function() {
610786
if (isLoading) return;

0 commit comments

Comments
 (0)