mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-24 06:32:12 -03:00
Add update check and change log
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { debounce } from './utils/debounce.js';
|
||||
import { LoadingManager } from './managers/LoadingManager.js';
|
||||
import { modalManager } from './managers/ModalManager.js';
|
||||
import { updateService } from './managers/UpdateService.js';
|
||||
import { state } from './state/index.js';
|
||||
import { showLoraModal, toggleShowcase, scrollToTop } from './components/LoraCard.js';
|
||||
import { loadMoreLoras, fetchCivitai, deleteModel, replacePreview, resetAndReload, refreshLoras } from './api/loraApi.js';
|
||||
@@ -50,9 +51,10 @@ window.toggleShowcase = toggleShowcase;
|
||||
window.scrollToTop = scrollToTop;
|
||||
|
||||
// Initialize everything when DOM is ready
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
state.loadingManager = new LoadingManager();
|
||||
modalManager.initialize(); // Initialize modalManager after DOM is loaded
|
||||
updateService.initialize(); // Initialize updateService after modalManager
|
||||
window.downloadManager = new DownloadManager(); // Move this after modalManager initialization
|
||||
window.filterManager = new FilterManager(); // Initialize filter manager
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ export class ModalManager {
|
||||
constructor() {
|
||||
this.modals = new Map();
|
||||
this.scrollPosition = 0;
|
||||
this.updateAvailable = false;
|
||||
}
|
||||
|
||||
initialize() {
|
||||
@@ -75,9 +74,8 @@ export class ModalManager {
|
||||
document.addEventListener('keydown', this.boundHandleEscape);
|
||||
this.initialized = true;
|
||||
|
||||
// Initialize corner controls and update modal
|
||||
// Initialize corner controls
|
||||
this.initCornerControls();
|
||||
this.initUpdateModal();
|
||||
}
|
||||
|
||||
registerModal(id, config) {
|
||||
@@ -159,79 +157,16 @@ export class ModalManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Add method to initialize corner controls behavior
|
||||
// Keep only the corner controls initialization
|
||||
initCornerControls() {
|
||||
const cornerControls = document.querySelector('.corner-controls');
|
||||
const cornerControlsToggle = document.querySelector('.corner-controls-toggle');
|
||||
|
||||
if(cornerControls && cornerControlsToggle) {
|
||||
// Check for updates (mock implementation)
|
||||
this.checkForUpdates();
|
||||
|
||||
// Apply the initial badge state based on localStorage
|
||||
const showUpdates = localStorage.getItem('show_update_notifications');
|
||||
if (showUpdates === 'false') {
|
||||
this.updateBadgeVisibility(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modified update checker
|
||||
checkForUpdates() {
|
||||
// First check if user has disabled update notifications
|
||||
const showUpdates = localStorage.getItem('show_update_notifications');
|
||||
|
||||
// For demo purposes, we'll simulate an update being available
|
||||
setTimeout(() => {
|
||||
// We have an update available (mock)
|
||||
this.updateAvailable = true;
|
||||
|
||||
// Only show badges if notifications are enabled
|
||||
const shouldShow = showUpdates !== 'false';
|
||||
this.updateBadgeVisibility(shouldShow);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Add method to initialize update modal
|
||||
initUpdateModal() {
|
||||
const updateModal = document.getElementById('updateModal');
|
||||
if (!updateModal) return;
|
||||
|
||||
const checkbox = updateModal.querySelector('#updateNotifications');
|
||||
if (!checkbox) return;
|
||||
|
||||
// Set initial state from localStorage or default to true
|
||||
const showUpdates = localStorage.getItem('show_update_notifications');
|
||||
checkbox.checked = showUpdates === null || showUpdates === 'true';
|
||||
|
||||
// Apply the initial badge visibility based on checkbox state
|
||||
this.updateBadgeVisibility(checkbox.checked);
|
||||
|
||||
// Add event listener for changes
|
||||
checkbox.addEventListener('change', (e) => {
|
||||
localStorage.setItem('show_update_notifications', e.target.checked);
|
||||
|
||||
// Immediately update badge visibility based on the new setting
|
||||
this.updateBadgeVisibility(e.target.checked);
|
||||
});
|
||||
}
|
||||
|
||||
// Enhanced helper method to update badge visibility
|
||||
updateBadgeVisibility(show) {
|
||||
const updateToggle = document.querySelector('.update-toggle');
|
||||
const updateBadge = document.querySelector('.update-toggle .update-badge');
|
||||
const cornerBadge = document.querySelector('.corner-badge');
|
||||
|
||||
if (updateToggle) {
|
||||
updateToggle.title = show && this.updateAvailable ? "Update Available" : "Check Updates";
|
||||
}
|
||||
|
||||
if (updateBadge) {
|
||||
updateBadge.classList.toggle('hidden', !(show && this.updateAvailable));
|
||||
}
|
||||
|
||||
if (cornerBadge) {
|
||||
cornerBadge.classList.toggle('hidden', !(show && this.updateAvailable));
|
||||
// Toggle corner controls visibility
|
||||
cornerControlsToggle.addEventListener('click', () => {
|
||||
cornerControls.classList.toggle('expanded');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
183
static/js/managers/UpdateService.js
Normal file
183
static/js/managers/UpdateService.js
Normal file
@@ -0,0 +1,183 @@
|
||||
import { modalManager } from './ModalManager.js';
|
||||
|
||||
export class UpdateService {
|
||||
constructor() {
|
||||
this.updateCheckInterval = 24 * 60 * 60 * 1000; // 24 hours
|
||||
this.currentVersion = "v0.0.0"; // Initialize with default values
|
||||
this.latestVersion = "v0.0.0"; // Initialize with default values
|
||||
this.updateInfo = null;
|
||||
this.updateAvailable = false;
|
||||
this.updateNotificationsEnabled = localStorage.getItem('show_update_notifications') !== 'false';
|
||||
this.lastCheckTime = parseInt(localStorage.getItem('last_update_check') || '0');
|
||||
}
|
||||
|
||||
initialize() {
|
||||
// Initialize update preferences from localStorage
|
||||
const showUpdates = localStorage.getItem('show_update_notifications');
|
||||
this.updateNotificationsEnabled = showUpdates === null || showUpdates === 'true';
|
||||
|
||||
// Register event listener for update notification toggle
|
||||
const updateCheckbox = document.getElementById('updateNotifications');
|
||||
if (updateCheckbox) {
|
||||
updateCheckbox.checked = this.updateNotificationsEnabled;
|
||||
updateCheckbox.addEventListener('change', (e) => {
|
||||
this.updateNotificationsEnabled = e.target.checked;
|
||||
localStorage.setItem('show_update_notifications', e.target.checked);
|
||||
this.updateBadgeVisibility();
|
||||
});
|
||||
}
|
||||
|
||||
// Perform update check if needed
|
||||
this.checkForUpdates();
|
||||
|
||||
// Set up event listener for update button
|
||||
const updateToggle = document.querySelector('.update-toggle');
|
||||
if (updateToggle) {
|
||||
updateToggle.addEventListener('click', () => this.showUpdateModal());
|
||||
}
|
||||
|
||||
// Immediately update modal content with current values (even if from default)
|
||||
this.updateModalContent();
|
||||
}
|
||||
|
||||
async checkForUpdates() {
|
||||
// Check if we should perform an update check
|
||||
const now = Date.now();
|
||||
if (now - this.lastCheckTime < this.updateCheckInterval) {
|
||||
// If we already have update info, just update the UI
|
||||
if (this.updateAvailable) {
|
||||
this.updateBadgeVisibility();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Call backend API to check for updates
|
||||
const response = await fetch('/loras/api/check-updates');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
this.currentVersion = data.current_version || "v0.0.0";
|
||||
this.latestVersion = data.latest_version || "v0.0.0";
|
||||
this.updateInfo = data;
|
||||
|
||||
// Determine if update is available
|
||||
this.updateAvailable = data.update_available;
|
||||
|
||||
// Update last check time
|
||||
this.lastCheckTime = now;
|
||||
localStorage.setItem('last_update_check', now.toString());
|
||||
|
||||
// Update UI
|
||||
this.updateBadgeVisibility();
|
||||
this.updateModalContent();
|
||||
|
||||
console.log("Update check complete:", {
|
||||
currentVersion: this.currentVersion,
|
||||
latestVersion: this.latestVersion,
|
||||
updateAvailable: this.updateAvailable
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to check for updates:', error);
|
||||
}
|
||||
}
|
||||
|
||||
updateBadgeVisibility() {
|
||||
const updateToggle = document.querySelector('.update-toggle');
|
||||
const updateBadge = document.querySelector('.update-toggle .update-badge');
|
||||
const cornerBadge = document.querySelector('.corner-badge');
|
||||
|
||||
if (updateToggle) {
|
||||
updateToggle.title = this.updateNotificationsEnabled && this.updateAvailable
|
||||
? "Update Available"
|
||||
: "Check Updates";
|
||||
}
|
||||
|
||||
if (updateBadge) {
|
||||
const shouldShow = this.updateNotificationsEnabled && this.updateAvailable;
|
||||
updateBadge.classList.toggle('hidden', !shouldShow);
|
||||
}
|
||||
|
||||
if (cornerBadge) {
|
||||
const shouldShow = this.updateNotificationsEnabled && this.updateAvailable;
|
||||
cornerBadge.classList.toggle('hidden', !shouldShow);
|
||||
}
|
||||
}
|
||||
|
||||
updateModalContent() {
|
||||
const modal = document.getElementById('updateModal');
|
||||
if (!modal) return;
|
||||
|
||||
// Update title based on update availability
|
||||
const headerTitle = modal.querySelector('.update-header h2');
|
||||
if (headerTitle) {
|
||||
headerTitle.textContent = this.updateAvailable ? "Update Available" : "Check for Updates";
|
||||
}
|
||||
|
||||
// Always update version information, even if updateInfo is null
|
||||
const currentVersionEl = modal.querySelector('.current-version .version-number');
|
||||
const newVersionEl = modal.querySelector('.new-version .version-number');
|
||||
|
||||
if (currentVersionEl) currentVersionEl.textContent = this.currentVersion;
|
||||
if (newVersionEl) newVersionEl.textContent = this.latestVersion;
|
||||
|
||||
// Update changelog content if available
|
||||
if (this.updateInfo && this.updateInfo.changelog) {
|
||||
const changelogContent = modal.querySelector('.changelog-content');
|
||||
if (changelogContent) {
|
||||
changelogContent.innerHTML = ''; // Clear existing content
|
||||
|
||||
// Create changelog item
|
||||
const changelogItem = document.createElement('div');
|
||||
changelogItem.className = 'changelog-item';
|
||||
|
||||
const versionHeader = document.createElement('h4');
|
||||
versionHeader.textContent = `Version ${this.latestVersion}`;
|
||||
changelogItem.appendChild(versionHeader);
|
||||
|
||||
// Create changelog list
|
||||
const changelogList = document.createElement('ul');
|
||||
|
||||
if (this.updateInfo.changelog && this.updateInfo.changelog.length > 0) {
|
||||
this.updateInfo.changelog.forEach(item => {
|
||||
const listItem = document.createElement('li');
|
||||
listItem.textContent = item;
|
||||
changelogList.appendChild(listItem);
|
||||
});
|
||||
} else {
|
||||
// If no changelog items available
|
||||
const listItem = document.createElement('li');
|
||||
listItem.textContent = "No detailed changelog available. Check GitHub for more information.";
|
||||
changelogList.appendChild(listItem);
|
||||
}
|
||||
|
||||
changelogItem.appendChild(changelogList);
|
||||
changelogContent.appendChild(changelogItem);
|
||||
}
|
||||
}
|
||||
|
||||
// Update GitHub link to point to the specific release if available
|
||||
const githubLink = modal.querySelector('.update-link');
|
||||
if (githubLink && this.latestVersion) {
|
||||
const versionTag = this.latestVersion.replace(/^v/, '');
|
||||
githubLink.href = `https://github.com/willmiao/ComfyUI-Lora-Manager/releases/tag/v${versionTag}`;
|
||||
}
|
||||
}
|
||||
|
||||
showUpdateModal() {
|
||||
// Force a check for updates when showing the modal
|
||||
this.manualCheckForUpdates().then(() => {
|
||||
// Show the modal after update check completes
|
||||
modalManager.showModal('updateModal');
|
||||
});
|
||||
}
|
||||
|
||||
async manualCheckForUpdates() {
|
||||
this.lastCheckTime = 0; // Reset last check time to force check
|
||||
await this.checkForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
// Create and export singleton instance
|
||||
export const updateService = new UpdateService();
|
||||
Reference in New Issue
Block a user